12cab237bSDimitry Andric //===- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA ---------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky 
106122f3e6SDimitry Andric #include "MCTargetDesc/ARMAddressingModes.h"
116122f3e6SDimitry Andric #include "MCTargetDesc/ARMBaseInfo.h"
127a7e6055SDimitry Andric #include "MCTargetDesc/ARMMCTargetDesc.h"
132cab237bSDimitry Andric #include "Utils/ARMBaseInfo.h"
14139f7f9bSDimitry Andric #include "llvm/MC/MCContext.h"
157a7e6055SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
16139f7f9bSDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
17f22ef01cSRoman Divacky #include "llvm/MC/MCInst.h"
18dff0c46cSDimitry Andric #include "llvm/MC/MCInstrDesc.h"
19dff0c46cSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
207a7e6055SDimitry Andric #include "llvm/MC/SubtargetFeature.h"
217a7e6055SDimitry Andric #include "llvm/Support/Compiler.h"
22f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
237a7e6055SDimitry Andric #include "llvm/Support/MathExtras.h"
247a7e6055SDimitry Andric #include "llvm/Support/TargetRegistry.h"
25db17bf38SDimitry Andric #include "llvm/Support/raw_ostream.h"
267a7e6055SDimitry Andric #include <algorithm>
277a7e6055SDimitry Andric #include <cassert>
287a7e6055SDimitry Andric #include <cstdint>
297ae0e2c9SDimitry Andric #include <vector>
30f22ef01cSRoman Divacky 
31f22ef01cSRoman Divacky using namespace llvm;
32f22ef01cSRoman Divacky 
3391bc56edSDimitry Andric #define DEBUG_TYPE "arm-disassembler"
3491bc56edSDimitry Andric 
352cab237bSDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
366122f3e6SDimitry Andric 
376122f3e6SDimitry Andric namespace {
387a7e6055SDimitry Andric 
397ae0e2c9SDimitry Andric   // Handles the condition code status of instructions in IT blocks
407ae0e2c9SDimitry Andric   class ITStatus
417ae0e2c9SDimitry Andric   {
427ae0e2c9SDimitry Andric     public:
437ae0e2c9SDimitry Andric       // Returns the condition code for instruction in IT block
getITCC()447ae0e2c9SDimitry Andric       unsigned getITCC() {
457ae0e2c9SDimitry Andric         unsigned CC = ARMCC::AL;
467ae0e2c9SDimitry Andric         if (instrInITBlock())
477ae0e2c9SDimitry Andric           CC = ITStates.back();
487ae0e2c9SDimitry Andric         return CC;
497ae0e2c9SDimitry Andric       }
507ae0e2c9SDimitry Andric 
517ae0e2c9SDimitry Andric       // Advances the IT block state to the next T or E
advanceITState()527ae0e2c9SDimitry Andric       void advanceITState() {
537ae0e2c9SDimitry Andric         ITStates.pop_back();
547ae0e2c9SDimitry Andric       }
557ae0e2c9SDimitry Andric 
567ae0e2c9SDimitry Andric       // Returns true if the current instruction is in an IT block
instrInITBlock()577ae0e2c9SDimitry Andric       bool instrInITBlock() {
587ae0e2c9SDimitry Andric         return !ITStates.empty();
597ae0e2c9SDimitry Andric       }
607ae0e2c9SDimitry Andric 
617ae0e2c9SDimitry Andric       // Returns true if current instruction is the last instruction in an IT block
instrLastInITBlock()627ae0e2c9SDimitry Andric       bool instrLastInITBlock() {
637ae0e2c9SDimitry Andric         return ITStates.size() == 1;
647ae0e2c9SDimitry Andric       }
657ae0e2c9SDimitry Andric 
667ae0e2c9SDimitry Andric       // Called when decoding an IT instruction. Sets the IT state for the following
677ae0e2c9SDimitry Andric       // instructions that for the IT block. Firstcond and Mask correspond to the
687ae0e2c9SDimitry Andric       // fields in the IT instruction encoding.
setITState(char Firstcond,char Mask)697ae0e2c9SDimitry Andric       void setITState(char Firstcond, char Mask) {
707ae0e2c9SDimitry Andric         // (3 - the number of trailing zeros) is the number of then / else.
717ae0e2c9SDimitry Andric         unsigned CondBit0 = Firstcond & 1;
72f785676fSDimitry Andric         unsigned NumTZ = countTrailingZeros<uint8_t>(Mask);
737ae0e2c9SDimitry Andric         unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
747ae0e2c9SDimitry Andric         assert(NumTZ <= 3 && "Invalid IT mask!");
757ae0e2c9SDimitry Andric         // push condition codes onto the stack the correct order for the pops
767ae0e2c9SDimitry Andric         for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
777ae0e2c9SDimitry Andric           bool T = ((Mask >> Pos) & 1) == CondBit0;
787ae0e2c9SDimitry Andric           if (T)
797ae0e2c9SDimitry Andric             ITStates.push_back(CCBits);
807ae0e2c9SDimitry Andric           else
817ae0e2c9SDimitry Andric             ITStates.push_back(CCBits ^ 1);
827ae0e2c9SDimitry Andric         }
837ae0e2c9SDimitry Andric         ITStates.push_back(CCBits);
847ae0e2c9SDimitry Andric       }
857ae0e2c9SDimitry Andric 
867ae0e2c9SDimitry Andric     private:
877ae0e2c9SDimitry Andric       std::vector<unsigned char> ITStates;
887ae0e2c9SDimitry Andric   };
897ae0e2c9SDimitry Andric 
9039d628a0SDimitry Andric /// ARM disassembler for all ARM platforms.
916122f3e6SDimitry Andric class ARMDisassembler : public MCDisassembler {
926122f3e6SDimitry Andric public:
ARMDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)9391bc56edSDimitry Andric   ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
9491bc56edSDimitry Andric     MCDisassembler(STI, Ctx) {
95f22ef01cSRoman Divacky   }
96f22ef01cSRoman Divacky 
977a7e6055SDimitry Andric   ~ARMDisassembler() override = default;
98f22ef01cSRoman Divacky 
9939d628a0SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
10039d628a0SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
10139d628a0SDimitry Andric                               raw_ostream &VStream,
10239d628a0SDimitry Andric                               raw_ostream &CStream) const override;
1036122f3e6SDimitry Andric };
104f22ef01cSRoman Divacky 
10539d628a0SDimitry Andric /// Thumb disassembler for all Thumb platforms.
1066122f3e6SDimitry Andric class ThumbDisassembler : public MCDisassembler {
1076122f3e6SDimitry Andric public:
ThumbDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)10891bc56edSDimitry Andric   ThumbDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
10991bc56edSDimitry Andric     MCDisassembler(STI, Ctx) {
110f22ef01cSRoman Divacky   }
111f22ef01cSRoman Divacky 
1127a7e6055SDimitry Andric   ~ThumbDisassembler() override = default;
1133b0f4066SDimitry Andric 
11439d628a0SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
11539d628a0SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
11639d628a0SDimitry Andric                               raw_ostream &VStream,
11739d628a0SDimitry Andric                               raw_ostream &CStream) const override;
1186122f3e6SDimitry Andric 
1196122f3e6SDimitry Andric private:
1207ae0e2c9SDimitry Andric   mutable ITStatus ITBlock;
1212cab237bSDimitry Andric 
1226122f3e6SDimitry Andric   DecodeStatus AddThumbPredicate(MCInst&) const;
1236122f3e6SDimitry Andric   void UpdateThumbVFPPredicate(MCInst&) const;
1246122f3e6SDimitry Andric };
1257a7e6055SDimitry Andric 
1267a7e6055SDimitry Andric } // end anonymous namespace
127f22ef01cSRoman Divacky 
Check(DecodeStatus & Out,DecodeStatus In)1286122f3e6SDimitry Andric static bool Check(DecodeStatus &Out, DecodeStatus In) {
1296122f3e6SDimitry Andric   switch (In) {
1306122f3e6SDimitry Andric     case MCDisassembler::Success:
1316122f3e6SDimitry Andric       // Out stays the same.
1326122f3e6SDimitry Andric       return true;
1336122f3e6SDimitry Andric     case MCDisassembler::SoftFail:
1346122f3e6SDimitry Andric       Out = In;
1356122f3e6SDimitry Andric       return true;
1366122f3e6SDimitry Andric     case MCDisassembler::Fail:
1376122f3e6SDimitry Andric       Out = In;
1386122f3e6SDimitry Andric       return false;
1396122f3e6SDimitry Andric   }
140dff0c46cSDimitry Andric   llvm_unreachable("Invalid DecodeStatus!");
141f22ef01cSRoman Divacky }
142f22ef01cSRoman Divacky 
1436122f3e6SDimitry Andric // Forward declare these because the autogenerated code will reference them.
1446122f3e6SDimitry Andric // Definitions are further down.
145dff0c46cSDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1466122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder);
147dff0c46cSDimitry Andric static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst,
1486122f3e6SDimitry Andric                                                unsigned RegNo, uint64_t Address,
1496122f3e6SDimitry Andric                                                const void *Decoder);
150f785676fSDimitry Andric static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst,
151f785676fSDimitry Andric                                                unsigned RegNo, uint64_t Address,
152f785676fSDimitry Andric                                                const void *Decoder);
153dff0c46cSDimitry Andric static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1546122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder);
155dff0c46cSDimitry Andric static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1566122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder);
157dff0c46cSDimitry Andric static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1586122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder);
159f785676fSDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
160f785676fSDimitry Andric                                    uint64_t Address, const void *Decoder);
161*4ba319b5SDimitry Andric static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
162*4ba319b5SDimitry Andric                                    uint64_t Address, const void *Decoder);
163dff0c46cSDimitry Andric static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
1646122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder);
165dff0c46cSDimitry Andric static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
1666122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder);
167dff0c46cSDimitry Andric static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1686122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder);
169dff0c46cSDimitry Andric static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
1706122f3e6SDimitry Andric                                                 unsigned RegNo,
171f22ef01cSRoman Divacky                                                 uint64_t Address,
1726122f3e6SDimitry Andric                                                 const void *Decoder);
173dff0c46cSDimitry Andric static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
174dff0c46cSDimitry Andric                                    uint64_t Address, const void *Decoder);
175dff0c46cSDimitry Andric static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
176dff0c46cSDimitry Andric                                    uint64_t Address, const void *Decoder);
177dff0c46cSDimitry Andric static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
178dff0c46cSDimitry Andric                                unsigned RegNo, uint64_t Address,
179dff0c46cSDimitry Andric                                const void *Decoder);
180dff0c46cSDimitry Andric 
181dff0c46cSDimitry Andric static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
182dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
183dff0c46cSDimitry Andric static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
184dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
185dff0c46cSDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
186dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
187dff0c46cSDimitry Andric static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
188dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
189dff0c46cSDimitry Andric static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
1906122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
191f22ef01cSRoman Divacky 
192dff0c46cSDimitry Andric static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
1936122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
194dff0c46cSDimitry Andric static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
1956122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
196dff0c46cSDimitry Andric static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst,
1976122f3e6SDimitry Andric                                                   unsigned Insn,
198f22ef01cSRoman Divacky                                                   uint64_t Address,
1996122f3e6SDimitry Andric                                                   const void *Decoder);
200dff0c46cSDimitry Andric static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
2016122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
202dff0c46cSDimitry Andric static DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn,
2036122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
204dff0c46cSDimitry Andric static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
2056122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
206dff0c46cSDimitry Andric static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
2076122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
208f22ef01cSRoman Divacky 
209dff0c46cSDimitry Andric static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst,
2106122f3e6SDimitry Andric                                                   unsigned Insn,
2116122f3e6SDimitry Andric                                                   uint64_t Adddress,
2126122f3e6SDimitry Andric                                                   const void *Decoder);
213dff0c46cSDimitry Andric static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
2146122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
215dff0c46cSDimitry Andric static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
2166122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
217dff0c46cSDimitry Andric static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
2186122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
2193ca95b02SDimitry Andric static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
2203ca95b02SDimitry Andric                                uint64_t Address, const void *Decoder);
221dff0c46cSDimitry Andric static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
2226122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
223ff0cc061SDimitry Andric static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
224ff0cc061SDimitry Andric                                uint64_t Address, const void *Decoder);
225ff0cc061SDimitry Andric static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
226ff0cc061SDimitry Andric                                uint64_t Address, const void *Decoder);
227dff0c46cSDimitry Andric static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
2286122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
229dff0c46cSDimitry Andric static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
2306122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
231dff0c46cSDimitry Andric static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
2326122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
2333ca95b02SDimitry Andric static DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
2343ca95b02SDimitry Andric                                uint64_t Address, const void *Decoder);
235dff0c46cSDimitry Andric static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
2366122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
237dff0c46cSDimitry Andric static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2386122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
239dff0c46cSDimitry Andric static DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn,
2406122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
241dff0c46cSDimitry Andric static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
2426122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
243f785676fSDimitry Andric static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val,
244f785676fSDimitry Andric                                uint64_t Address, const void *Decoder);
245f785676fSDimitry Andric static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val,
246f785676fSDimitry Andric                                uint64_t Address, const void *Decoder);
247f785676fSDimitry Andric static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val,
248f785676fSDimitry Andric                                uint64_t Address, const void *Decoder);
249f785676fSDimitry Andric static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val,
250f785676fSDimitry Andric                                uint64_t Address, const void *Decoder);
251dff0c46cSDimitry Andric static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
2526122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
253dff0c46cSDimitry Andric static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
2546122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
255dff0c46cSDimitry Andric static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
2566122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
257dff0c46cSDimitry Andric static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
2586122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
259dff0c46cSDimitry Andric static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
2606122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
261dff0c46cSDimitry Andric static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
2626122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
263dff0c46cSDimitry Andric static DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val,
2646122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
265dff0c46cSDimitry Andric static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
2666122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
267dff0c46cSDimitry Andric static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
2686122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
269dff0c46cSDimitry Andric static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
2706122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
271dff0c46cSDimitry Andric static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
2726122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
273dff0c46cSDimitry Andric static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
2746122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
275dff0c46cSDimitry Andric static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
2766122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
277dff0c46cSDimitry Andric static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
2786122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
279dff0c46cSDimitry Andric static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
2806122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
281dff0c46cSDimitry Andric static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
2826122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
283f785676fSDimitry Andric static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
284f785676fSDimitry Andric                                uint64_t Address, const void *Decoder);
285dff0c46cSDimitry Andric static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
2866122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
28739d628a0SDimitry Andric static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Insn,
28839d628a0SDimitry Andric                                uint64_t Address, const void *Decoder);
289dff0c46cSDimitry Andric static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
2906122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
291dff0c46cSDimitry Andric static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
2926122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
293dff0c46cSDimitry Andric static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
2946122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
295dff0c46cSDimitry Andric static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
2966122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
297dff0c46cSDimitry Andric static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
2986122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
299dff0c46cSDimitry Andric static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
3006122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
301dff0c46cSDimitry Andric static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
3026122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
303dff0c46cSDimitry Andric static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
3046122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
305dff0c46cSDimitry Andric static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
3066122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
307dff0c46cSDimitry Andric static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
3086122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
309dff0c46cSDimitry Andric static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
3106122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
311dff0c46cSDimitry Andric static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
3126122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
313dff0c46cSDimitry Andric static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
3146122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
315dff0c46cSDimitry Andric static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
3166122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
317dff0c46cSDimitry Andric static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
3186122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
319dff0c46cSDimitry Andric static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
3206122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
321dff0c46cSDimitry Andric static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
3226122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder);
323dff0c46cSDimitry Andric static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
3246122f3e6SDimitry Andric                                 uint64_t Address, const void *Decoder);
325dff0c46cSDimitry Andric static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
3266122f3e6SDimitry Andric                                 uint64_t Address, const void *Decoder);
3272cab237bSDimitry Andric static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst,
3282cab237bSDimitry Andric                                                        unsigned Val,
3292cab237bSDimitry Andric                                                        uint64_t Address,
3302cab237bSDimitry Andric                                                        const void *Decoder);
331f22ef01cSRoman Divacky 
332dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
333dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
334dff0c46cSDimitry Andric static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
335dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
336dff0c46cSDimitry Andric static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
337dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
338dff0c46cSDimitry Andric static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
339dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
340dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
341dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
342dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
343dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
344dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
345dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
346dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
347dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
348dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
349dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
350dff0c46cSDimitry Andric static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
351dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
352f785676fSDimitry Andric static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
353f785676fSDimitry Andric                                uint64_t Address, const void* Decoder);
354f785676fSDimitry Andric static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
355f785676fSDimitry Andric                                uint64_t Address, const void* Decoder);
356f785676fSDimitry Andric static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
357f785676fSDimitry Andric                                uint64_t Address, const void* Decoder);
358f785676fSDimitry Andric static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
359f785676fSDimitry Andric                                uint64_t Address, const void* Decoder);
360dff0c46cSDimitry Andric static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
361dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
362dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
363dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
364dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
365dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
366dff0c46cSDimitry Andric static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
367dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
368dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
369dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
370dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
371dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
372dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
373dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
374dff0c46cSDimitry Andric static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
375dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
376f785676fSDimitry Andric static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
377f785676fSDimitry Andric                                 uint64_t Address, const void *Decoder);
378dff0c46cSDimitry Andric static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
379dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
380dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
381dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
382dff0c46cSDimitry Andric static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
383dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
384dff0c46cSDimitry Andric static DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
385dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
386dff0c46cSDimitry Andric static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
387dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
388dff0c46cSDimitry Andric static DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val,
389dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
390dff0c46cSDimitry Andric static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
391dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
392dff0c46cSDimitry Andric static DecodeStatus DecodeIT(MCInst &Inst, unsigned Val,
393dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
394dff0c46cSDimitry Andric static DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn,
395dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
396dff0c46cSDimitry Andric static DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn,
397dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder);
398dff0c46cSDimitry Andric static DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val,
399dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
400dff0c46cSDimitry Andric static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
401dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
402dff0c46cSDimitry Andric static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
403dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
404f22ef01cSRoman Divacky 
405dff0c46cSDimitry Andric static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
406dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder);
4077a7e6055SDimitry Andric static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
408cb4dff85SDimitry Andric                                             uint64_t Address, const void *Decoder);
4092cab237bSDimitry Andric static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
4102cab237bSDimitry Andric                                          uint64_t Address, const void *Decoder);
4117a7e6055SDimitry Andric 
4126122f3e6SDimitry Andric #include "ARMGenDisassemblerTables.inc"
4136122f3e6SDimitry Andric 
createARMDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)41491bc56edSDimitry Andric static MCDisassembler *createARMDisassembler(const Target &T,
41591bc56edSDimitry Andric                                              const MCSubtargetInfo &STI,
41691bc56edSDimitry Andric                                              MCContext &Ctx) {
41791bc56edSDimitry Andric   return new ARMDisassembler(STI, Ctx);
418f22ef01cSRoman Divacky }
419f22ef01cSRoman Divacky 
createThumbDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)42091bc56edSDimitry Andric static MCDisassembler *createThumbDisassembler(const Target &T,
42191bc56edSDimitry Andric                                                const MCSubtargetInfo &STI,
42291bc56edSDimitry Andric                                                MCContext &Ctx) {
42391bc56edSDimitry Andric   return new ThumbDisassembler(STI, Ctx);
424f22ef01cSRoman Divacky }
425f22ef01cSRoman Divacky 
42639d628a0SDimitry Andric // Post-decoding checks
checkDecodedInstruction(MCInst & MI,uint64_t & Size,uint64_t Address,raw_ostream & OS,raw_ostream & CS,uint32_t Insn,DecodeStatus Result)42739d628a0SDimitry Andric static DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,
42839d628a0SDimitry Andric                                             uint64_t Address, raw_ostream &OS,
42939d628a0SDimitry Andric                                             raw_ostream &CS,
43039d628a0SDimitry Andric                                             uint32_t Insn,
4317a7e6055SDimitry Andric                                             DecodeStatus Result) {
43239d628a0SDimitry Andric   switch (MI.getOpcode()) {
43339d628a0SDimitry Andric     case ARM::HVC: {
43439d628a0SDimitry Andric       // HVC is undefined if condition = 0xf otherwise upredictable
43539d628a0SDimitry Andric       // if condition != 0xe
43639d628a0SDimitry Andric       uint32_t Cond = (Insn >> 28) & 0xF;
43739d628a0SDimitry Andric       if (Cond == 0xF)
43839d628a0SDimitry Andric         return MCDisassembler::Fail;
43939d628a0SDimitry Andric       if (Cond != 0xE)
44039d628a0SDimitry Andric         return MCDisassembler::SoftFail;
44139d628a0SDimitry Andric       return Result;
44239d628a0SDimitry Andric     }
44339d628a0SDimitry Andric     default: return Result;
44439d628a0SDimitry Andric   }
44539d628a0SDimitry Andric }
4466122f3e6SDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const44739d628a0SDimitry Andric DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
44839d628a0SDimitry Andric                                              ArrayRef<uint8_t> Bytes,
44939d628a0SDimitry Andric                                              uint64_t Address, raw_ostream &OS,
45039d628a0SDimitry Andric                                              raw_ostream &CS) const {
45139d628a0SDimitry Andric   CommentStream = &CS;
4526122f3e6SDimitry Andric 
453ff0cc061SDimitry Andric   assert(!STI.getFeatureBits()[ARM::ModeThumb] &&
45439d628a0SDimitry Andric          "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
45539d628a0SDimitry Andric          "mode!");
4566122f3e6SDimitry Andric 
4576122f3e6SDimitry Andric   // We want to read exactly 4 bytes of data.
45839d628a0SDimitry Andric   if (Bytes.size() < 4) {
4596122f3e6SDimitry Andric     Size = 0;
4606122f3e6SDimitry Andric     return MCDisassembler::Fail;
4616122f3e6SDimitry Andric   }
4626122f3e6SDimitry Andric 
4636122f3e6SDimitry Andric   // Encoded as a small-endian 32-bit word in the stream.
46439d628a0SDimitry Andric   uint32_t Insn =
46539d628a0SDimitry Andric       (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
4666122f3e6SDimitry Andric 
4676122f3e6SDimitry Andric   // Calling the auto-generated decoder function.
46839d628a0SDimitry Andric   DecodeStatus Result =
46939d628a0SDimitry Andric       decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI);
47039d628a0SDimitry Andric   if (Result != MCDisassembler::Fail) {
4716122f3e6SDimitry Andric     Size = 4;
47239d628a0SDimitry Andric     return checkDecodedInstruction(MI, Size, Address, OS, CS, Insn, Result);
4736122f3e6SDimitry Andric   }
4746122f3e6SDimitry Andric 
4757a7e6055SDimitry Andric   struct DecodeTable {
4767a7e6055SDimitry Andric     const uint8_t *P;
4777a7e6055SDimitry Andric     bool DecodePred;
4787a7e6055SDimitry Andric   };
4796122f3e6SDimitry Andric 
4807a7e6055SDimitry Andric   const DecodeTable Tables[] = {
4817a7e6055SDimitry Andric       {DecoderTableVFP32, false},      {DecoderTableVFPV832, false},
4827a7e6055SDimitry Andric       {DecoderTableNEONData32, true},  {DecoderTableNEONLoadStore32, true},
4837a7e6055SDimitry Andric       {DecoderTableNEONDup32, true},   {DecoderTablev8NEON32, false},
4847a7e6055SDimitry Andric       {DecoderTablev8Crypto32, false},
4857a7e6055SDimitry Andric   };
486f785676fSDimitry Andric 
4877a7e6055SDimitry Andric   for (auto Table : Tables) {
4887a7e6055SDimitry Andric     Result = decodeInstruction(Table.P, MI, Insn, Address, this, STI);
48939d628a0SDimitry Andric     if (Result != MCDisassembler::Fail) {
4906122f3e6SDimitry Andric       Size = 4;
4916122f3e6SDimitry Andric       // Add a fake predicate operand, because we share these instruction
4926122f3e6SDimitry Andric       // definitions with Thumb2 where these instructions are predicable.
4937a7e6055SDimitry Andric       if (Table.DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this))
4946122f3e6SDimitry Andric         return MCDisassembler::Fail;
49539d628a0SDimitry Andric       return Result;
4966122f3e6SDimitry Andric     }
497f785676fSDimitry Andric   }
498f785676fSDimitry Andric 
4992cab237bSDimitry Andric   Result =
5002cab237bSDimitry Andric       decodeInstruction(DecoderTableCoProc32, MI, Insn, Address, this, STI);
5012cab237bSDimitry Andric   if (Result != MCDisassembler::Fail) {
5022cab237bSDimitry Andric     Size = 4;
5032cab237bSDimitry Andric     return checkDecodedInstruction(MI, Size, Address, OS, CS, Insn, Result);
5042cab237bSDimitry Andric   }
5052cab237bSDimitry Andric 
506a580b014SDimitry Andric   Size = 4;
5076122f3e6SDimitry Andric   return MCDisassembler::Fail;
5086122f3e6SDimitry Andric }
5096122f3e6SDimitry Andric 
5106122f3e6SDimitry Andric namespace llvm {
5117a7e6055SDimitry Andric 
512dff0c46cSDimitry Andric extern const MCInstrDesc ARMInsts[];
5137a7e6055SDimitry Andric 
5147a7e6055SDimitry Andric } // end namespace llvm
5156122f3e6SDimitry Andric 
5166122f3e6SDimitry Andric /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
5176122f3e6SDimitry Andric /// immediate Value in the MCInst.  The immediate Value has had any PC
5186122f3e6SDimitry Andric /// adjustment made by the caller.  If the instruction is a branch instruction
5196122f3e6SDimitry Andric /// then isBranch is true, else false.  If the getOpInfo() function was set as
5206122f3e6SDimitry Andric /// part of the setupForSymbolicDisassembly() call then that function is called
5216122f3e6SDimitry Andric /// to get any symbolic information at the Address for this instruction.  If
5226122f3e6SDimitry Andric /// that returns non-zero then the symbolic information it returns is used to
5236122f3e6SDimitry Andric /// create an MCExpr and that is added as an operand to the MCInst.  If
5246122f3e6SDimitry Andric /// getOpInfo() returns zero and isBranch is true then a symbol look up for
5256122f3e6SDimitry Andric /// Value is done and if a symbol is found an MCExpr is created with that, else
5266122f3e6SDimitry Andric /// an MCExpr with Value is created.  This function returns true if it adds an
5276122f3e6SDimitry Andric /// operand to the MCInst and false otherwise.
tryAddingSymbolicOperand(uint64_t Address,int32_t Value,bool isBranch,uint64_t InstSize,MCInst & MI,const void * Decoder)5286122f3e6SDimitry Andric static bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
5296122f3e6SDimitry Andric                                      bool isBranch, uint64_t InstSize,
5306122f3e6SDimitry Andric                                      MCInst &MI, const void *Decoder) {
5316122f3e6SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
532f785676fSDimitry Andric   // FIXME: Does it make sense for value to be negative?
533f785676fSDimitry Andric   return Dis->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address, isBranch,
534f785676fSDimitry Andric                                        /* Offset */ 0, InstSize);
5356122f3e6SDimitry Andric }
5366122f3e6SDimitry Andric 
5376122f3e6SDimitry Andric /// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
5386122f3e6SDimitry Andric /// referenced by a load instruction with the base register that is the Pc.
5396122f3e6SDimitry Andric /// These can often be values in a literal pool near the Address of the
5406122f3e6SDimitry Andric /// instruction.  The Address of the instruction and its immediate Value are
5416122f3e6SDimitry Andric /// used as a possible literal pool entry.  The SymbolLookUp call back will
5427ae0e2c9SDimitry Andric /// return the name of a symbol referenced by the literal pool's entry if
5436122f3e6SDimitry Andric /// the referenced address is that of a symbol.  Or it will return a pointer to
5446122f3e6SDimitry Andric /// a literal 'C' string if the referenced address of the literal pool's entry
5456122f3e6SDimitry Andric /// is an address into a section with 'C' string literals.
tryAddingPcLoadReferenceComment(uint64_t Address,int Value,const void * Decoder)5466122f3e6SDimitry Andric static void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
5476122f3e6SDimitry Andric                                             const void *Decoder) {
5486122f3e6SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
549f785676fSDimitry Andric   Dis->tryAddingPcLoadReferenceComment(Value, Address);
5506122f3e6SDimitry Andric }
5516122f3e6SDimitry Andric 
5526122f3e6SDimitry Andric // Thumb1 instructions don't have explicit S bits.  Rather, they
5536122f3e6SDimitry Andric // implicitly set CPSR.  Since it's not represented in the encoding, the
5546122f3e6SDimitry Andric // auto-generated decoder won't inject the CPSR operand.  We need to fix
5556122f3e6SDimitry Andric // that as a post-pass.
AddThumb1SBit(MCInst & MI,bool InITBlock)5566122f3e6SDimitry Andric static void AddThumb1SBit(MCInst &MI, bool InITBlock) {
5576122f3e6SDimitry Andric   const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
5586122f3e6SDimitry Andric   unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
5596122f3e6SDimitry Andric   MCInst::iterator I = MI.begin();
5606122f3e6SDimitry Andric   for (unsigned i = 0; i < NumOps; ++i, ++I) {
5616122f3e6SDimitry Andric     if (I == MI.end()) break;
5626122f3e6SDimitry Andric     if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
5636122f3e6SDimitry Andric       if (i > 0 && OpInfo[i-1].isPredicate()) continue;
564ff0cc061SDimitry Andric       MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
5656122f3e6SDimitry Andric       return;
5666122f3e6SDimitry Andric     }
5676122f3e6SDimitry Andric   }
5686122f3e6SDimitry Andric 
569ff0cc061SDimitry Andric   MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
5706122f3e6SDimitry Andric }
5716122f3e6SDimitry Andric 
5726122f3e6SDimitry Andric // Most Thumb instructions don't have explicit predicates in the
5736122f3e6SDimitry Andric // encoding, but rather get their predicates from IT context.  We need
5746122f3e6SDimitry Andric // to fix up the predicate operands using this context information as a
5756122f3e6SDimitry Andric // post-pass.
5766122f3e6SDimitry Andric MCDisassembler::DecodeStatus
AddThumbPredicate(MCInst & MI) const5776122f3e6SDimitry Andric ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
5786122f3e6SDimitry Andric   MCDisassembler::DecodeStatus S = Success;
5796122f3e6SDimitry Andric 
5803ca95b02SDimitry Andric   const FeatureBitset &FeatureBits = getSubtargetInfo().getFeatureBits();
5813ca95b02SDimitry Andric 
5826122f3e6SDimitry Andric   // A few instructions actually have predicates encoded in them.  Don't
5836122f3e6SDimitry Andric   // try to overwrite it if we're seeing one of those.
5846122f3e6SDimitry Andric   switch (MI.getOpcode()) {
5856122f3e6SDimitry Andric     case ARM::tBcc:
5866122f3e6SDimitry Andric     case ARM::t2Bcc:
5876122f3e6SDimitry Andric     case ARM::tCBZ:
5886122f3e6SDimitry Andric     case ARM::tCBNZ:
5896122f3e6SDimitry Andric     case ARM::tCPS:
5906122f3e6SDimitry Andric     case ARM::t2CPS3p:
5916122f3e6SDimitry Andric     case ARM::t2CPS2p:
5926122f3e6SDimitry Andric     case ARM::t2CPS1p:
5936122f3e6SDimitry Andric     case ARM::tMOVSr:
5946122f3e6SDimitry Andric     case ARM::tSETEND:
5956122f3e6SDimitry Andric       // Some instructions (mostly conditional branches) are not
5966122f3e6SDimitry Andric       // allowed in IT blocks.
5977ae0e2c9SDimitry Andric       if (ITBlock.instrInITBlock())
5986122f3e6SDimitry Andric         S = SoftFail;
5996122f3e6SDimitry Andric       else
6006122f3e6SDimitry Andric         return Success;
6016122f3e6SDimitry Andric       break;
6023ca95b02SDimitry Andric     case ARM::t2HINT:
6033ca95b02SDimitry Andric       if (MI.getOperand(0).getImm() == 0x10 && (FeatureBits[ARM::FeatureRAS]) != 0)
6043ca95b02SDimitry Andric         S = SoftFail;
6053ca95b02SDimitry Andric       break;
6066122f3e6SDimitry Andric     case ARM::tB:
6076122f3e6SDimitry Andric     case ARM::t2B:
6086122f3e6SDimitry Andric     case ARM::t2TBB:
6096122f3e6SDimitry Andric     case ARM::t2TBH:
6106122f3e6SDimitry Andric       // Some instructions (mostly unconditional branches) can
6116122f3e6SDimitry Andric       // only appears at the end of, or outside of, an IT.
6127ae0e2c9SDimitry Andric       if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
6136122f3e6SDimitry Andric         S = SoftFail;
6146122f3e6SDimitry Andric       break;
6156122f3e6SDimitry Andric     default:
6166122f3e6SDimitry Andric       break;
6176122f3e6SDimitry Andric   }
6186122f3e6SDimitry Andric 
6196122f3e6SDimitry Andric   // If we're in an IT block, base the predicate on that.  Otherwise,
6206122f3e6SDimitry Andric   // assume a predicate of AL.
6216122f3e6SDimitry Andric   unsigned CC;
6227ae0e2c9SDimitry Andric   CC = ITBlock.getITCC();
6236122f3e6SDimitry Andric   if (CC == 0xF)
6246122f3e6SDimitry Andric     CC = ARMCC::AL;
6257ae0e2c9SDimitry Andric   if (ITBlock.instrInITBlock())
6267ae0e2c9SDimitry Andric     ITBlock.advanceITState();
6276122f3e6SDimitry Andric 
6286122f3e6SDimitry Andric   const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
6296122f3e6SDimitry Andric   unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
6306122f3e6SDimitry Andric   MCInst::iterator I = MI.begin();
6316122f3e6SDimitry Andric   for (unsigned i = 0; i < NumOps; ++i, ++I) {
6326122f3e6SDimitry Andric     if (I == MI.end()) break;
6336122f3e6SDimitry Andric     if (OpInfo[i].isPredicate()) {
634ff0cc061SDimitry Andric       I = MI.insert(I, MCOperand::createImm(CC));
6356122f3e6SDimitry Andric       ++I;
6366122f3e6SDimitry Andric       if (CC == ARMCC::AL)
637ff0cc061SDimitry Andric         MI.insert(I, MCOperand::createReg(0));
6386122f3e6SDimitry Andric       else
639ff0cc061SDimitry Andric         MI.insert(I, MCOperand::createReg(ARM::CPSR));
6406122f3e6SDimitry Andric       return S;
6416122f3e6SDimitry Andric     }
6426122f3e6SDimitry Andric   }
6436122f3e6SDimitry Andric 
644ff0cc061SDimitry Andric   I = MI.insert(I, MCOperand::createImm(CC));
6456122f3e6SDimitry Andric   ++I;
6466122f3e6SDimitry Andric   if (CC == ARMCC::AL)
647ff0cc061SDimitry Andric     MI.insert(I, MCOperand::createReg(0));
6486122f3e6SDimitry Andric   else
649ff0cc061SDimitry Andric     MI.insert(I, MCOperand::createReg(ARM::CPSR));
6506122f3e6SDimitry Andric 
6516122f3e6SDimitry Andric   return S;
6526122f3e6SDimitry Andric }
6536122f3e6SDimitry Andric 
6546122f3e6SDimitry Andric // Thumb VFP instructions are a special case.  Because we share their
6556122f3e6SDimitry Andric // encodings between ARM and Thumb modes, and they are predicable in ARM
6566122f3e6SDimitry Andric // mode, the auto-generated decoder will give them an (incorrect)
6576122f3e6SDimitry Andric // predicate operand.  We need to rewrite these operands based on the IT
6586122f3e6SDimitry Andric // context as a post-pass.
UpdateThumbVFPPredicate(MCInst & MI) const6596122f3e6SDimitry Andric void ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const {
6606122f3e6SDimitry Andric   unsigned CC;
6617ae0e2c9SDimitry Andric   CC = ITBlock.getITCC();
662*4ba319b5SDimitry Andric   if (CC == 0xF)
663*4ba319b5SDimitry Andric     CC = ARMCC::AL;
6647ae0e2c9SDimitry Andric   if (ITBlock.instrInITBlock())
6657ae0e2c9SDimitry Andric     ITBlock.advanceITState();
6666122f3e6SDimitry Andric 
6676122f3e6SDimitry Andric   const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
6686122f3e6SDimitry Andric   MCInst::iterator I = MI.begin();
6696122f3e6SDimitry Andric   unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
6706122f3e6SDimitry Andric   for (unsigned i = 0; i < NumOps; ++i, ++I) {
6716122f3e6SDimitry Andric     if (OpInfo[i].isPredicate() ) {
6726122f3e6SDimitry Andric       I->setImm(CC);
6736122f3e6SDimitry Andric       ++I;
6746122f3e6SDimitry Andric       if (CC == ARMCC::AL)
6756122f3e6SDimitry Andric         I->setReg(0);
6766122f3e6SDimitry Andric       else
6776122f3e6SDimitry Andric         I->setReg(ARM::CPSR);
6786122f3e6SDimitry Andric       return;
6796122f3e6SDimitry Andric     }
6806122f3e6SDimitry Andric   }
6816122f3e6SDimitry Andric }
6826122f3e6SDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const6836122f3e6SDimitry Andric DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
68439d628a0SDimitry Andric                                                ArrayRef<uint8_t> Bytes,
6856122f3e6SDimitry Andric                                                uint64_t Address,
68639d628a0SDimitry Andric                                                raw_ostream &OS,
68739d628a0SDimitry Andric                                                raw_ostream &CS) const {
68839d628a0SDimitry Andric   CommentStream = &CS;
6896122f3e6SDimitry Andric 
690ff0cc061SDimitry Andric   assert(STI.getFeatureBits()[ARM::ModeThumb] &&
6916122f3e6SDimitry Andric          "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
6926122f3e6SDimitry Andric 
6936122f3e6SDimitry Andric   // We want to read exactly 2 bytes of data.
69439d628a0SDimitry Andric   if (Bytes.size() < 2) {
6956122f3e6SDimitry Andric     Size = 0;
6966122f3e6SDimitry Andric     return MCDisassembler::Fail;
6976122f3e6SDimitry Andric   }
6986122f3e6SDimitry Andric 
69939d628a0SDimitry Andric   uint16_t Insn16 = (Bytes[1] << 8) | Bytes[0];
70039d628a0SDimitry Andric   DecodeStatus Result =
70139d628a0SDimitry Andric       decodeInstruction(DecoderTableThumb16, MI, Insn16, Address, this, STI);
70239d628a0SDimitry Andric   if (Result != MCDisassembler::Fail) {
7036122f3e6SDimitry Andric     Size = 2;
70439d628a0SDimitry Andric     Check(Result, AddThumbPredicate(MI));
70539d628a0SDimitry Andric     return Result;
7066122f3e6SDimitry Andric   }
7076122f3e6SDimitry Andric 
70839d628a0SDimitry Andric   Result = decodeInstruction(DecoderTableThumbSBit16, MI, Insn16, Address, this,
70939d628a0SDimitry Andric                              STI);
71039d628a0SDimitry Andric   if (Result) {
7116122f3e6SDimitry Andric     Size = 2;
7127ae0e2c9SDimitry Andric     bool InITBlock = ITBlock.instrInITBlock();
71339d628a0SDimitry Andric     Check(Result, AddThumbPredicate(MI));
7146122f3e6SDimitry Andric     AddThumb1SBit(MI, InITBlock);
71539d628a0SDimitry Andric     return Result;
7166122f3e6SDimitry Andric   }
7176122f3e6SDimitry Andric 
71839d628a0SDimitry Andric   Result =
71939d628a0SDimitry Andric       decodeInstruction(DecoderTableThumb216, MI, Insn16, Address, this, STI);
72039d628a0SDimitry Andric   if (Result != MCDisassembler::Fail) {
7216122f3e6SDimitry Andric     Size = 2;
7226122f3e6SDimitry Andric 
7236122f3e6SDimitry Andric     // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
7246122f3e6SDimitry Andric     // the Thumb predicate.
7257ae0e2c9SDimitry Andric     if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
72639d628a0SDimitry Andric       Result = MCDisassembler::SoftFail;
7276122f3e6SDimitry Andric 
72839d628a0SDimitry Andric     Check(Result, AddThumbPredicate(MI));
7296122f3e6SDimitry Andric 
7306122f3e6SDimitry Andric     // If we find an IT instruction, we need to parse its condition
7316122f3e6SDimitry Andric     // code and mask operands so that we can apply them correctly
7326122f3e6SDimitry Andric     // to the subsequent instructions.
7336122f3e6SDimitry Andric     if (MI.getOpcode() == ARM::t2IT) {
7347ae0e2c9SDimitry Andric       unsigned Firstcond = MI.getOperand(0).getImm();
7356122f3e6SDimitry Andric       unsigned Mask = MI.getOperand(1).getImm();
7367ae0e2c9SDimitry Andric       ITBlock.setITState(Firstcond, Mask);
737*4ba319b5SDimitry Andric 
738*4ba319b5SDimitry Andric       // An IT instruction that would give a 'NV' predicate is unpredictable.
739*4ba319b5SDimitry Andric       if (Firstcond == ARMCC::AL && !isPowerOf2_32(Mask))
740*4ba319b5SDimitry Andric         CS << "unpredictable IT predicate sequence";
7416122f3e6SDimitry Andric     }
7426122f3e6SDimitry Andric 
74339d628a0SDimitry Andric     return Result;
7446122f3e6SDimitry Andric   }
7456122f3e6SDimitry Andric 
7466122f3e6SDimitry Andric   // We want to read exactly 4 bytes of data.
74739d628a0SDimitry Andric   if (Bytes.size() < 4) {
7486122f3e6SDimitry Andric     Size = 0;
7496122f3e6SDimitry Andric     return MCDisassembler::Fail;
7506122f3e6SDimitry Andric   }
7516122f3e6SDimitry Andric 
75239d628a0SDimitry Andric   uint32_t Insn32 =
75339d628a0SDimitry Andric       (Bytes[3] << 8) | (Bytes[2] << 0) | (Bytes[1] << 24) | (Bytes[0] << 16);
75439d628a0SDimitry Andric   Result =
75539d628a0SDimitry Andric       decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
75639d628a0SDimitry Andric   if (Result != MCDisassembler::Fail) {
7576122f3e6SDimitry Andric     Size = 4;
7587ae0e2c9SDimitry Andric     bool InITBlock = ITBlock.instrInITBlock();
75939d628a0SDimitry Andric     Check(Result, AddThumbPredicate(MI));
7606122f3e6SDimitry Andric     AddThumb1SBit(MI, InITBlock);
76139d628a0SDimitry Andric     return Result;
7626122f3e6SDimitry Andric   }
7636122f3e6SDimitry Andric 
76439d628a0SDimitry Andric   Result =
76539d628a0SDimitry Andric       decodeInstruction(DecoderTableThumb232, MI, Insn32, Address, this, STI);
76639d628a0SDimitry Andric   if (Result != MCDisassembler::Fail) {
7676122f3e6SDimitry Andric     Size = 4;
76839d628a0SDimitry Andric     Check(Result, AddThumbPredicate(MI));
76939d628a0SDimitry Andric     return Result;
7706122f3e6SDimitry Andric   }
7716122f3e6SDimitry Andric 
77239d628a0SDimitry Andric   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
77339d628a0SDimitry Andric     Result =
77439d628a0SDimitry Andric         decodeInstruction(DecoderTableVFP32, MI, Insn32, Address, this, STI);
77539d628a0SDimitry Andric     if (Result != MCDisassembler::Fail) {
7766122f3e6SDimitry Andric       Size = 4;
7776122f3e6SDimitry Andric       UpdateThumbVFPPredicate(MI);
77839d628a0SDimitry Andric       return Result;
7796122f3e6SDimitry Andric     }
780f785676fSDimitry Andric   }
7816122f3e6SDimitry Andric 
78239d628a0SDimitry Andric   Result =
78339d628a0SDimitry Andric       decodeInstruction(DecoderTableVFPV832, MI, Insn32, Address, this, STI);
78439d628a0SDimitry Andric   if (Result != MCDisassembler::Fail) {
785f785676fSDimitry Andric     Size = 4;
78639d628a0SDimitry Andric     return Result;
787f785676fSDimitry Andric   }
788f785676fSDimitry Andric 
78939d628a0SDimitry Andric   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
79039d628a0SDimitry Andric     Result = decodeInstruction(DecoderTableNEONDup32, MI, Insn32, Address, this,
79139d628a0SDimitry Andric                                STI);
79239d628a0SDimitry Andric     if (Result != MCDisassembler::Fail) {
7936122f3e6SDimitry Andric       Size = 4;
79439d628a0SDimitry Andric       Check(Result, AddThumbPredicate(MI));
79539d628a0SDimitry Andric       return Result;
7966122f3e6SDimitry Andric     }
797f785676fSDimitry Andric   }
7986122f3e6SDimitry Andric 
79939d628a0SDimitry Andric   if (fieldFromInstruction(Insn32, 24, 8) == 0xF9) {
80039d628a0SDimitry Andric     uint32_t NEONLdStInsn = Insn32;
8016122f3e6SDimitry Andric     NEONLdStInsn &= 0xF0FFFFFF;
8026122f3e6SDimitry Andric     NEONLdStInsn |= 0x04000000;
80339d628a0SDimitry Andric     Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
8047ae0e2c9SDimitry Andric                                Address, this, STI);
80539d628a0SDimitry Andric     if (Result != MCDisassembler::Fail) {
8066122f3e6SDimitry Andric       Size = 4;
80739d628a0SDimitry Andric       Check(Result, AddThumbPredicate(MI));
80839d628a0SDimitry Andric       return Result;
8096122f3e6SDimitry Andric     }
8106122f3e6SDimitry Andric   }
8116122f3e6SDimitry Andric 
81239d628a0SDimitry Andric   if (fieldFromInstruction(Insn32, 24, 4) == 0xF) {
81339d628a0SDimitry Andric     uint32_t NEONDataInsn = Insn32;
8146122f3e6SDimitry Andric     NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
8156122f3e6SDimitry Andric     NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
8166122f3e6SDimitry Andric     NEONDataInsn |= 0x12000000; // Set bits 28 and 25
81739d628a0SDimitry Andric     Result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
8187ae0e2c9SDimitry Andric                                Address, this, STI);
81939d628a0SDimitry Andric     if (Result != MCDisassembler::Fail) {
8206122f3e6SDimitry Andric       Size = 4;
82139d628a0SDimitry Andric       Check(Result, AddThumbPredicate(MI));
82239d628a0SDimitry Andric       return Result;
8236122f3e6SDimitry Andric     }
824f785676fSDimitry Andric 
82539d628a0SDimitry Andric     uint32_t NEONCryptoInsn = Insn32;
826f785676fSDimitry Andric     NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
827f785676fSDimitry Andric     NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
828f785676fSDimitry Andric     NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
82939d628a0SDimitry Andric     Result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
830f785676fSDimitry Andric                                Address, this, STI);
83139d628a0SDimitry Andric     if (Result != MCDisassembler::Fail) {
832f785676fSDimitry Andric       Size = 4;
83339d628a0SDimitry Andric       return Result;
8346122f3e6SDimitry Andric     }
8356122f3e6SDimitry Andric 
83639d628a0SDimitry Andric     uint32_t NEONv8Insn = Insn32;
837f785676fSDimitry Andric     NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
83839d628a0SDimitry Andric     Result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
839f785676fSDimitry Andric                                this, STI);
84039d628a0SDimitry Andric     if (Result != MCDisassembler::Fail) {
841f785676fSDimitry Andric       Size = 4;
84239d628a0SDimitry Andric       return Result;
843f785676fSDimitry Andric     }
844f785676fSDimitry Andric   }
845f785676fSDimitry Andric 
8462cab237bSDimitry Andric   Result =
8472cab237bSDimitry Andric       decodeInstruction(DecoderTableThumb2CoProc32, MI, Insn32, Address, this, STI);
8482cab237bSDimitry Andric   if (Result != MCDisassembler::Fail) {
8492cab237bSDimitry Andric     Size = 4;
8502cab237bSDimitry Andric     Check(Result, AddThumbPredicate(MI));
8512cab237bSDimitry Andric     return Result;
8522cab237bSDimitry Andric   }
8532cab237bSDimitry Andric 
8546122f3e6SDimitry Andric   Size = 0;
8556122f3e6SDimitry Andric   return MCDisassembler::Fail;
8566122f3e6SDimitry Andric }
8576122f3e6SDimitry Andric 
LLVMInitializeARMDisassembler()8586122f3e6SDimitry Andric extern "C" void LLVMInitializeARMDisassembler() {
859d88c1a5aSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARMLETarget(),
8606122f3e6SDimitry Andric                                          createARMDisassembler);
861d88c1a5aSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARMBETarget(),
86291bc56edSDimitry Andric                                          createARMDisassembler);
863d88c1a5aSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheThumbLETarget(),
86491bc56edSDimitry Andric                                          createThumbDisassembler);
865d88c1a5aSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheThumbBETarget(),
8666122f3e6SDimitry Andric                                          createThumbDisassembler);
8676122f3e6SDimitry Andric }
8686122f3e6SDimitry Andric 
869dff0c46cSDimitry Andric static const uint16_t GPRDecoderTable[] = {
8706122f3e6SDimitry Andric   ARM::R0, ARM::R1, ARM::R2, ARM::R3,
8716122f3e6SDimitry Andric   ARM::R4, ARM::R5, ARM::R6, ARM::R7,
8726122f3e6SDimitry Andric   ARM::R8, ARM::R9, ARM::R10, ARM::R11,
8736122f3e6SDimitry Andric   ARM::R12, ARM::SP, ARM::LR, ARM::PC
8746122f3e6SDimitry Andric };
8756122f3e6SDimitry Andric 
DecodeGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)876dff0c46cSDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
8776122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
8786122f3e6SDimitry Andric   if (RegNo > 15)
8796122f3e6SDimitry Andric     return MCDisassembler::Fail;
8806122f3e6SDimitry Andric 
8816122f3e6SDimitry Andric   unsigned Register = GPRDecoderTable[RegNo];
882ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
8836122f3e6SDimitry Andric   return MCDisassembler::Success;
8846122f3e6SDimitry Andric }
8856122f3e6SDimitry Andric 
8866122f3e6SDimitry Andric static DecodeStatus
DecodeGPRnopcRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)887dff0c46cSDimitry Andric DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
8886122f3e6SDimitry Andric                            uint64_t Address, const void *Decoder) {
889dff0c46cSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
890dff0c46cSDimitry Andric 
891dff0c46cSDimitry Andric   if (RegNo == 15)
892dff0c46cSDimitry Andric     S = MCDisassembler::SoftFail;
893dff0c46cSDimitry Andric 
894dff0c46cSDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
895dff0c46cSDimitry Andric 
896dff0c46cSDimitry Andric   return S;
8976122f3e6SDimitry Andric }
8986122f3e6SDimitry Andric 
899f785676fSDimitry Andric static DecodeStatus
DecodeGPRwithAPSRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)900f785676fSDimitry Andric DecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo,
901f785676fSDimitry Andric                                uint64_t Address, const void *Decoder) {
902f785676fSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
903f785676fSDimitry Andric 
904f785676fSDimitry Andric   if (RegNo == 15)
905f785676fSDimitry Andric   {
906ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
907f785676fSDimitry Andric     return MCDisassembler::Success;
908f785676fSDimitry Andric   }
909f785676fSDimitry Andric 
910f785676fSDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
911f785676fSDimitry Andric   return S;
912f785676fSDimitry Andric }
913f785676fSDimitry Andric 
DecodetGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)914dff0c46cSDimitry Andric static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
9156122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
9166122f3e6SDimitry Andric   if (RegNo > 7)
9176122f3e6SDimitry Andric     return MCDisassembler::Fail;
9186122f3e6SDimitry Andric   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
9196122f3e6SDimitry Andric }
9206122f3e6SDimitry Andric 
921f785676fSDimitry Andric static const uint16_t GPRPairDecoderTable[] = {
922f785676fSDimitry Andric   ARM::R0_R1, ARM::R2_R3,   ARM::R4_R5,  ARM::R6_R7,
923f785676fSDimitry Andric   ARM::R8_R9, ARM::R10_R11, ARM::R12_SP
924f785676fSDimitry Andric };
925f785676fSDimitry Andric 
DecodeGPRPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)926f785676fSDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
927f785676fSDimitry Andric                                    uint64_t Address, const void *Decoder) {
928f785676fSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
929f785676fSDimitry Andric 
930f785676fSDimitry Andric   if (RegNo > 13)
931f785676fSDimitry Andric     return MCDisassembler::Fail;
932f785676fSDimitry Andric 
933f785676fSDimitry Andric   if ((RegNo & 1) || RegNo == 0xe)
934f785676fSDimitry Andric      S = MCDisassembler::SoftFail;
935f785676fSDimitry Andric 
936f785676fSDimitry Andric   unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
937ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(RegisterPair));
938f785676fSDimitry Andric   return S;
939f785676fSDimitry Andric }
940f785676fSDimitry Andric 
DecodetcGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)941dff0c46cSDimitry Andric static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
9426122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
9436122f3e6SDimitry Andric   unsigned Register = 0;
9446122f3e6SDimitry Andric   switch (RegNo) {
9456122f3e6SDimitry Andric     case 0:
9466122f3e6SDimitry Andric       Register = ARM::R0;
9476122f3e6SDimitry Andric       break;
9486122f3e6SDimitry Andric     case 1:
9496122f3e6SDimitry Andric       Register = ARM::R1;
9506122f3e6SDimitry Andric       break;
9516122f3e6SDimitry Andric     case 2:
9526122f3e6SDimitry Andric       Register = ARM::R2;
9536122f3e6SDimitry Andric       break;
9546122f3e6SDimitry Andric     case 3:
9556122f3e6SDimitry Andric       Register = ARM::R3;
9566122f3e6SDimitry Andric       break;
9576122f3e6SDimitry Andric     case 9:
9586122f3e6SDimitry Andric       Register = ARM::R9;
9596122f3e6SDimitry Andric       break;
9606122f3e6SDimitry Andric     case 12:
9616122f3e6SDimitry Andric       Register = ARM::R12;
9626122f3e6SDimitry Andric       break;
9636122f3e6SDimitry Andric     default:
9646122f3e6SDimitry Andric       return MCDisassembler::Fail;
9656122f3e6SDimitry Andric     }
9666122f3e6SDimitry Andric 
967ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
9686122f3e6SDimitry Andric   return MCDisassembler::Success;
9696122f3e6SDimitry Andric }
9706122f3e6SDimitry Andric 
DecoderGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)971dff0c46cSDimitry Andric static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
9726122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
973f785676fSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
9747d523365SDimitry Andric 
9757d523365SDimitry Andric   const FeatureBitset &featureBits =
9767d523365SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
9777d523365SDimitry Andric 
9787d523365SDimitry Andric   if ((RegNo == 13 && !featureBits[ARM::HasV8Ops]) || RegNo == 15)
979f785676fSDimitry Andric     S = MCDisassembler::SoftFail;
9807d523365SDimitry Andric 
981f785676fSDimitry Andric   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
982f785676fSDimitry Andric   return S;
9836122f3e6SDimitry Andric }
9846122f3e6SDimitry Andric 
985dff0c46cSDimitry Andric static const uint16_t SPRDecoderTable[] = {
9866122f3e6SDimitry Andric      ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
9876122f3e6SDimitry Andric      ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
9886122f3e6SDimitry Andric      ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
9896122f3e6SDimitry Andric     ARM::S12, ARM::S13, ARM::S14, ARM::S15,
9906122f3e6SDimitry Andric     ARM::S16, ARM::S17, ARM::S18, ARM::S19,
9916122f3e6SDimitry Andric     ARM::S20, ARM::S21, ARM::S22, ARM::S23,
9926122f3e6SDimitry Andric     ARM::S24, ARM::S25, ARM::S26, ARM::S27,
9936122f3e6SDimitry Andric     ARM::S28, ARM::S29, ARM::S30, ARM::S31
9946122f3e6SDimitry Andric };
9956122f3e6SDimitry Andric 
DecodeSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)996dff0c46cSDimitry Andric static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
9976122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
9986122f3e6SDimitry Andric   if (RegNo > 31)
9996122f3e6SDimitry Andric     return MCDisassembler::Fail;
10006122f3e6SDimitry Andric 
10016122f3e6SDimitry Andric   unsigned Register = SPRDecoderTable[RegNo];
1002ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
10036122f3e6SDimitry Andric   return MCDisassembler::Success;
10046122f3e6SDimitry Andric }
10056122f3e6SDimitry Andric 
DecodeHPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1006*4ba319b5SDimitry Andric static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
1007*4ba319b5SDimitry Andric                                    uint64_t Address, const void *Decoder) {
1008*4ba319b5SDimitry Andric   return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
1009*4ba319b5SDimitry Andric }
1010*4ba319b5SDimitry Andric 
1011dff0c46cSDimitry Andric static const uint16_t DPRDecoderTable[] = {
10126122f3e6SDimitry Andric      ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
10136122f3e6SDimitry Andric      ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
10146122f3e6SDimitry Andric      ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
10156122f3e6SDimitry Andric     ARM::D12, ARM::D13, ARM::D14, ARM::D15,
10166122f3e6SDimitry Andric     ARM::D16, ARM::D17, ARM::D18, ARM::D19,
10176122f3e6SDimitry Andric     ARM::D20, ARM::D21, ARM::D22, ARM::D23,
10186122f3e6SDimitry Andric     ARM::D24, ARM::D25, ARM::D26, ARM::D27,
10196122f3e6SDimitry Andric     ARM::D28, ARM::D29, ARM::D30, ARM::D31
10206122f3e6SDimitry Andric };
10216122f3e6SDimitry Andric 
DecodeDPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1022dff0c46cSDimitry Andric static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
10236122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
1024ff0cc061SDimitry Andric   const FeatureBitset &featureBits =
1025ff0cc061SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
1026ff0cc061SDimitry Andric 
1027ff0cc061SDimitry Andric   bool hasD16 = featureBits[ARM::FeatureD16];
102839d628a0SDimitry Andric 
102939d628a0SDimitry Andric   if (RegNo > 31 || (hasD16 && RegNo > 15))
10306122f3e6SDimitry Andric     return MCDisassembler::Fail;
10316122f3e6SDimitry Andric 
10326122f3e6SDimitry Andric   unsigned Register = DPRDecoderTable[RegNo];
1033ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
10346122f3e6SDimitry Andric   return MCDisassembler::Success;
10356122f3e6SDimitry Andric }
10366122f3e6SDimitry Andric 
DecodeDPR_8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1037dff0c46cSDimitry Andric static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
10386122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
10396122f3e6SDimitry Andric   if (RegNo > 7)
10406122f3e6SDimitry Andric     return MCDisassembler::Fail;
10416122f3e6SDimitry Andric   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
10426122f3e6SDimitry Andric }
10436122f3e6SDimitry Andric 
10446122f3e6SDimitry Andric static DecodeStatus
DecodeDPR_VFP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1045dff0c46cSDimitry Andric DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
10466122f3e6SDimitry Andric                             uint64_t Address, const void *Decoder) {
10476122f3e6SDimitry Andric   if (RegNo > 15)
10486122f3e6SDimitry Andric     return MCDisassembler::Fail;
10496122f3e6SDimitry Andric   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
10506122f3e6SDimitry Andric }
10516122f3e6SDimitry Andric 
1052dff0c46cSDimitry Andric static const uint16_t QPRDecoderTable[] = {
10536122f3e6SDimitry Andric      ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
10546122f3e6SDimitry Andric      ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
10556122f3e6SDimitry Andric      ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
10566122f3e6SDimitry Andric     ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
10576122f3e6SDimitry Andric };
10586122f3e6SDimitry Andric 
DecodeQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1059dff0c46cSDimitry Andric static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
10606122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
1061f785676fSDimitry Andric   if (RegNo > 31 || (RegNo & 1) != 0)
10626122f3e6SDimitry Andric     return MCDisassembler::Fail;
10636122f3e6SDimitry Andric   RegNo >>= 1;
10646122f3e6SDimitry Andric 
10656122f3e6SDimitry Andric   unsigned Register = QPRDecoderTable[RegNo];
1066ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
10676122f3e6SDimitry Andric   return MCDisassembler::Success;
10686122f3e6SDimitry Andric }
10696122f3e6SDimitry Andric 
1070dff0c46cSDimitry Andric static const uint16_t DPairDecoderTable[] = {
1071dff0c46cSDimitry Andric   ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
1072dff0c46cSDimitry Andric   ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
1073dff0c46cSDimitry Andric   ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
1074dff0c46cSDimitry Andric   ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
1075dff0c46cSDimitry Andric   ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
1076dff0c46cSDimitry Andric   ARM::Q15
1077dff0c46cSDimitry Andric };
1078dff0c46cSDimitry Andric 
DecodeDPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1079dff0c46cSDimitry Andric static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
1080dff0c46cSDimitry Andric                                    uint64_t Address, const void *Decoder) {
1081dff0c46cSDimitry Andric   if (RegNo > 30)
1082dff0c46cSDimitry Andric     return MCDisassembler::Fail;
1083dff0c46cSDimitry Andric 
1084dff0c46cSDimitry Andric   unsigned Register = DPairDecoderTable[RegNo];
1085ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
1086dff0c46cSDimitry Andric   return MCDisassembler::Success;
1087dff0c46cSDimitry Andric }
1088dff0c46cSDimitry Andric 
1089dff0c46cSDimitry Andric static const uint16_t DPairSpacedDecoderTable[] = {
1090dff0c46cSDimitry Andric   ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
1091dff0c46cSDimitry Andric   ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
1092dff0c46cSDimitry Andric   ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
1093dff0c46cSDimitry Andric   ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
1094dff0c46cSDimitry Andric   ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
1095dff0c46cSDimitry Andric   ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
1096dff0c46cSDimitry Andric   ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
1097dff0c46cSDimitry Andric   ARM::D28_D30, ARM::D29_D31
1098dff0c46cSDimitry Andric };
1099dff0c46cSDimitry Andric 
DecodeDPairSpacedRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1100dff0c46cSDimitry Andric static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
1101dff0c46cSDimitry Andric                                                    unsigned RegNo,
1102dff0c46cSDimitry Andric                                                    uint64_t Address,
1103dff0c46cSDimitry Andric                                                    const void *Decoder) {
1104dff0c46cSDimitry Andric   if (RegNo > 29)
1105dff0c46cSDimitry Andric     return MCDisassembler::Fail;
1106dff0c46cSDimitry Andric 
1107dff0c46cSDimitry Andric   unsigned Register = DPairSpacedDecoderTable[RegNo];
1108ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
1109dff0c46cSDimitry Andric   return MCDisassembler::Success;
1110dff0c46cSDimitry Andric }
1111dff0c46cSDimitry Andric 
DecodePredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1112dff0c46cSDimitry Andric static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
11136122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder) {
11146122f3e6SDimitry Andric   if (Val == 0xF) return MCDisassembler::Fail;
11156122f3e6SDimitry Andric   // AL predicate is not allowed on Thumb1 branches.
11166122f3e6SDimitry Andric   if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
11176122f3e6SDimitry Andric     return MCDisassembler::Fail;
1118ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
11196122f3e6SDimitry Andric   if (Val == ARMCC::AL) {
1120ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
11216122f3e6SDimitry Andric   } else
1122ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::CPSR));
11236122f3e6SDimitry Andric   return MCDisassembler::Success;
11246122f3e6SDimitry Andric }
11256122f3e6SDimitry Andric 
DecodeCCOutOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1126dff0c46cSDimitry Andric static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
11276122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder) {
11286122f3e6SDimitry Andric   if (Val)
1129ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::CPSR));
11306122f3e6SDimitry Andric   else
1131ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
11326122f3e6SDimitry Andric   return MCDisassembler::Success;
11336122f3e6SDimitry Andric }
11346122f3e6SDimitry Andric 
DecodeSORegImmOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1135dff0c46cSDimitry Andric static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
11366122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder) {
11376122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
11386122f3e6SDimitry Andric 
11397ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
11407ae0e2c9SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
11417ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 7, 5);
11426122f3e6SDimitry Andric 
11436122f3e6SDimitry Andric   // Register-immediate
11447d523365SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
11456122f3e6SDimitry Andric     return MCDisassembler::Fail;
11466122f3e6SDimitry Andric 
11476122f3e6SDimitry Andric   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
11486122f3e6SDimitry Andric   switch (type) {
11496122f3e6SDimitry Andric     case 0:
11506122f3e6SDimitry Andric       Shift = ARM_AM::lsl;
11516122f3e6SDimitry Andric       break;
11526122f3e6SDimitry Andric     case 1:
11536122f3e6SDimitry Andric       Shift = ARM_AM::lsr;
11546122f3e6SDimitry Andric       break;
11556122f3e6SDimitry Andric     case 2:
11566122f3e6SDimitry Andric       Shift = ARM_AM::asr;
11576122f3e6SDimitry Andric       break;
11586122f3e6SDimitry Andric     case 3:
11596122f3e6SDimitry Andric       Shift = ARM_AM::ror;
11606122f3e6SDimitry Andric       break;
11616122f3e6SDimitry Andric   }
11626122f3e6SDimitry Andric 
11636122f3e6SDimitry Andric   if (Shift == ARM_AM::ror && imm == 0)
11646122f3e6SDimitry Andric     Shift = ARM_AM::rrx;
11656122f3e6SDimitry Andric 
11666122f3e6SDimitry Andric   unsigned Op = Shift | (imm << 3);
1167ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Op));
11686122f3e6SDimitry Andric 
11696122f3e6SDimitry Andric   return S;
11706122f3e6SDimitry Andric }
11716122f3e6SDimitry Andric 
DecodeSORegRegOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1172dff0c46cSDimitry Andric static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
11736122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder) {
11746122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
11756122f3e6SDimitry Andric 
11767ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
11777ae0e2c9SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
11787ae0e2c9SDimitry Andric   unsigned Rs = fieldFromInstruction(Val, 8, 4);
11796122f3e6SDimitry Andric 
11806122f3e6SDimitry Andric   // Register-register
11816122f3e6SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
11826122f3e6SDimitry Andric     return MCDisassembler::Fail;
11836122f3e6SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
11846122f3e6SDimitry Andric     return MCDisassembler::Fail;
11856122f3e6SDimitry Andric 
11866122f3e6SDimitry Andric   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
11876122f3e6SDimitry Andric   switch (type) {
11886122f3e6SDimitry Andric     case 0:
11896122f3e6SDimitry Andric       Shift = ARM_AM::lsl;
11906122f3e6SDimitry Andric       break;
11916122f3e6SDimitry Andric     case 1:
11926122f3e6SDimitry Andric       Shift = ARM_AM::lsr;
11936122f3e6SDimitry Andric       break;
11946122f3e6SDimitry Andric     case 2:
11956122f3e6SDimitry Andric       Shift = ARM_AM::asr;
11966122f3e6SDimitry Andric       break;
11976122f3e6SDimitry Andric     case 3:
11986122f3e6SDimitry Andric       Shift = ARM_AM::ror;
11996122f3e6SDimitry Andric       break;
12006122f3e6SDimitry Andric   }
12016122f3e6SDimitry Andric 
1202ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Shift));
12036122f3e6SDimitry Andric 
12046122f3e6SDimitry Andric   return S;
12056122f3e6SDimitry Andric }
12066122f3e6SDimitry Andric 
DecodeRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1207dff0c46cSDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
12086122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
12096122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
12106122f3e6SDimitry Andric 
1211f785676fSDimitry Andric   bool NeedDisjointWriteback = false;
1212f785676fSDimitry Andric   unsigned WritebackReg = 0;
12136122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
12146122f3e6SDimitry Andric   default:
12156122f3e6SDimitry Andric     break;
12166122f3e6SDimitry Andric   case ARM::LDMIA_UPD:
12176122f3e6SDimitry Andric   case ARM::LDMDB_UPD:
12186122f3e6SDimitry Andric   case ARM::LDMIB_UPD:
12196122f3e6SDimitry Andric   case ARM::LDMDA_UPD:
12206122f3e6SDimitry Andric   case ARM::t2LDMIA_UPD:
12216122f3e6SDimitry Andric   case ARM::t2LDMDB_UPD:
1222f785676fSDimitry Andric   case ARM::t2STMIA_UPD:
1223f785676fSDimitry Andric   case ARM::t2STMDB_UPD:
1224f785676fSDimitry Andric     NeedDisjointWriteback = true;
1225f785676fSDimitry Andric     WritebackReg = Inst.getOperand(0).getReg();
12266122f3e6SDimitry Andric     break;
12276122f3e6SDimitry Andric   }
12286122f3e6SDimitry Andric 
12296122f3e6SDimitry Andric   // Empty register lists are not allowed.
1230f785676fSDimitry Andric   if (Val == 0) return MCDisassembler::Fail;
12316122f3e6SDimitry Andric   for (unsigned i = 0; i < 16; ++i) {
12326122f3e6SDimitry Andric     if (Val & (1 << i)) {
12336122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
12346122f3e6SDimitry Andric         return MCDisassembler::Fail;
12356122f3e6SDimitry Andric       // Writeback not allowed if Rn is in the target list.
1236f785676fSDimitry Andric       if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg())
12376122f3e6SDimitry Andric         Check(S, MCDisassembler::SoftFail);
12386122f3e6SDimitry Andric     }
12396122f3e6SDimitry Andric   }
12406122f3e6SDimitry Andric 
12416122f3e6SDimitry Andric   return S;
12426122f3e6SDimitry Andric }
12436122f3e6SDimitry Andric 
DecodeSPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1244dff0c46cSDimitry Andric static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
12456122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
12466122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
12476122f3e6SDimitry Andric 
12487ae0e2c9SDimitry Andric   unsigned Vd = fieldFromInstruction(Val, 8, 5);
12497ae0e2c9SDimitry Andric   unsigned regs = fieldFromInstruction(Val, 0, 8);
12506122f3e6SDimitry Andric 
1251f785676fSDimitry Andric   // In case of unpredictable encoding, tweak the operands.
1252f785676fSDimitry Andric   if (regs == 0 || (Vd + regs) > 32) {
1253f785676fSDimitry Andric     regs = Vd + regs > 32 ? 32 - Vd : regs;
1254f785676fSDimitry Andric     regs = std::max( 1u, regs);
1255f785676fSDimitry Andric     S = MCDisassembler::SoftFail;
1256f785676fSDimitry Andric   }
1257f785676fSDimitry Andric 
12586122f3e6SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
12596122f3e6SDimitry Andric     return MCDisassembler::Fail;
12606122f3e6SDimitry Andric   for (unsigned i = 0; i < (regs - 1); ++i) {
12616122f3e6SDimitry Andric     if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
12626122f3e6SDimitry Andric       return MCDisassembler::Fail;
12636122f3e6SDimitry Andric   }
12646122f3e6SDimitry Andric 
12656122f3e6SDimitry Andric   return S;
12666122f3e6SDimitry Andric }
12676122f3e6SDimitry Andric 
DecodeDPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1268dff0c46cSDimitry Andric static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
12696122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
12706122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
12716122f3e6SDimitry Andric 
12727ae0e2c9SDimitry Andric   unsigned Vd = fieldFromInstruction(Val, 8, 5);
1273f785676fSDimitry Andric   unsigned regs = fieldFromInstruction(Val, 1, 7);
12747ae0e2c9SDimitry Andric 
1275f785676fSDimitry Andric   // In case of unpredictable encoding, tweak the operands.
1276f785676fSDimitry Andric   if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
1277f785676fSDimitry Andric     regs = Vd + regs > 32 ? 32 - Vd : regs;
1278f785676fSDimitry Andric     regs = std::max( 1u, regs);
1279f785676fSDimitry Andric     regs = std::min(16u, regs);
1280f785676fSDimitry Andric     S = MCDisassembler::SoftFail;
1281f785676fSDimitry Andric   }
12826122f3e6SDimitry Andric 
12836122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
12846122f3e6SDimitry Andric       return MCDisassembler::Fail;
12856122f3e6SDimitry Andric   for (unsigned i = 0; i < (regs - 1); ++i) {
12866122f3e6SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
12876122f3e6SDimitry Andric       return MCDisassembler::Fail;
12886122f3e6SDimitry Andric   }
12896122f3e6SDimitry Andric 
12906122f3e6SDimitry Andric   return S;
12916122f3e6SDimitry Andric }
12926122f3e6SDimitry Andric 
DecodeBitfieldMaskOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1293dff0c46cSDimitry Andric static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
12946122f3e6SDimitry Andric                                       uint64_t Address, const void *Decoder) {
12956122f3e6SDimitry Andric   // This operand encodes a mask of contiguous zeros between a specified MSB
12966122f3e6SDimitry Andric   // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
12976122f3e6SDimitry Andric   // the mask of all bits LSB-and-lower, and then xor them to create
12986122f3e6SDimitry Andric   // the mask of that's all ones on [msb, lsb].  Finally we not it to
12996122f3e6SDimitry Andric   // create the final mask.
13007ae0e2c9SDimitry Andric   unsigned msb = fieldFromInstruction(Val, 5, 5);
13017ae0e2c9SDimitry Andric   unsigned lsb = fieldFromInstruction(Val, 0, 5);
13026122f3e6SDimitry Andric 
13036122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
1304139f7f9bSDimitry Andric   if (lsb > msb) {
1305139f7f9bSDimitry Andric     Check(S, MCDisassembler::SoftFail);
1306139f7f9bSDimitry Andric     // The check above will cause the warning for the "potentially undefined
1307139f7f9bSDimitry Andric     // instruction encoding" but we can't build a bad MCOperand value here
1308139f7f9bSDimitry Andric     // with a lsb > msb or else printing the MCInst will cause a crash.
1309139f7f9bSDimitry Andric     lsb = msb;
1310139f7f9bSDimitry Andric   }
13116122f3e6SDimitry Andric 
13126122f3e6SDimitry Andric   uint32_t msb_mask = 0xFFFFFFFF;
13136122f3e6SDimitry Andric   if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
13146122f3e6SDimitry Andric   uint32_t lsb_mask = (1U << lsb) - 1;
13156122f3e6SDimitry Andric 
1316ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(~(msb_mask ^ lsb_mask)));
13176122f3e6SDimitry Andric   return S;
13186122f3e6SDimitry Andric }
13196122f3e6SDimitry Andric 
DecodeCopMemInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1320dff0c46cSDimitry Andric static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
13216122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
13226122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
13236122f3e6SDimitry Andric 
13247ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
13257ae0e2c9SDimitry Andric   unsigned CRd = fieldFromInstruction(Insn, 12, 4);
13267ae0e2c9SDimitry Andric   unsigned coproc = fieldFromInstruction(Insn, 8, 4);
13277ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
13287ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
13297ae0e2c9SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
13306122f3e6SDimitry Andric 
13316122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
13326122f3e6SDimitry Andric     case ARM::LDC_OFFSET:
13336122f3e6SDimitry Andric     case ARM::LDC_PRE:
13346122f3e6SDimitry Andric     case ARM::LDC_POST:
13356122f3e6SDimitry Andric     case ARM::LDC_OPTION:
13366122f3e6SDimitry Andric     case ARM::LDCL_OFFSET:
13376122f3e6SDimitry Andric     case ARM::LDCL_PRE:
13386122f3e6SDimitry Andric     case ARM::LDCL_POST:
13396122f3e6SDimitry Andric     case ARM::LDCL_OPTION:
13406122f3e6SDimitry Andric     case ARM::STC_OFFSET:
13416122f3e6SDimitry Andric     case ARM::STC_PRE:
13426122f3e6SDimitry Andric     case ARM::STC_POST:
13436122f3e6SDimitry Andric     case ARM::STC_OPTION:
13446122f3e6SDimitry Andric     case ARM::STCL_OFFSET:
13456122f3e6SDimitry Andric     case ARM::STCL_PRE:
13466122f3e6SDimitry Andric     case ARM::STCL_POST:
13476122f3e6SDimitry Andric     case ARM::STCL_OPTION:
13486122f3e6SDimitry Andric     case ARM::t2LDC_OFFSET:
13496122f3e6SDimitry Andric     case ARM::t2LDC_PRE:
13506122f3e6SDimitry Andric     case ARM::t2LDC_POST:
13516122f3e6SDimitry Andric     case ARM::t2LDC_OPTION:
13526122f3e6SDimitry Andric     case ARM::t2LDCL_OFFSET:
13536122f3e6SDimitry Andric     case ARM::t2LDCL_PRE:
13546122f3e6SDimitry Andric     case ARM::t2LDCL_POST:
13556122f3e6SDimitry Andric     case ARM::t2LDCL_OPTION:
13566122f3e6SDimitry Andric     case ARM::t2STC_OFFSET:
13576122f3e6SDimitry Andric     case ARM::t2STC_PRE:
13586122f3e6SDimitry Andric     case ARM::t2STC_POST:
13596122f3e6SDimitry Andric     case ARM::t2STC_OPTION:
13606122f3e6SDimitry Andric     case ARM::t2STCL_OFFSET:
13616122f3e6SDimitry Andric     case ARM::t2STCL_PRE:
13626122f3e6SDimitry Andric     case ARM::t2STCL_POST:
13636122f3e6SDimitry Andric     case ARM::t2STCL_OPTION:
13646122f3e6SDimitry Andric       if (coproc == 0xA || coproc == 0xB)
13656122f3e6SDimitry Andric         return MCDisassembler::Fail;
13666122f3e6SDimitry Andric       break;
13676122f3e6SDimitry Andric     default:
13686122f3e6SDimitry Andric       break;
13696122f3e6SDimitry Andric   }
13706122f3e6SDimitry Andric 
1371ff0cc061SDimitry Andric   const FeatureBitset &featureBits =
1372ff0cc061SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
1373ff0cc061SDimitry Andric   if (featureBits[ARM::HasV8Ops] && (coproc != 14))
1374f785676fSDimitry Andric     return MCDisassembler::Fail;
1375f785676fSDimitry Andric 
1376ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(coproc));
1377ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(CRd));
13786122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
13796122f3e6SDimitry Andric     return MCDisassembler::Fail;
13806122f3e6SDimitry Andric 
13816122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
13826122f3e6SDimitry Andric     case ARM::t2LDC2_OFFSET:
13836122f3e6SDimitry Andric     case ARM::t2LDC2L_OFFSET:
13846122f3e6SDimitry Andric     case ARM::t2LDC2_PRE:
13856122f3e6SDimitry Andric     case ARM::t2LDC2L_PRE:
13866122f3e6SDimitry Andric     case ARM::t2STC2_OFFSET:
13876122f3e6SDimitry Andric     case ARM::t2STC2L_OFFSET:
13886122f3e6SDimitry Andric     case ARM::t2STC2_PRE:
13896122f3e6SDimitry Andric     case ARM::t2STC2L_PRE:
13906122f3e6SDimitry Andric     case ARM::LDC2_OFFSET:
13916122f3e6SDimitry Andric     case ARM::LDC2L_OFFSET:
13926122f3e6SDimitry Andric     case ARM::LDC2_PRE:
13936122f3e6SDimitry Andric     case ARM::LDC2L_PRE:
13946122f3e6SDimitry Andric     case ARM::STC2_OFFSET:
13956122f3e6SDimitry Andric     case ARM::STC2L_OFFSET:
13966122f3e6SDimitry Andric     case ARM::STC2_PRE:
13976122f3e6SDimitry Andric     case ARM::STC2L_PRE:
13986122f3e6SDimitry Andric     case ARM::t2LDC_OFFSET:
13996122f3e6SDimitry Andric     case ARM::t2LDCL_OFFSET:
14006122f3e6SDimitry Andric     case ARM::t2LDC_PRE:
14016122f3e6SDimitry Andric     case ARM::t2LDCL_PRE:
14026122f3e6SDimitry Andric     case ARM::t2STC_OFFSET:
14036122f3e6SDimitry Andric     case ARM::t2STCL_OFFSET:
14046122f3e6SDimitry Andric     case ARM::t2STC_PRE:
14056122f3e6SDimitry Andric     case ARM::t2STCL_PRE:
14066122f3e6SDimitry Andric     case ARM::LDC_OFFSET:
14076122f3e6SDimitry Andric     case ARM::LDCL_OFFSET:
14086122f3e6SDimitry Andric     case ARM::LDC_PRE:
14096122f3e6SDimitry Andric     case ARM::LDCL_PRE:
14106122f3e6SDimitry Andric     case ARM::STC_OFFSET:
14116122f3e6SDimitry Andric     case ARM::STCL_OFFSET:
14126122f3e6SDimitry Andric     case ARM::STC_PRE:
14136122f3e6SDimitry Andric     case ARM::STCL_PRE:
14146122f3e6SDimitry Andric       imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
1415ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createImm(imm));
14166122f3e6SDimitry Andric       break;
14176122f3e6SDimitry Andric     case ARM::t2LDC2_POST:
14186122f3e6SDimitry Andric     case ARM::t2LDC2L_POST:
14196122f3e6SDimitry Andric     case ARM::t2STC2_POST:
14206122f3e6SDimitry Andric     case ARM::t2STC2L_POST:
14216122f3e6SDimitry Andric     case ARM::LDC2_POST:
14226122f3e6SDimitry Andric     case ARM::LDC2L_POST:
14236122f3e6SDimitry Andric     case ARM::STC2_POST:
14246122f3e6SDimitry Andric     case ARM::STC2L_POST:
14256122f3e6SDimitry Andric     case ARM::t2LDC_POST:
14266122f3e6SDimitry Andric     case ARM::t2LDCL_POST:
14276122f3e6SDimitry Andric     case ARM::t2STC_POST:
14286122f3e6SDimitry Andric     case ARM::t2STCL_POST:
14296122f3e6SDimitry Andric     case ARM::LDC_POST:
14306122f3e6SDimitry Andric     case ARM::LDCL_POST:
14316122f3e6SDimitry Andric     case ARM::STC_POST:
14326122f3e6SDimitry Andric     case ARM::STCL_POST:
14336122f3e6SDimitry Andric       imm |= U << 8;
1434d88c1a5aSDimitry Andric       LLVM_FALLTHROUGH;
14356122f3e6SDimitry Andric     default:
14366122f3e6SDimitry Andric       // The 'option' variant doesn't encode 'U' in the immediate since
14376122f3e6SDimitry Andric       // the immediate is unsigned [0,255].
1438ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createImm(imm));
14396122f3e6SDimitry Andric       break;
14406122f3e6SDimitry Andric   }
14416122f3e6SDimitry Andric 
14426122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
14436122f3e6SDimitry Andric     case ARM::LDC_OFFSET:
14446122f3e6SDimitry Andric     case ARM::LDC_PRE:
14456122f3e6SDimitry Andric     case ARM::LDC_POST:
14466122f3e6SDimitry Andric     case ARM::LDC_OPTION:
14476122f3e6SDimitry Andric     case ARM::LDCL_OFFSET:
14486122f3e6SDimitry Andric     case ARM::LDCL_PRE:
14496122f3e6SDimitry Andric     case ARM::LDCL_POST:
14506122f3e6SDimitry Andric     case ARM::LDCL_OPTION:
14516122f3e6SDimitry Andric     case ARM::STC_OFFSET:
14526122f3e6SDimitry Andric     case ARM::STC_PRE:
14536122f3e6SDimitry Andric     case ARM::STC_POST:
14546122f3e6SDimitry Andric     case ARM::STC_OPTION:
14556122f3e6SDimitry Andric     case ARM::STCL_OFFSET:
14566122f3e6SDimitry Andric     case ARM::STCL_PRE:
14576122f3e6SDimitry Andric     case ARM::STCL_POST:
14586122f3e6SDimitry Andric     case ARM::STCL_OPTION:
14596122f3e6SDimitry Andric       if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
14606122f3e6SDimitry Andric         return MCDisassembler::Fail;
14616122f3e6SDimitry Andric       break;
14626122f3e6SDimitry Andric     default:
14636122f3e6SDimitry Andric       break;
14646122f3e6SDimitry Andric   }
14656122f3e6SDimitry Andric 
14666122f3e6SDimitry Andric   return S;
14676122f3e6SDimitry Andric }
14686122f3e6SDimitry Andric 
14696122f3e6SDimitry Andric static DecodeStatus
DecodeAddrMode2IdxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1470dff0c46cSDimitry Andric DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn,
14716122f3e6SDimitry Andric                               uint64_t Address, const void *Decoder) {
14726122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
14736122f3e6SDimitry Andric 
14747ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
14757ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
14767ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
14777ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
14787ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
14797ae0e2c9SDimitry Andric   unsigned reg = fieldFromInstruction(Insn, 25, 1);
14807ae0e2c9SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
14817ae0e2c9SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
14826122f3e6SDimitry Andric 
14836122f3e6SDimitry Andric   // On stores, the writeback operand precedes Rt.
14846122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
14856122f3e6SDimitry Andric     case ARM::STR_POST_IMM:
14866122f3e6SDimitry Andric     case ARM::STR_POST_REG:
14876122f3e6SDimitry Andric     case ARM::STRB_POST_IMM:
14886122f3e6SDimitry Andric     case ARM::STRB_POST_REG:
14896122f3e6SDimitry Andric     case ARM::STRT_POST_REG:
14906122f3e6SDimitry Andric     case ARM::STRT_POST_IMM:
14916122f3e6SDimitry Andric     case ARM::STRBT_POST_REG:
14926122f3e6SDimitry Andric     case ARM::STRBT_POST_IMM:
14936122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
14946122f3e6SDimitry Andric         return MCDisassembler::Fail;
14956122f3e6SDimitry Andric       break;
14966122f3e6SDimitry Andric     default:
14976122f3e6SDimitry Andric       break;
14986122f3e6SDimitry Andric   }
14996122f3e6SDimitry Andric 
15006122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
15016122f3e6SDimitry Andric     return MCDisassembler::Fail;
15026122f3e6SDimitry Andric 
15036122f3e6SDimitry Andric   // On loads, the writeback operand comes after Rt.
15046122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
15056122f3e6SDimitry Andric     case ARM::LDR_POST_IMM:
15066122f3e6SDimitry Andric     case ARM::LDR_POST_REG:
15076122f3e6SDimitry Andric     case ARM::LDRB_POST_IMM:
15086122f3e6SDimitry Andric     case ARM::LDRB_POST_REG:
15096122f3e6SDimitry Andric     case ARM::LDRBT_POST_REG:
15106122f3e6SDimitry Andric     case ARM::LDRBT_POST_IMM:
15116122f3e6SDimitry Andric     case ARM::LDRT_POST_REG:
15126122f3e6SDimitry Andric     case ARM::LDRT_POST_IMM:
15136122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
15146122f3e6SDimitry Andric         return MCDisassembler::Fail;
15156122f3e6SDimitry Andric       break;
15166122f3e6SDimitry Andric     default:
15176122f3e6SDimitry Andric       break;
15186122f3e6SDimitry Andric   }
15196122f3e6SDimitry Andric 
15206122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
15216122f3e6SDimitry Andric     return MCDisassembler::Fail;
15226122f3e6SDimitry Andric 
15236122f3e6SDimitry Andric   ARM_AM::AddrOpc Op = ARM_AM::add;
15247ae0e2c9SDimitry Andric   if (!fieldFromInstruction(Insn, 23, 1))
15256122f3e6SDimitry Andric     Op = ARM_AM::sub;
15266122f3e6SDimitry Andric 
15276122f3e6SDimitry Andric   bool writeback = (P == 0) || (W == 1);
15286122f3e6SDimitry Andric   unsigned idx_mode = 0;
15296122f3e6SDimitry Andric   if (P && writeback)
15306122f3e6SDimitry Andric     idx_mode = ARMII::IndexModePre;
15316122f3e6SDimitry Andric   else if (!P && writeback)
15326122f3e6SDimitry Andric     idx_mode = ARMII::IndexModePost;
15336122f3e6SDimitry Andric 
15346122f3e6SDimitry Andric   if (writeback && (Rn == 15 || Rn == Rt))
15356122f3e6SDimitry Andric     S = MCDisassembler::SoftFail; // UNPREDICTABLE
15366122f3e6SDimitry Andric 
15376122f3e6SDimitry Andric   if (reg) {
15386122f3e6SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
15396122f3e6SDimitry Andric       return MCDisassembler::Fail;
15406122f3e6SDimitry Andric     ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
15417ae0e2c9SDimitry Andric     switch( fieldFromInstruction(Insn, 5, 2)) {
15426122f3e6SDimitry Andric       case 0:
15436122f3e6SDimitry Andric         Opc = ARM_AM::lsl;
15446122f3e6SDimitry Andric         break;
15456122f3e6SDimitry Andric       case 1:
15466122f3e6SDimitry Andric         Opc = ARM_AM::lsr;
15476122f3e6SDimitry Andric         break;
15486122f3e6SDimitry Andric       case 2:
15496122f3e6SDimitry Andric         Opc = ARM_AM::asr;
15506122f3e6SDimitry Andric         break;
15516122f3e6SDimitry Andric       case 3:
15526122f3e6SDimitry Andric         Opc = ARM_AM::ror;
15536122f3e6SDimitry Andric         break;
15546122f3e6SDimitry Andric       default:
15556122f3e6SDimitry Andric         return MCDisassembler::Fail;
15566122f3e6SDimitry Andric     }
15577ae0e2c9SDimitry Andric     unsigned amt = fieldFromInstruction(Insn, 7, 5);
15583861d79fSDimitry Andric     if (Opc == ARM_AM::ror && amt == 0)
15593861d79fSDimitry Andric       Opc = ARM_AM::rrx;
15606122f3e6SDimitry Andric     unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
15616122f3e6SDimitry Andric 
1562ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
15636122f3e6SDimitry Andric   } else {
1564ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
15656122f3e6SDimitry Andric     unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
1566ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(tmp));
15676122f3e6SDimitry Andric   }
15686122f3e6SDimitry Andric 
15696122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
15706122f3e6SDimitry Andric     return MCDisassembler::Fail;
15716122f3e6SDimitry Andric 
15726122f3e6SDimitry Andric   return S;
15736122f3e6SDimitry Andric }
15746122f3e6SDimitry Andric 
DecodeSORegMemOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1575dff0c46cSDimitry Andric static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
15766122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
15776122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
15786122f3e6SDimitry Andric 
15797ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
15807ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Val,  0, 4);
15817ae0e2c9SDimitry Andric   unsigned type = fieldFromInstruction(Val, 5, 2);
15827ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 7, 5);
15837ae0e2c9SDimitry Andric   unsigned U = fieldFromInstruction(Val, 12, 1);
15846122f3e6SDimitry Andric 
15856122f3e6SDimitry Andric   ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
15866122f3e6SDimitry Andric   switch (type) {
15876122f3e6SDimitry Andric     case 0:
15886122f3e6SDimitry Andric       ShOp = ARM_AM::lsl;
15896122f3e6SDimitry Andric       break;
15906122f3e6SDimitry Andric     case 1:
15916122f3e6SDimitry Andric       ShOp = ARM_AM::lsr;
15926122f3e6SDimitry Andric       break;
15936122f3e6SDimitry Andric     case 2:
15946122f3e6SDimitry Andric       ShOp = ARM_AM::asr;
15956122f3e6SDimitry Andric       break;
15966122f3e6SDimitry Andric     case 3:
15976122f3e6SDimitry Andric       ShOp = ARM_AM::ror;
15986122f3e6SDimitry Andric       break;
15996122f3e6SDimitry Andric   }
16006122f3e6SDimitry Andric 
16013861d79fSDimitry Andric   if (ShOp == ARM_AM::ror && imm == 0)
16023861d79fSDimitry Andric     ShOp = ARM_AM::rrx;
16033861d79fSDimitry Andric 
16046122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
16056122f3e6SDimitry Andric     return MCDisassembler::Fail;
16066122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
16076122f3e6SDimitry Andric     return MCDisassembler::Fail;
16086122f3e6SDimitry Andric   unsigned shift;
16096122f3e6SDimitry Andric   if (U)
16106122f3e6SDimitry Andric     shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
16116122f3e6SDimitry Andric   else
16126122f3e6SDimitry Andric     shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
1613ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(shift));
16146122f3e6SDimitry Andric 
16156122f3e6SDimitry Andric   return S;
16166122f3e6SDimitry Andric }
16176122f3e6SDimitry Andric 
16186122f3e6SDimitry Andric static DecodeStatus
DecodeAddrMode3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1619dff0c46cSDimitry Andric DecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
16206122f3e6SDimitry Andric                            uint64_t Address, const void *Decoder) {
16216122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
16226122f3e6SDimitry Andric 
16237ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
16247ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
16257ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
16267ae0e2c9SDimitry Andric   unsigned type = fieldFromInstruction(Insn, 22, 1);
16277ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 8, 4);
16287ae0e2c9SDimitry Andric   unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
16297ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
16307ae0e2c9SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
16317ae0e2c9SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
1632dff0c46cSDimitry Andric   unsigned Rt2 = Rt + 1;
16336122f3e6SDimitry Andric 
16346122f3e6SDimitry Andric   bool writeback = (W == 1) | (P == 0);
16356122f3e6SDimitry Andric 
16366122f3e6SDimitry Andric   // For {LD,ST}RD, Rt must be even, else undefined.
16376122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
16386122f3e6SDimitry Andric     case ARM::STRD:
16396122f3e6SDimitry Andric     case ARM::STRD_PRE:
16406122f3e6SDimitry Andric     case ARM::STRD_POST:
16416122f3e6SDimitry Andric     case ARM::LDRD:
16426122f3e6SDimitry Andric     case ARM::LDRD_PRE:
16436122f3e6SDimitry Andric     case ARM::LDRD_POST:
1644dff0c46cSDimitry Andric       if (Rt & 0x1) S = MCDisassembler::SoftFail;
1645dff0c46cSDimitry Andric       break;
1646dff0c46cSDimitry Andric     default:
1647dff0c46cSDimitry Andric       break;
1648dff0c46cSDimitry Andric   }
1649dff0c46cSDimitry Andric   switch (Inst.getOpcode()) {
1650dff0c46cSDimitry Andric     case ARM::STRD:
1651dff0c46cSDimitry Andric     case ARM::STRD_PRE:
1652dff0c46cSDimitry Andric     case ARM::STRD_POST:
1653dff0c46cSDimitry Andric       if (P == 0 && W == 1)
1654dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1655dff0c46cSDimitry Andric 
1656dff0c46cSDimitry Andric       if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
1657dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1658dff0c46cSDimitry Andric       if (type && Rm == 15)
1659dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1660dff0c46cSDimitry Andric       if (Rt2 == 15)
1661dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
16627ae0e2c9SDimitry Andric       if (!type && fieldFromInstruction(Insn, 8, 4))
1663dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1664dff0c46cSDimitry Andric       break;
1665dff0c46cSDimitry Andric     case ARM::STRH:
1666dff0c46cSDimitry Andric     case ARM::STRH_PRE:
1667dff0c46cSDimitry Andric     case ARM::STRH_POST:
1668dff0c46cSDimitry Andric       if (Rt == 15)
1669dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1670dff0c46cSDimitry Andric       if (writeback && (Rn == 15 || Rn == Rt))
1671dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1672dff0c46cSDimitry Andric       if (!type && Rm == 15)
1673dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1674dff0c46cSDimitry Andric       break;
1675dff0c46cSDimitry Andric     case ARM::LDRD:
1676dff0c46cSDimitry Andric     case ARM::LDRD_PRE:
1677dff0c46cSDimitry Andric     case ARM::LDRD_POST:
1678dff0c46cSDimitry Andric       if (type && Rn == 15) {
1679dff0c46cSDimitry Andric         if (Rt2 == 15)
1680dff0c46cSDimitry Andric           S = MCDisassembler::SoftFail;
1681dff0c46cSDimitry Andric         break;
1682dff0c46cSDimitry Andric       }
1683dff0c46cSDimitry Andric       if (P == 0 && W == 1)
1684dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1685dff0c46cSDimitry Andric       if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
1686dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1687dff0c46cSDimitry Andric       if (!type && writeback && Rn == 15)
1688dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1689dff0c46cSDimitry Andric       if (writeback && (Rn == Rt || Rn == Rt2))
1690dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1691dff0c46cSDimitry Andric       break;
1692dff0c46cSDimitry Andric     case ARM::LDRH:
1693dff0c46cSDimitry Andric     case ARM::LDRH_PRE:
1694dff0c46cSDimitry Andric     case ARM::LDRH_POST:
1695dff0c46cSDimitry Andric       if (type && Rn == 15) {
1696dff0c46cSDimitry Andric         if (Rt == 15)
1697dff0c46cSDimitry Andric           S = MCDisassembler::SoftFail;
1698dff0c46cSDimitry Andric         break;
1699dff0c46cSDimitry Andric       }
1700dff0c46cSDimitry Andric       if (Rt == 15)
1701dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1702dff0c46cSDimitry Andric       if (!type && Rm == 15)
1703dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1704dff0c46cSDimitry Andric       if (!type && writeback && (Rn == 15 || Rn == Rt))
1705dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1706dff0c46cSDimitry Andric       break;
1707dff0c46cSDimitry Andric     case ARM::LDRSH:
1708dff0c46cSDimitry Andric     case ARM::LDRSH_PRE:
1709dff0c46cSDimitry Andric     case ARM::LDRSH_POST:
1710dff0c46cSDimitry Andric     case ARM::LDRSB:
1711dff0c46cSDimitry Andric     case ARM::LDRSB_PRE:
1712dff0c46cSDimitry Andric     case ARM::LDRSB_POST:
1713dff0c46cSDimitry Andric       if (type && Rn == 15) {
1714dff0c46cSDimitry Andric         if (Rt == 15)
1715dff0c46cSDimitry Andric           S = MCDisassembler::SoftFail;
1716dff0c46cSDimitry Andric         break;
1717dff0c46cSDimitry Andric       }
1718dff0c46cSDimitry Andric       if (type && (Rt == 15 || (writeback && Rn == Rt)))
1719dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1720dff0c46cSDimitry Andric       if (!type && (Rt == 15 || Rm == 15))
1721dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
1722dff0c46cSDimitry Andric       if (!type && writeback && (Rn == 15 || Rn == Rt))
1723dff0c46cSDimitry Andric         S = MCDisassembler::SoftFail;
17246122f3e6SDimitry Andric       break;
17256122f3e6SDimitry Andric     default:
17266122f3e6SDimitry Andric       break;
17276122f3e6SDimitry Andric   }
17286122f3e6SDimitry Andric 
17296122f3e6SDimitry Andric   if (writeback) { // Writeback
17306122f3e6SDimitry Andric     if (P)
17316122f3e6SDimitry Andric       U |= ARMII::IndexModePre << 9;
17326122f3e6SDimitry Andric     else
17336122f3e6SDimitry Andric       U |= ARMII::IndexModePost << 9;
17346122f3e6SDimitry Andric 
17356122f3e6SDimitry Andric     // On stores, the writeback operand precedes Rt.
17366122f3e6SDimitry Andric     switch (Inst.getOpcode()) {
17376122f3e6SDimitry Andric     case ARM::STRD:
17386122f3e6SDimitry Andric     case ARM::STRD_PRE:
17396122f3e6SDimitry Andric     case ARM::STRD_POST:
17406122f3e6SDimitry Andric     case ARM::STRH:
17416122f3e6SDimitry Andric     case ARM::STRH_PRE:
17426122f3e6SDimitry Andric     case ARM::STRH_POST:
17436122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
17446122f3e6SDimitry Andric         return MCDisassembler::Fail;
17456122f3e6SDimitry Andric       break;
17466122f3e6SDimitry Andric     default:
17476122f3e6SDimitry Andric       break;
17486122f3e6SDimitry Andric     }
17496122f3e6SDimitry Andric   }
17506122f3e6SDimitry Andric 
17516122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
17526122f3e6SDimitry Andric     return MCDisassembler::Fail;
17536122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
17546122f3e6SDimitry Andric     case ARM::STRD:
17556122f3e6SDimitry Andric     case ARM::STRD_PRE:
17566122f3e6SDimitry Andric     case ARM::STRD_POST:
17576122f3e6SDimitry Andric     case ARM::LDRD:
17586122f3e6SDimitry Andric     case ARM::LDRD_PRE:
17596122f3e6SDimitry Andric     case ARM::LDRD_POST:
17606122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
17616122f3e6SDimitry Andric         return MCDisassembler::Fail;
17626122f3e6SDimitry Andric       break;
17636122f3e6SDimitry Andric     default:
17646122f3e6SDimitry Andric       break;
17656122f3e6SDimitry Andric   }
17666122f3e6SDimitry Andric 
17676122f3e6SDimitry Andric   if (writeback) {
17686122f3e6SDimitry Andric     // On loads, the writeback operand comes after Rt.
17696122f3e6SDimitry Andric     switch (Inst.getOpcode()) {
17706122f3e6SDimitry Andric     case ARM::LDRD:
17716122f3e6SDimitry Andric     case ARM::LDRD_PRE:
17726122f3e6SDimitry Andric     case ARM::LDRD_POST:
17736122f3e6SDimitry Andric     case ARM::LDRH:
17746122f3e6SDimitry Andric     case ARM::LDRH_PRE:
17756122f3e6SDimitry Andric     case ARM::LDRH_POST:
17766122f3e6SDimitry Andric     case ARM::LDRSH:
17776122f3e6SDimitry Andric     case ARM::LDRSH_PRE:
17786122f3e6SDimitry Andric     case ARM::LDRSH_POST:
17796122f3e6SDimitry Andric     case ARM::LDRSB:
17806122f3e6SDimitry Andric     case ARM::LDRSB_PRE:
17816122f3e6SDimitry Andric     case ARM::LDRSB_POST:
17826122f3e6SDimitry Andric     case ARM::LDRHTr:
17836122f3e6SDimitry Andric     case ARM::LDRSBTr:
17846122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
17856122f3e6SDimitry Andric         return MCDisassembler::Fail;
17866122f3e6SDimitry Andric       break;
17876122f3e6SDimitry Andric     default:
17886122f3e6SDimitry Andric       break;
17896122f3e6SDimitry Andric     }
17906122f3e6SDimitry Andric   }
17916122f3e6SDimitry Andric 
17926122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
17936122f3e6SDimitry Andric     return MCDisassembler::Fail;
17946122f3e6SDimitry Andric 
17956122f3e6SDimitry Andric   if (type) {
1796ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
1797ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(U | (imm << 4) | Rm));
17986122f3e6SDimitry Andric   } else {
17996122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
18006122f3e6SDimitry Andric     return MCDisassembler::Fail;
1801ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(U));
18026122f3e6SDimitry Andric   }
18036122f3e6SDimitry Andric 
18046122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
18056122f3e6SDimitry Andric     return MCDisassembler::Fail;
18066122f3e6SDimitry Andric 
18076122f3e6SDimitry Andric   return S;
18086122f3e6SDimitry Andric }
18096122f3e6SDimitry Andric 
DecodeRFEInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1810dff0c46cSDimitry Andric static DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
18116122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
18126122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
18136122f3e6SDimitry Andric 
18147ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
18157ae0e2c9SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 23, 2);
18166122f3e6SDimitry Andric 
18176122f3e6SDimitry Andric   switch (mode) {
18186122f3e6SDimitry Andric     case 0:
18196122f3e6SDimitry Andric       mode = ARM_AM::da;
18206122f3e6SDimitry Andric       break;
18216122f3e6SDimitry Andric     case 1:
18226122f3e6SDimitry Andric       mode = ARM_AM::ia;
18236122f3e6SDimitry Andric       break;
18246122f3e6SDimitry Andric     case 2:
18256122f3e6SDimitry Andric       mode = ARM_AM::db;
18266122f3e6SDimitry Andric       break;
18276122f3e6SDimitry Andric     case 3:
18286122f3e6SDimitry Andric       mode = ARM_AM::ib;
18296122f3e6SDimitry Andric       break;
18306122f3e6SDimitry Andric   }
18316122f3e6SDimitry Andric 
1832ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(mode));
18336122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
18346122f3e6SDimitry Andric     return MCDisassembler::Fail;
18356122f3e6SDimitry Andric 
18366122f3e6SDimitry Andric   return S;
18376122f3e6SDimitry Andric }
18386122f3e6SDimitry Andric 
DecodeQADDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1839f785676fSDimitry Andric static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
1840f785676fSDimitry Andric                                uint64_t Address, const void *Decoder) {
1841f785676fSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
1842f785676fSDimitry Andric 
1843f785676fSDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
1844f785676fSDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1845f785676fSDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1846f785676fSDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
1847f785676fSDimitry Andric 
1848f785676fSDimitry Andric   if (pred == 0xF)
1849f785676fSDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
1850f785676fSDimitry Andric 
1851f785676fSDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
1852f785676fSDimitry Andric     return MCDisassembler::Fail;
1853f785676fSDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1854f785676fSDimitry Andric     return MCDisassembler::Fail;
1855f785676fSDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
1856f785676fSDimitry Andric     return MCDisassembler::Fail;
1857f785676fSDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1858f785676fSDimitry Andric     return MCDisassembler::Fail;
1859f785676fSDimitry Andric   return S;
1860f785676fSDimitry Andric }
1861f785676fSDimitry Andric 
DecodeMemMultipleWritebackInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1862dff0c46cSDimitry Andric static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst,
18636122f3e6SDimitry Andric                                   unsigned Insn,
18646122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
18656122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
18666122f3e6SDimitry Andric 
18677ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
18687ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
18697ae0e2c9SDimitry Andric   unsigned reglist = fieldFromInstruction(Insn, 0, 16);
18706122f3e6SDimitry Andric 
18716122f3e6SDimitry Andric   if (pred == 0xF) {
1872f785676fSDimitry Andric     // Ambiguous with RFE and SRS
18736122f3e6SDimitry Andric     switch (Inst.getOpcode()) {
18746122f3e6SDimitry Andric       case ARM::LDMDA:
18756122f3e6SDimitry Andric         Inst.setOpcode(ARM::RFEDA);
18766122f3e6SDimitry Andric         break;
18776122f3e6SDimitry Andric       case ARM::LDMDA_UPD:
18786122f3e6SDimitry Andric         Inst.setOpcode(ARM::RFEDA_UPD);
18796122f3e6SDimitry Andric         break;
18806122f3e6SDimitry Andric       case ARM::LDMDB:
18816122f3e6SDimitry Andric         Inst.setOpcode(ARM::RFEDB);
18826122f3e6SDimitry Andric         break;
18836122f3e6SDimitry Andric       case ARM::LDMDB_UPD:
18846122f3e6SDimitry Andric         Inst.setOpcode(ARM::RFEDB_UPD);
18856122f3e6SDimitry Andric         break;
18866122f3e6SDimitry Andric       case ARM::LDMIA:
18876122f3e6SDimitry Andric         Inst.setOpcode(ARM::RFEIA);
18886122f3e6SDimitry Andric         break;
18896122f3e6SDimitry Andric       case ARM::LDMIA_UPD:
18906122f3e6SDimitry Andric         Inst.setOpcode(ARM::RFEIA_UPD);
18916122f3e6SDimitry Andric         break;
18926122f3e6SDimitry Andric       case ARM::LDMIB:
18936122f3e6SDimitry Andric         Inst.setOpcode(ARM::RFEIB);
18946122f3e6SDimitry Andric         break;
18956122f3e6SDimitry Andric       case ARM::LDMIB_UPD:
18966122f3e6SDimitry Andric         Inst.setOpcode(ARM::RFEIB_UPD);
18976122f3e6SDimitry Andric         break;
18986122f3e6SDimitry Andric       case ARM::STMDA:
18996122f3e6SDimitry Andric         Inst.setOpcode(ARM::SRSDA);
19006122f3e6SDimitry Andric         break;
19016122f3e6SDimitry Andric       case ARM::STMDA_UPD:
19026122f3e6SDimitry Andric         Inst.setOpcode(ARM::SRSDA_UPD);
19036122f3e6SDimitry Andric         break;
19046122f3e6SDimitry Andric       case ARM::STMDB:
19056122f3e6SDimitry Andric         Inst.setOpcode(ARM::SRSDB);
19066122f3e6SDimitry Andric         break;
19076122f3e6SDimitry Andric       case ARM::STMDB_UPD:
19086122f3e6SDimitry Andric         Inst.setOpcode(ARM::SRSDB_UPD);
19096122f3e6SDimitry Andric         break;
19106122f3e6SDimitry Andric       case ARM::STMIA:
19116122f3e6SDimitry Andric         Inst.setOpcode(ARM::SRSIA);
19126122f3e6SDimitry Andric         break;
19136122f3e6SDimitry Andric       case ARM::STMIA_UPD:
19146122f3e6SDimitry Andric         Inst.setOpcode(ARM::SRSIA_UPD);
19156122f3e6SDimitry Andric         break;
19166122f3e6SDimitry Andric       case ARM::STMIB:
19176122f3e6SDimitry Andric         Inst.setOpcode(ARM::SRSIB);
19186122f3e6SDimitry Andric         break;
19196122f3e6SDimitry Andric       case ARM::STMIB_UPD:
19206122f3e6SDimitry Andric         Inst.setOpcode(ARM::SRSIB_UPD);
19216122f3e6SDimitry Andric         break;
19226122f3e6SDimitry Andric       default:
1923f785676fSDimitry Andric         return MCDisassembler::Fail;
19246122f3e6SDimitry Andric     }
19256122f3e6SDimitry Andric 
19266122f3e6SDimitry Andric     // For stores (which become SRS's, the only operand is the mode.
19277ae0e2c9SDimitry Andric     if (fieldFromInstruction(Insn, 20, 1) == 0) {
1928f785676fSDimitry Andric       // Check SRS encoding constraints
1929f785676fSDimitry Andric       if (!(fieldFromInstruction(Insn, 22, 1) == 1 &&
1930f785676fSDimitry Andric             fieldFromInstruction(Insn, 20, 1) == 0))
1931f785676fSDimitry Andric         return MCDisassembler::Fail;
1932f785676fSDimitry Andric 
19336122f3e6SDimitry Andric       Inst.addOperand(
1934ff0cc061SDimitry Andric           MCOperand::createImm(fieldFromInstruction(Insn, 0, 4)));
19356122f3e6SDimitry Andric       return S;
19366122f3e6SDimitry Andric     }
19376122f3e6SDimitry Andric 
19386122f3e6SDimitry Andric     return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
19396122f3e6SDimitry Andric   }
19406122f3e6SDimitry Andric 
19416122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
19426122f3e6SDimitry Andric     return MCDisassembler::Fail;
19436122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
19446122f3e6SDimitry Andric     return MCDisassembler::Fail; // Tied
19456122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
19466122f3e6SDimitry Andric     return MCDisassembler::Fail;
19476122f3e6SDimitry Andric   if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
19486122f3e6SDimitry Andric     return MCDisassembler::Fail;
19496122f3e6SDimitry Andric 
19506122f3e6SDimitry Andric   return S;
19516122f3e6SDimitry Andric }
19526122f3e6SDimitry Andric 
19533ca95b02SDimitry Andric // Check for UNPREDICTABLE predicated ESB instruction
DecodeHINTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)19543ca95b02SDimitry Andric static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
19553ca95b02SDimitry Andric                                  uint64_t Address, const void *Decoder) {
19563ca95b02SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
19573ca95b02SDimitry Andric   unsigned imm8 = fieldFromInstruction(Insn, 0, 8);
19583ca95b02SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
19593ca95b02SDimitry Andric   const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
19603ca95b02SDimitry Andric 
19613ca95b02SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
19623ca95b02SDimitry Andric 
19633ca95b02SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm8));
19643ca95b02SDimitry Andric 
19653ca95b02SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
19663ca95b02SDimitry Andric     return MCDisassembler::Fail;
19673ca95b02SDimitry Andric 
19683ca95b02SDimitry Andric   // ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP,
19693ca95b02SDimitry Andric   // so all predicates should be allowed.
19703ca95b02SDimitry Andric   if (imm8 == 0x10 && pred != 0xe && ((FeatureBits[ARM::FeatureRAS]) != 0))
19713ca95b02SDimitry Andric     S = MCDisassembler::SoftFail;
19723ca95b02SDimitry Andric 
19733ca95b02SDimitry Andric   return S;
19743ca95b02SDimitry Andric }
19753ca95b02SDimitry Andric 
DecodeCPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1976dff0c46cSDimitry Andric static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
19776122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
19787ae0e2c9SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 18, 2);
19797ae0e2c9SDimitry Andric   unsigned M = fieldFromInstruction(Insn, 17, 1);
19807ae0e2c9SDimitry Andric   unsigned iflags = fieldFromInstruction(Insn, 6, 3);
19817ae0e2c9SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 0, 5);
19826122f3e6SDimitry Andric 
19836122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
19846122f3e6SDimitry Andric 
1985f785676fSDimitry Andric   // This decoder is called from multiple location that do not check
1986f785676fSDimitry Andric   // the full encoding is valid before they do.
1987f785676fSDimitry Andric   if (fieldFromInstruction(Insn, 5, 1) != 0 ||
1988f785676fSDimitry Andric       fieldFromInstruction(Insn, 16, 1) != 0 ||
1989f785676fSDimitry Andric       fieldFromInstruction(Insn, 20, 8) != 0x10)
1990f785676fSDimitry Andric     return MCDisassembler::Fail;
1991f785676fSDimitry Andric 
19926122f3e6SDimitry Andric   // imod == '01' --> UNPREDICTABLE
19936122f3e6SDimitry Andric   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
19946122f3e6SDimitry Andric   // return failure here.  The '01' imod value is unprintable, so there's
19956122f3e6SDimitry Andric   // nothing useful we could do even if we returned UNPREDICTABLE.
19966122f3e6SDimitry Andric 
19976122f3e6SDimitry Andric   if (imod == 1) return MCDisassembler::Fail;
19986122f3e6SDimitry Andric 
19996122f3e6SDimitry Andric   if (imod && M) {
20006122f3e6SDimitry Andric     Inst.setOpcode(ARM::CPS3p);
2001ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
2002ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
2003ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
20046122f3e6SDimitry Andric   } else if (imod && !M) {
20056122f3e6SDimitry Andric     Inst.setOpcode(ARM::CPS2p);
2006ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
2007ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
20086122f3e6SDimitry Andric     if (mode) S = MCDisassembler::SoftFail;
20096122f3e6SDimitry Andric   } else if (!imod && M) {
20106122f3e6SDimitry Andric     Inst.setOpcode(ARM::CPS1p);
2011ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
20126122f3e6SDimitry Andric     if (iflags) S = MCDisassembler::SoftFail;
20136122f3e6SDimitry Andric   } else {
20146122f3e6SDimitry Andric     // imod == '00' && M == '0' --> UNPREDICTABLE
20156122f3e6SDimitry Andric     Inst.setOpcode(ARM::CPS1p);
2016ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
20176122f3e6SDimitry Andric     S = MCDisassembler::SoftFail;
20186122f3e6SDimitry Andric   }
20196122f3e6SDimitry Andric 
20206122f3e6SDimitry Andric   return S;
20216122f3e6SDimitry Andric }
20226122f3e6SDimitry Andric 
DecodeT2CPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2023dff0c46cSDimitry Andric static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
20246122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
20257ae0e2c9SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 9, 2);
20267ae0e2c9SDimitry Andric   unsigned M = fieldFromInstruction(Insn, 8, 1);
20277ae0e2c9SDimitry Andric   unsigned iflags = fieldFromInstruction(Insn, 5, 3);
20287ae0e2c9SDimitry Andric   unsigned mode = fieldFromInstruction(Insn, 0, 5);
20296122f3e6SDimitry Andric 
20306122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
20316122f3e6SDimitry Andric 
20326122f3e6SDimitry Andric   // imod == '01' --> UNPREDICTABLE
20336122f3e6SDimitry Andric   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
20346122f3e6SDimitry Andric   // return failure here.  The '01' imod value is unprintable, so there's
20356122f3e6SDimitry Andric   // nothing useful we could do even if we returned UNPREDICTABLE.
20366122f3e6SDimitry Andric 
20376122f3e6SDimitry Andric   if (imod == 1) return MCDisassembler::Fail;
20386122f3e6SDimitry Andric 
20396122f3e6SDimitry Andric   if (imod && M) {
20406122f3e6SDimitry Andric     Inst.setOpcode(ARM::t2CPS3p);
2041ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
2042ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
2043ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
20446122f3e6SDimitry Andric   } else if (imod && !M) {
20456122f3e6SDimitry Andric     Inst.setOpcode(ARM::t2CPS2p);
2046ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imod));
2047ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(iflags));
20486122f3e6SDimitry Andric     if (mode) S = MCDisassembler::SoftFail;
20496122f3e6SDimitry Andric   } else if (!imod && M) {
20506122f3e6SDimitry Andric     Inst.setOpcode(ARM::t2CPS1p);
2051ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(mode));
20526122f3e6SDimitry Andric     if (iflags) S = MCDisassembler::SoftFail;
20536122f3e6SDimitry Andric   } else {
2054284c1978SDimitry Andric     // imod == '00' && M == '0' --> this is a HINT instruction
2055284c1978SDimitry Andric     int imm = fieldFromInstruction(Insn, 0, 8);
2056284c1978SDimitry Andric     // HINT are defined only for immediate in [0..4]
2057284c1978SDimitry Andric     if(imm > 4) return MCDisassembler::Fail;
2058284c1978SDimitry Andric     Inst.setOpcode(ARM::t2HINT);
2059ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
20606122f3e6SDimitry Andric   }
20616122f3e6SDimitry Andric 
20626122f3e6SDimitry Andric   return S;
20636122f3e6SDimitry Andric }
20646122f3e6SDimitry Andric 
DecodeT2MOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2065dff0c46cSDimitry Andric static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
20666122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
20676122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
20686122f3e6SDimitry Andric 
20697ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 8, 4);
20706122f3e6SDimitry Andric   unsigned imm = 0;
20716122f3e6SDimitry Andric 
20727ae0e2c9SDimitry Andric   imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
20737ae0e2c9SDimitry Andric   imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
20747ae0e2c9SDimitry Andric   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
20757ae0e2c9SDimitry Andric   imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
20766122f3e6SDimitry Andric 
20776122f3e6SDimitry Andric   if (Inst.getOpcode() == ARM::t2MOVTi16)
20786122f3e6SDimitry Andric     if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
20796122f3e6SDimitry Andric       return MCDisassembler::Fail;
20806122f3e6SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
20816122f3e6SDimitry Andric     return MCDisassembler::Fail;
20826122f3e6SDimitry Andric 
20836122f3e6SDimitry Andric   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
2084ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
20856122f3e6SDimitry Andric 
20866122f3e6SDimitry Andric   return S;
20876122f3e6SDimitry Andric }
20886122f3e6SDimitry Andric 
DecodeArmMOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2089dff0c46cSDimitry Andric static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
20906122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
20916122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
20926122f3e6SDimitry Andric 
20937ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
20947ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
20956122f3e6SDimitry Andric   unsigned imm = 0;
20966122f3e6SDimitry Andric 
20977ae0e2c9SDimitry Andric   imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
20987ae0e2c9SDimitry Andric   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
20996122f3e6SDimitry Andric 
21006122f3e6SDimitry Andric   if (Inst.getOpcode() == ARM::MOVTi16)
2101284c1978SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
21026122f3e6SDimitry Andric       return MCDisassembler::Fail;
2103284c1978SDimitry Andric 
2104284c1978SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
21056122f3e6SDimitry Andric     return MCDisassembler::Fail;
21066122f3e6SDimitry Andric 
21076122f3e6SDimitry Andric   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
2108ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
21096122f3e6SDimitry Andric 
21106122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
21116122f3e6SDimitry Andric     return MCDisassembler::Fail;
21126122f3e6SDimitry Andric 
21136122f3e6SDimitry Andric   return S;
21146122f3e6SDimitry Andric }
21156122f3e6SDimitry Andric 
DecodeSMLAInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2116dff0c46cSDimitry Andric static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
21176122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
21186122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
21196122f3e6SDimitry Andric 
21207ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 16, 4);
21217ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 0, 4);
21227ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 8, 4);
21237ae0e2c9SDimitry Andric   unsigned Ra = fieldFromInstruction(Insn, 12, 4);
21247ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
21256122f3e6SDimitry Andric 
21266122f3e6SDimitry Andric   if (pred == 0xF)
21276122f3e6SDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
21286122f3e6SDimitry Andric 
21296122f3e6SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
21306122f3e6SDimitry Andric     return MCDisassembler::Fail;
21316122f3e6SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
21326122f3e6SDimitry Andric     return MCDisassembler::Fail;
21336122f3e6SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
21346122f3e6SDimitry Andric     return MCDisassembler::Fail;
21356122f3e6SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
21366122f3e6SDimitry Andric     return MCDisassembler::Fail;
21376122f3e6SDimitry Andric 
21386122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
21396122f3e6SDimitry Andric     return MCDisassembler::Fail;
21406122f3e6SDimitry Andric 
21416122f3e6SDimitry Andric   return S;
21426122f3e6SDimitry Andric }
21436122f3e6SDimitry Andric 
DecodeTSTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2144ff0cc061SDimitry Andric static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
2145ff0cc061SDimitry Andric                                   uint64_t Address, const void *Decoder) {
2146ff0cc061SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
2147ff0cc061SDimitry Andric 
2148ff0cc061SDimitry Andric   unsigned Pred = fieldFromInstruction(Insn, 28, 4);
2149ff0cc061SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2150ff0cc061SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2151ff0cc061SDimitry Andric 
2152ff0cc061SDimitry Andric   if (Pred == 0xF)
2153ff0cc061SDimitry Andric     return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
2154ff0cc061SDimitry Andric 
2155ff0cc061SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2156ff0cc061SDimitry Andric     return MCDisassembler::Fail;
2157ff0cc061SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2158ff0cc061SDimitry Andric     return MCDisassembler::Fail;
2159ff0cc061SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
2160ff0cc061SDimitry Andric     return MCDisassembler::Fail;
2161ff0cc061SDimitry Andric 
2162ff0cc061SDimitry Andric   return S;
2163ff0cc061SDimitry Andric }
2164ff0cc061SDimitry Andric 
DecodeSETPANInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2165ff0cc061SDimitry Andric static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
2166ff0cc061SDimitry Andric                                   uint64_t Address, const void *Decoder) {
2167ff0cc061SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
2168ff0cc061SDimitry Andric 
2169ff0cc061SDimitry Andric   unsigned Imm = fieldFromInstruction(Insn, 9, 1);
2170ff0cc061SDimitry Andric 
2171ff0cc061SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
2172ff0cc061SDimitry Andric   const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
2173ff0cc061SDimitry Andric 
2174ff0cc061SDimitry Andric   if (!FeatureBits[ARM::HasV8_1aOps] ||
2175ff0cc061SDimitry Andric       !FeatureBits[ARM::HasV8Ops])
2176ff0cc061SDimitry Andric     return MCDisassembler::Fail;
2177ff0cc061SDimitry Andric 
2178ff0cc061SDimitry Andric   // Decoder can be called from DecodeTST, which does not check the full
2179ff0cc061SDimitry Andric   // encoding is valid.
2180ff0cc061SDimitry Andric   if (fieldFromInstruction(Insn, 20,12) != 0xf11 ||
2181ff0cc061SDimitry Andric       fieldFromInstruction(Insn, 4,4) != 0)
2182ff0cc061SDimitry Andric     return MCDisassembler::Fail;
2183ff0cc061SDimitry Andric   if (fieldFromInstruction(Insn, 10,10) != 0 ||
2184ff0cc061SDimitry Andric       fieldFromInstruction(Insn, 0,4) != 0)
2185ff0cc061SDimitry Andric     S = MCDisassembler::SoftFail;
2186ff0cc061SDimitry Andric 
2187ff0cc061SDimitry Andric   Inst.setOpcode(ARM::SETPAN);
2188ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
2189ff0cc061SDimitry Andric 
2190ff0cc061SDimitry Andric   return S;
2191ff0cc061SDimitry Andric }
2192ff0cc061SDimitry Andric 
DecodeAddrModeImm12Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)2193dff0c46cSDimitry Andric static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
21946122f3e6SDimitry Andric                            uint64_t Address, const void *Decoder) {
21956122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
21966122f3e6SDimitry Andric 
21977ae0e2c9SDimitry Andric   unsigned add = fieldFromInstruction(Val, 12, 1);
21987ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 12);
21997ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
22006122f3e6SDimitry Andric 
22016122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
22026122f3e6SDimitry Andric     return MCDisassembler::Fail;
22036122f3e6SDimitry Andric 
22046122f3e6SDimitry Andric   if (!add) imm *= -1;
22056122f3e6SDimitry Andric   if (imm == 0 && !add) imm = INT32_MIN;
2206ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
22076122f3e6SDimitry Andric   if (Rn == 15)
22086122f3e6SDimitry Andric     tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
22096122f3e6SDimitry Andric 
22106122f3e6SDimitry Andric   return S;
22116122f3e6SDimitry Andric }
22126122f3e6SDimitry Andric 
DecodeAddrMode5Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)2213dff0c46cSDimitry Andric static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
22146122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
22156122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
22166122f3e6SDimitry Andric 
22177ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
22183ca95b02SDimitry Andric   // U == 1 to add imm, 0 to subtract it.
22197ae0e2c9SDimitry Andric   unsigned U = fieldFromInstruction(Val, 8, 1);
22207ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
22216122f3e6SDimitry Andric 
22226122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
22236122f3e6SDimitry Andric     return MCDisassembler::Fail;
22246122f3e6SDimitry Andric 
22256122f3e6SDimitry Andric   if (U)
2226ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
22276122f3e6SDimitry Andric   else
2228ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
22296122f3e6SDimitry Andric 
22306122f3e6SDimitry Andric   return S;
22316122f3e6SDimitry Andric }
22326122f3e6SDimitry Andric 
DecodeAddrMode5FP16Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)22333ca95b02SDimitry Andric static DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
22343ca95b02SDimitry Andric                                    uint64_t Address, const void *Decoder) {
22353ca95b02SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
22363ca95b02SDimitry Andric 
22373ca95b02SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
22383ca95b02SDimitry Andric   // U == 1 to add imm, 0 to subtract it.
22393ca95b02SDimitry Andric   unsigned U = fieldFromInstruction(Val, 8, 1);
22403ca95b02SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
22413ca95b02SDimitry Andric 
22423ca95b02SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
22433ca95b02SDimitry Andric     return MCDisassembler::Fail;
22443ca95b02SDimitry Andric 
22453ca95b02SDimitry Andric   if (U)
22463ca95b02SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::add, imm)));
22473ca95b02SDimitry Andric   else
22483ca95b02SDimitry Andric     Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::sub, imm)));
22493ca95b02SDimitry Andric 
22503ca95b02SDimitry Andric   return S;
22513ca95b02SDimitry Andric }
22523ca95b02SDimitry Andric 
DecodeAddrMode7Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)2253dff0c46cSDimitry Andric static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
22546122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
22556122f3e6SDimitry Andric   return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
22566122f3e6SDimitry Andric }
22576122f3e6SDimitry Andric 
22586122f3e6SDimitry Andric static DecodeStatus
DecodeT2BInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2259dff0c46cSDimitry Andric DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2260dff0c46cSDimitry Andric                      uint64_t Address, const void *Decoder) {
22613861d79fSDimitry Andric   DecodeStatus Status = MCDisassembler::Success;
22623861d79fSDimitry Andric 
22633861d79fSDimitry Andric   // Note the J1 and J2 values are from the encoded instruction.  So here
22643861d79fSDimitry Andric   // change them to I1 and I2 values via as documented:
22653861d79fSDimitry Andric   // I1 = NOT(J1 EOR S);
22663861d79fSDimitry Andric   // I2 = NOT(J2 EOR S);
22673861d79fSDimitry Andric   // and build the imm32 with one trailing zero as documented:
22683861d79fSDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
22693861d79fSDimitry Andric   unsigned S = fieldFromInstruction(Insn, 26, 1);
22703861d79fSDimitry Andric   unsigned J1 = fieldFromInstruction(Insn, 13, 1);
22713861d79fSDimitry Andric   unsigned J2 = fieldFromInstruction(Insn, 11, 1);
22723861d79fSDimitry Andric   unsigned I1 = !(J1 ^ S);
22733861d79fSDimitry Andric   unsigned I2 = !(J2 ^ S);
22743861d79fSDimitry Andric   unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
22753861d79fSDimitry Andric   unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
22763861d79fSDimitry Andric   unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
2277f785676fSDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
22783861d79fSDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
2279dff0c46cSDimitry Andric                                 true, 4, Inst, Decoder))
2280ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
22813861d79fSDimitry Andric 
22823861d79fSDimitry Andric   return Status;
2283dff0c46cSDimitry Andric }
2284dff0c46cSDimitry Andric 
2285dff0c46cSDimitry Andric static DecodeStatus
DecodeBranchImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2286dff0c46cSDimitry Andric DecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
22876122f3e6SDimitry Andric                            uint64_t Address, const void *Decoder) {
22886122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
22896122f3e6SDimitry Andric 
22907ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
22917ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
22926122f3e6SDimitry Andric 
22936122f3e6SDimitry Andric   if (pred == 0xF) {
22946122f3e6SDimitry Andric     Inst.setOpcode(ARM::BLXi);
22957ae0e2c9SDimitry Andric     imm |= fieldFromInstruction(Insn, 24, 1) << 1;
2296dff0c46cSDimitry Andric     if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2297dff0c46cSDimitry Andric                                   true, 4, Inst, Decoder))
2298ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
22996122f3e6SDimitry Andric     return S;
23006122f3e6SDimitry Andric   }
23016122f3e6SDimitry Andric 
2302dff0c46cSDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2303dff0c46cSDimitry Andric                                 true, 4, Inst, Decoder))
2304ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
23056122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
23066122f3e6SDimitry Andric     return MCDisassembler::Fail;
23076122f3e6SDimitry Andric 
23086122f3e6SDimitry Andric   return S;
23096122f3e6SDimitry Andric }
23106122f3e6SDimitry Andric 
DecodeAddrMode6Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)2311dff0c46cSDimitry Andric static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
23126122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
23136122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
23146122f3e6SDimitry Andric 
23157ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
23167ae0e2c9SDimitry Andric   unsigned align = fieldFromInstruction(Val, 4, 2);
23176122f3e6SDimitry Andric 
23186122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
23196122f3e6SDimitry Andric     return MCDisassembler::Fail;
23206122f3e6SDimitry Andric   if (!align)
2321ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
23226122f3e6SDimitry Andric   else
2323ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(4 << align));
23246122f3e6SDimitry Andric 
23256122f3e6SDimitry Andric   return S;
23266122f3e6SDimitry Andric }
23276122f3e6SDimitry Andric 
DecodeVLDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2328dff0c46cSDimitry Andric static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
23296122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
23306122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
23316122f3e6SDimitry Andric 
23327ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
23337ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
23347ae0e2c9SDimitry Andric   unsigned wb = fieldFromInstruction(Insn, 16, 4);
23357ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
23367ae0e2c9SDimitry Andric   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
23377ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
23386122f3e6SDimitry Andric 
23396122f3e6SDimitry Andric   // First output register
2340dff0c46cSDimitry Andric   switch (Inst.getOpcode()) {
2341dff0c46cSDimitry Andric   case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
2342dff0c46cSDimitry Andric   case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
2343dff0c46cSDimitry Andric   case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
2344dff0c46cSDimitry Andric   case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
2345dff0c46cSDimitry Andric   case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
2346dff0c46cSDimitry Andric   case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
2347dff0c46cSDimitry Andric   case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
2348dff0c46cSDimitry Andric   case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
2349dff0c46cSDimitry Andric   case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
2350dff0c46cSDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2351dff0c46cSDimitry Andric       return MCDisassembler::Fail;
2352dff0c46cSDimitry Andric     break;
2353dff0c46cSDimitry Andric   case ARM::VLD2b16:
2354dff0c46cSDimitry Andric   case ARM::VLD2b32:
2355dff0c46cSDimitry Andric   case ARM::VLD2b8:
2356dff0c46cSDimitry Andric   case ARM::VLD2b16wb_fixed:
2357dff0c46cSDimitry Andric   case ARM::VLD2b16wb_register:
2358dff0c46cSDimitry Andric   case ARM::VLD2b32wb_fixed:
2359dff0c46cSDimitry Andric   case ARM::VLD2b32wb_register:
2360dff0c46cSDimitry Andric   case ARM::VLD2b8wb_fixed:
2361dff0c46cSDimitry Andric   case ARM::VLD2b8wb_register:
2362dff0c46cSDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2363dff0c46cSDimitry Andric       return MCDisassembler::Fail;
2364dff0c46cSDimitry Andric     break;
2365dff0c46cSDimitry Andric   default:
23666122f3e6SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
23676122f3e6SDimitry Andric       return MCDisassembler::Fail;
2368dff0c46cSDimitry Andric   }
23696122f3e6SDimitry Andric 
23706122f3e6SDimitry Andric   // Second output register
23716122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
23726122f3e6SDimitry Andric     case ARM::VLD3d8:
23736122f3e6SDimitry Andric     case ARM::VLD3d16:
23746122f3e6SDimitry Andric     case ARM::VLD3d32:
23756122f3e6SDimitry Andric     case ARM::VLD3d8_UPD:
23766122f3e6SDimitry Andric     case ARM::VLD3d16_UPD:
23776122f3e6SDimitry Andric     case ARM::VLD3d32_UPD:
23786122f3e6SDimitry Andric     case ARM::VLD4d8:
23796122f3e6SDimitry Andric     case ARM::VLD4d16:
23806122f3e6SDimitry Andric     case ARM::VLD4d32:
23816122f3e6SDimitry Andric     case ARM::VLD4d8_UPD:
23826122f3e6SDimitry Andric     case ARM::VLD4d16_UPD:
23836122f3e6SDimitry Andric     case ARM::VLD4d32_UPD:
23846122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
23856122f3e6SDimitry Andric         return MCDisassembler::Fail;
23866122f3e6SDimitry Andric       break;
23876122f3e6SDimitry Andric     case ARM::VLD3q8:
23886122f3e6SDimitry Andric     case ARM::VLD3q16:
23896122f3e6SDimitry Andric     case ARM::VLD3q32:
23906122f3e6SDimitry Andric     case ARM::VLD3q8_UPD:
23916122f3e6SDimitry Andric     case ARM::VLD3q16_UPD:
23926122f3e6SDimitry Andric     case ARM::VLD3q32_UPD:
23936122f3e6SDimitry Andric     case ARM::VLD4q8:
23946122f3e6SDimitry Andric     case ARM::VLD4q16:
23956122f3e6SDimitry Andric     case ARM::VLD4q32:
23966122f3e6SDimitry Andric     case ARM::VLD4q8_UPD:
23976122f3e6SDimitry Andric     case ARM::VLD4q16_UPD:
23986122f3e6SDimitry Andric     case ARM::VLD4q32_UPD:
23996122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
24006122f3e6SDimitry Andric         return MCDisassembler::Fail;
2401da09e106SDimitry Andric       break;
24026122f3e6SDimitry Andric     default:
24036122f3e6SDimitry Andric       break;
24046122f3e6SDimitry Andric   }
24056122f3e6SDimitry Andric 
24066122f3e6SDimitry Andric   // Third output register
24076122f3e6SDimitry Andric   switch(Inst.getOpcode()) {
24086122f3e6SDimitry Andric     case ARM::VLD3d8:
24096122f3e6SDimitry Andric     case ARM::VLD3d16:
24106122f3e6SDimitry Andric     case ARM::VLD3d32:
24116122f3e6SDimitry Andric     case ARM::VLD3d8_UPD:
24126122f3e6SDimitry Andric     case ARM::VLD3d16_UPD:
24136122f3e6SDimitry Andric     case ARM::VLD3d32_UPD:
24146122f3e6SDimitry Andric     case ARM::VLD4d8:
24156122f3e6SDimitry Andric     case ARM::VLD4d16:
24166122f3e6SDimitry Andric     case ARM::VLD4d32:
24176122f3e6SDimitry Andric     case ARM::VLD4d8_UPD:
24186122f3e6SDimitry Andric     case ARM::VLD4d16_UPD:
24196122f3e6SDimitry Andric     case ARM::VLD4d32_UPD:
24206122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
24216122f3e6SDimitry Andric         return MCDisassembler::Fail;
24226122f3e6SDimitry Andric       break;
24236122f3e6SDimitry Andric     case ARM::VLD3q8:
24246122f3e6SDimitry Andric     case ARM::VLD3q16:
24256122f3e6SDimitry Andric     case ARM::VLD3q32:
24266122f3e6SDimitry Andric     case ARM::VLD3q8_UPD:
24276122f3e6SDimitry Andric     case ARM::VLD3q16_UPD:
24286122f3e6SDimitry Andric     case ARM::VLD3q32_UPD:
24296122f3e6SDimitry Andric     case ARM::VLD4q8:
24306122f3e6SDimitry Andric     case ARM::VLD4q16:
24316122f3e6SDimitry Andric     case ARM::VLD4q32:
24326122f3e6SDimitry Andric     case ARM::VLD4q8_UPD:
24336122f3e6SDimitry Andric     case ARM::VLD4q16_UPD:
24346122f3e6SDimitry Andric     case ARM::VLD4q32_UPD:
24356122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
24366122f3e6SDimitry Andric         return MCDisassembler::Fail;
24376122f3e6SDimitry Andric       break;
24386122f3e6SDimitry Andric     default:
24396122f3e6SDimitry Andric       break;
24406122f3e6SDimitry Andric   }
24416122f3e6SDimitry Andric 
24426122f3e6SDimitry Andric   // Fourth output register
24436122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
24446122f3e6SDimitry Andric     case ARM::VLD4d8:
24456122f3e6SDimitry Andric     case ARM::VLD4d16:
24466122f3e6SDimitry Andric     case ARM::VLD4d32:
24476122f3e6SDimitry Andric     case ARM::VLD4d8_UPD:
24486122f3e6SDimitry Andric     case ARM::VLD4d16_UPD:
24496122f3e6SDimitry Andric     case ARM::VLD4d32_UPD:
24506122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
24516122f3e6SDimitry Andric         return MCDisassembler::Fail;
24526122f3e6SDimitry Andric       break;
24536122f3e6SDimitry Andric     case ARM::VLD4q8:
24546122f3e6SDimitry Andric     case ARM::VLD4q16:
24556122f3e6SDimitry Andric     case ARM::VLD4q32:
24566122f3e6SDimitry Andric     case ARM::VLD4q8_UPD:
24576122f3e6SDimitry Andric     case ARM::VLD4q16_UPD:
24586122f3e6SDimitry Andric     case ARM::VLD4q32_UPD:
24596122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
24606122f3e6SDimitry Andric         return MCDisassembler::Fail;
24616122f3e6SDimitry Andric       break;
24626122f3e6SDimitry Andric     default:
24636122f3e6SDimitry Andric       break;
24646122f3e6SDimitry Andric   }
24656122f3e6SDimitry Andric 
24666122f3e6SDimitry Andric   // Writeback operand
24676122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
2468dff0c46cSDimitry Andric     case ARM::VLD1d8wb_fixed:
2469dff0c46cSDimitry Andric     case ARM::VLD1d16wb_fixed:
2470dff0c46cSDimitry Andric     case ARM::VLD1d32wb_fixed:
2471dff0c46cSDimitry Andric     case ARM::VLD1d64wb_fixed:
2472dff0c46cSDimitry Andric     case ARM::VLD1d8wb_register:
2473dff0c46cSDimitry Andric     case ARM::VLD1d16wb_register:
2474dff0c46cSDimitry Andric     case ARM::VLD1d32wb_register:
2475dff0c46cSDimitry Andric     case ARM::VLD1d64wb_register:
2476dff0c46cSDimitry Andric     case ARM::VLD1q8wb_fixed:
2477dff0c46cSDimitry Andric     case ARM::VLD1q16wb_fixed:
2478dff0c46cSDimitry Andric     case ARM::VLD1q32wb_fixed:
2479dff0c46cSDimitry Andric     case ARM::VLD1q64wb_fixed:
2480dff0c46cSDimitry Andric     case ARM::VLD1q8wb_register:
2481dff0c46cSDimitry Andric     case ARM::VLD1q16wb_register:
2482dff0c46cSDimitry Andric     case ARM::VLD1q32wb_register:
2483dff0c46cSDimitry Andric     case ARM::VLD1q64wb_register:
2484dff0c46cSDimitry Andric     case ARM::VLD1d8Twb_fixed:
2485dff0c46cSDimitry Andric     case ARM::VLD1d8Twb_register:
2486dff0c46cSDimitry Andric     case ARM::VLD1d16Twb_fixed:
2487dff0c46cSDimitry Andric     case ARM::VLD1d16Twb_register:
2488dff0c46cSDimitry Andric     case ARM::VLD1d32Twb_fixed:
2489dff0c46cSDimitry Andric     case ARM::VLD1d32Twb_register:
2490dff0c46cSDimitry Andric     case ARM::VLD1d64Twb_fixed:
2491dff0c46cSDimitry Andric     case ARM::VLD1d64Twb_register:
2492dff0c46cSDimitry Andric     case ARM::VLD1d8Qwb_fixed:
2493dff0c46cSDimitry Andric     case ARM::VLD1d8Qwb_register:
2494dff0c46cSDimitry Andric     case ARM::VLD1d16Qwb_fixed:
2495dff0c46cSDimitry Andric     case ARM::VLD1d16Qwb_register:
2496dff0c46cSDimitry Andric     case ARM::VLD1d32Qwb_fixed:
2497dff0c46cSDimitry Andric     case ARM::VLD1d32Qwb_register:
2498dff0c46cSDimitry Andric     case ARM::VLD1d64Qwb_fixed:
2499dff0c46cSDimitry Andric     case ARM::VLD1d64Qwb_register:
2500dff0c46cSDimitry Andric     case ARM::VLD2d8wb_fixed:
2501dff0c46cSDimitry Andric     case ARM::VLD2d16wb_fixed:
2502dff0c46cSDimitry Andric     case ARM::VLD2d32wb_fixed:
2503dff0c46cSDimitry Andric     case ARM::VLD2q8wb_fixed:
2504dff0c46cSDimitry Andric     case ARM::VLD2q16wb_fixed:
2505dff0c46cSDimitry Andric     case ARM::VLD2q32wb_fixed:
2506dff0c46cSDimitry Andric     case ARM::VLD2d8wb_register:
2507dff0c46cSDimitry Andric     case ARM::VLD2d16wb_register:
2508dff0c46cSDimitry Andric     case ARM::VLD2d32wb_register:
2509dff0c46cSDimitry Andric     case ARM::VLD2q8wb_register:
2510dff0c46cSDimitry Andric     case ARM::VLD2q16wb_register:
2511dff0c46cSDimitry Andric     case ARM::VLD2q32wb_register:
2512dff0c46cSDimitry Andric     case ARM::VLD2b8wb_fixed:
2513dff0c46cSDimitry Andric     case ARM::VLD2b16wb_fixed:
2514dff0c46cSDimitry Andric     case ARM::VLD2b32wb_fixed:
2515dff0c46cSDimitry Andric     case ARM::VLD2b8wb_register:
2516dff0c46cSDimitry Andric     case ARM::VLD2b16wb_register:
2517dff0c46cSDimitry Andric     case ARM::VLD2b32wb_register:
2518ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
2519dff0c46cSDimitry Andric       break;
25206122f3e6SDimitry Andric     case ARM::VLD3d8_UPD:
25216122f3e6SDimitry Andric     case ARM::VLD3d16_UPD:
25226122f3e6SDimitry Andric     case ARM::VLD3d32_UPD:
25236122f3e6SDimitry Andric     case ARM::VLD3q8_UPD:
25246122f3e6SDimitry Andric     case ARM::VLD3q16_UPD:
25256122f3e6SDimitry Andric     case ARM::VLD3q32_UPD:
25266122f3e6SDimitry Andric     case ARM::VLD4d8_UPD:
25276122f3e6SDimitry Andric     case ARM::VLD4d16_UPD:
25286122f3e6SDimitry Andric     case ARM::VLD4d32_UPD:
25296122f3e6SDimitry Andric     case ARM::VLD4q8_UPD:
25306122f3e6SDimitry Andric     case ARM::VLD4q16_UPD:
25316122f3e6SDimitry Andric     case ARM::VLD4q32_UPD:
25326122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
25336122f3e6SDimitry Andric         return MCDisassembler::Fail;
25346122f3e6SDimitry Andric       break;
25356122f3e6SDimitry Andric     default:
25366122f3e6SDimitry Andric       break;
25376122f3e6SDimitry Andric   }
25386122f3e6SDimitry Andric 
25396122f3e6SDimitry Andric   // AddrMode6 Base (register+alignment)
25406122f3e6SDimitry Andric   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
25416122f3e6SDimitry Andric     return MCDisassembler::Fail;
25426122f3e6SDimitry Andric 
25436122f3e6SDimitry Andric   // AddrMode6 Offset (register)
2544dff0c46cSDimitry Andric   switch (Inst.getOpcode()) {
2545dff0c46cSDimitry Andric   default:
2546dff0c46cSDimitry Andric     // The below have been updated to have explicit am6offset split
2547dff0c46cSDimitry Andric     // between fixed and register offset. For those instructions not
2548dff0c46cSDimitry Andric     // yet updated, we need to add an additional reg0 operand for the
2549dff0c46cSDimitry Andric     // fixed variant.
2550dff0c46cSDimitry Andric     //
2551dff0c46cSDimitry Andric     // The fixed offset encodes as Rm == 0xd, so we check for that.
2552dff0c46cSDimitry Andric     if (Rm == 0xd) {
2553ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
2554dff0c46cSDimitry Andric       break;
2555dff0c46cSDimitry Andric     }
2556dff0c46cSDimitry Andric     // Fall through to handle the register offset variant.
2557d88c1a5aSDimitry Andric     LLVM_FALLTHROUGH;
2558dff0c46cSDimitry Andric   case ARM::VLD1d8wb_fixed:
2559dff0c46cSDimitry Andric   case ARM::VLD1d16wb_fixed:
2560dff0c46cSDimitry Andric   case ARM::VLD1d32wb_fixed:
2561dff0c46cSDimitry Andric   case ARM::VLD1d64wb_fixed:
2562dff0c46cSDimitry Andric   case ARM::VLD1d8Twb_fixed:
2563dff0c46cSDimitry Andric   case ARM::VLD1d16Twb_fixed:
2564dff0c46cSDimitry Andric   case ARM::VLD1d32Twb_fixed:
2565dff0c46cSDimitry Andric   case ARM::VLD1d64Twb_fixed:
2566dff0c46cSDimitry Andric   case ARM::VLD1d8Qwb_fixed:
2567dff0c46cSDimitry Andric   case ARM::VLD1d16Qwb_fixed:
2568dff0c46cSDimitry Andric   case ARM::VLD1d32Qwb_fixed:
2569dff0c46cSDimitry Andric   case ARM::VLD1d64Qwb_fixed:
2570dff0c46cSDimitry Andric   case ARM::VLD1d8wb_register:
2571dff0c46cSDimitry Andric   case ARM::VLD1d16wb_register:
2572dff0c46cSDimitry Andric   case ARM::VLD1d32wb_register:
2573dff0c46cSDimitry Andric   case ARM::VLD1d64wb_register:
2574dff0c46cSDimitry Andric   case ARM::VLD1q8wb_fixed:
2575dff0c46cSDimitry Andric   case ARM::VLD1q16wb_fixed:
2576dff0c46cSDimitry Andric   case ARM::VLD1q32wb_fixed:
2577dff0c46cSDimitry Andric   case ARM::VLD1q64wb_fixed:
2578dff0c46cSDimitry Andric   case ARM::VLD1q8wb_register:
2579dff0c46cSDimitry Andric   case ARM::VLD1q16wb_register:
2580dff0c46cSDimitry Andric   case ARM::VLD1q32wb_register:
2581dff0c46cSDimitry Andric   case ARM::VLD1q64wb_register:
2582dff0c46cSDimitry Andric     // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2583dff0c46cSDimitry Andric     // variant encodes Rm == 0xf. Anything else is a register offset post-
2584dff0c46cSDimitry Andric     // increment and we need to add the register operand to the instruction.
2585dff0c46cSDimitry Andric     if (Rm != 0xD && Rm != 0xF &&
2586dff0c46cSDimitry Andric         !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
25876122f3e6SDimitry Andric       return MCDisassembler::Fail;
2588dff0c46cSDimitry Andric     break;
2589dff0c46cSDimitry Andric   case ARM::VLD2d8wb_fixed:
2590dff0c46cSDimitry Andric   case ARM::VLD2d16wb_fixed:
2591dff0c46cSDimitry Andric   case ARM::VLD2d32wb_fixed:
2592dff0c46cSDimitry Andric   case ARM::VLD2b8wb_fixed:
2593dff0c46cSDimitry Andric   case ARM::VLD2b16wb_fixed:
2594dff0c46cSDimitry Andric   case ARM::VLD2b32wb_fixed:
2595dff0c46cSDimitry Andric   case ARM::VLD2q8wb_fixed:
2596dff0c46cSDimitry Andric   case ARM::VLD2q16wb_fixed:
2597dff0c46cSDimitry Andric   case ARM::VLD2q32wb_fixed:
2598dff0c46cSDimitry Andric     break;
25996122f3e6SDimitry Andric   }
26006122f3e6SDimitry Andric 
26016122f3e6SDimitry Andric   return S;
26026122f3e6SDimitry Andric }
26036122f3e6SDimitry Andric 
DecodeVLDST1Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2604f785676fSDimitry Andric static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
2605f785676fSDimitry Andric                                    uint64_t Address, const void *Decoder) {
2606f785676fSDimitry Andric   unsigned type = fieldFromInstruction(Insn, 8, 4);
2607f785676fSDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
2608f785676fSDimitry Andric   if (type == 6 && (align & 2)) return MCDisassembler::Fail;
2609f785676fSDimitry Andric   if (type == 7 && (align & 2)) return MCDisassembler::Fail;
2610f785676fSDimitry Andric   if (type == 10 && align == 3) return MCDisassembler::Fail;
2611f785676fSDimitry Andric 
2612f785676fSDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
2613f785676fSDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2614f785676fSDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2615f785676fSDimitry Andric }
2616f785676fSDimitry Andric 
DecodeVLDST2Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2617f785676fSDimitry Andric static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
2618f785676fSDimitry Andric                                    uint64_t Address, const void *Decoder) {
2619f785676fSDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
2620f785676fSDimitry Andric   if (size == 3) return MCDisassembler::Fail;
2621f785676fSDimitry Andric 
2622f785676fSDimitry Andric   unsigned type = fieldFromInstruction(Insn, 8, 4);
2623f785676fSDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
2624f785676fSDimitry Andric   if (type == 8 && align == 3) return MCDisassembler::Fail;
2625f785676fSDimitry Andric   if (type == 9 && align == 3) return MCDisassembler::Fail;
2626f785676fSDimitry Andric 
2627f785676fSDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
2628f785676fSDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2629f785676fSDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2630f785676fSDimitry Andric }
2631f785676fSDimitry Andric 
DecodeVLDST3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2632f785676fSDimitry Andric static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
2633f785676fSDimitry Andric                                    uint64_t Address, const void *Decoder) {
2634f785676fSDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
2635f785676fSDimitry Andric   if (size == 3) return MCDisassembler::Fail;
2636f785676fSDimitry Andric 
2637f785676fSDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 2);
2638f785676fSDimitry Andric   if (align & 2) return MCDisassembler::Fail;
2639f785676fSDimitry Andric 
2640f785676fSDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
2641f785676fSDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2642f785676fSDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2643f785676fSDimitry Andric }
2644f785676fSDimitry Andric 
DecodeVLDST4Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2645f785676fSDimitry Andric static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
2646f785676fSDimitry Andric                                    uint64_t Address, const void *Decoder) {
2647f785676fSDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
2648f785676fSDimitry Andric   if (size == 3) return MCDisassembler::Fail;
2649f785676fSDimitry Andric 
2650f785676fSDimitry Andric   unsigned load = fieldFromInstruction(Insn, 21, 1);
2651f785676fSDimitry Andric   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2652f785676fSDimitry Andric               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2653f785676fSDimitry Andric }
2654f785676fSDimitry Andric 
DecodeVSTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2655dff0c46cSDimitry Andric static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
26566122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
26576122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
26586122f3e6SDimitry Andric 
26597ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
26607ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
26617ae0e2c9SDimitry Andric   unsigned wb = fieldFromInstruction(Insn, 16, 4);
26627ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
26637ae0e2c9SDimitry Andric   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
26647ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
26656122f3e6SDimitry Andric 
26666122f3e6SDimitry Andric   // Writeback Operand
26676122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
2668dff0c46cSDimitry Andric     case ARM::VST1d8wb_fixed:
2669dff0c46cSDimitry Andric     case ARM::VST1d16wb_fixed:
2670dff0c46cSDimitry Andric     case ARM::VST1d32wb_fixed:
2671dff0c46cSDimitry Andric     case ARM::VST1d64wb_fixed:
2672dff0c46cSDimitry Andric     case ARM::VST1d8wb_register:
2673dff0c46cSDimitry Andric     case ARM::VST1d16wb_register:
2674dff0c46cSDimitry Andric     case ARM::VST1d32wb_register:
2675dff0c46cSDimitry Andric     case ARM::VST1d64wb_register:
2676dff0c46cSDimitry Andric     case ARM::VST1q8wb_fixed:
2677dff0c46cSDimitry Andric     case ARM::VST1q16wb_fixed:
2678dff0c46cSDimitry Andric     case ARM::VST1q32wb_fixed:
2679dff0c46cSDimitry Andric     case ARM::VST1q64wb_fixed:
2680dff0c46cSDimitry Andric     case ARM::VST1q8wb_register:
2681dff0c46cSDimitry Andric     case ARM::VST1q16wb_register:
2682dff0c46cSDimitry Andric     case ARM::VST1q32wb_register:
2683dff0c46cSDimitry Andric     case ARM::VST1q64wb_register:
2684dff0c46cSDimitry Andric     case ARM::VST1d8Twb_fixed:
2685dff0c46cSDimitry Andric     case ARM::VST1d16Twb_fixed:
2686dff0c46cSDimitry Andric     case ARM::VST1d32Twb_fixed:
2687dff0c46cSDimitry Andric     case ARM::VST1d64Twb_fixed:
2688dff0c46cSDimitry Andric     case ARM::VST1d8Twb_register:
2689dff0c46cSDimitry Andric     case ARM::VST1d16Twb_register:
2690dff0c46cSDimitry Andric     case ARM::VST1d32Twb_register:
2691dff0c46cSDimitry Andric     case ARM::VST1d64Twb_register:
2692dff0c46cSDimitry Andric     case ARM::VST1d8Qwb_fixed:
2693dff0c46cSDimitry Andric     case ARM::VST1d16Qwb_fixed:
2694dff0c46cSDimitry Andric     case ARM::VST1d32Qwb_fixed:
2695dff0c46cSDimitry Andric     case ARM::VST1d64Qwb_fixed:
2696dff0c46cSDimitry Andric     case ARM::VST1d8Qwb_register:
2697dff0c46cSDimitry Andric     case ARM::VST1d16Qwb_register:
2698dff0c46cSDimitry Andric     case ARM::VST1d32Qwb_register:
2699dff0c46cSDimitry Andric     case ARM::VST1d64Qwb_register:
2700dff0c46cSDimitry Andric     case ARM::VST2d8wb_fixed:
2701dff0c46cSDimitry Andric     case ARM::VST2d16wb_fixed:
2702dff0c46cSDimitry Andric     case ARM::VST2d32wb_fixed:
2703dff0c46cSDimitry Andric     case ARM::VST2d8wb_register:
2704dff0c46cSDimitry Andric     case ARM::VST2d16wb_register:
2705dff0c46cSDimitry Andric     case ARM::VST2d32wb_register:
2706dff0c46cSDimitry Andric     case ARM::VST2q8wb_fixed:
2707dff0c46cSDimitry Andric     case ARM::VST2q16wb_fixed:
2708dff0c46cSDimitry Andric     case ARM::VST2q32wb_fixed:
2709dff0c46cSDimitry Andric     case ARM::VST2q8wb_register:
2710dff0c46cSDimitry Andric     case ARM::VST2q16wb_register:
2711dff0c46cSDimitry Andric     case ARM::VST2q32wb_register:
2712dff0c46cSDimitry Andric     case ARM::VST2b8wb_fixed:
2713dff0c46cSDimitry Andric     case ARM::VST2b16wb_fixed:
2714dff0c46cSDimitry Andric     case ARM::VST2b32wb_fixed:
2715dff0c46cSDimitry Andric     case ARM::VST2b8wb_register:
2716dff0c46cSDimitry Andric     case ARM::VST2b16wb_register:
2717dff0c46cSDimitry Andric     case ARM::VST2b32wb_register:
2718dff0c46cSDimitry Andric       if (Rm == 0xF)
2719dff0c46cSDimitry Andric         return MCDisassembler::Fail;
2720ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
2721dff0c46cSDimitry Andric       break;
27226122f3e6SDimitry Andric     case ARM::VST3d8_UPD:
27236122f3e6SDimitry Andric     case ARM::VST3d16_UPD:
27246122f3e6SDimitry Andric     case ARM::VST3d32_UPD:
27256122f3e6SDimitry Andric     case ARM::VST3q8_UPD:
27266122f3e6SDimitry Andric     case ARM::VST3q16_UPD:
27276122f3e6SDimitry Andric     case ARM::VST3q32_UPD:
27286122f3e6SDimitry Andric     case ARM::VST4d8_UPD:
27296122f3e6SDimitry Andric     case ARM::VST4d16_UPD:
27306122f3e6SDimitry Andric     case ARM::VST4d32_UPD:
27316122f3e6SDimitry Andric     case ARM::VST4q8_UPD:
27326122f3e6SDimitry Andric     case ARM::VST4q16_UPD:
27336122f3e6SDimitry Andric     case ARM::VST4q32_UPD:
27346122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
27356122f3e6SDimitry Andric         return MCDisassembler::Fail;
27366122f3e6SDimitry Andric       break;
27376122f3e6SDimitry Andric     default:
27386122f3e6SDimitry Andric       break;
27396122f3e6SDimitry Andric   }
27406122f3e6SDimitry Andric 
27416122f3e6SDimitry Andric   // AddrMode6 Base (register+alignment)
27426122f3e6SDimitry Andric   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
27436122f3e6SDimitry Andric     return MCDisassembler::Fail;
27446122f3e6SDimitry Andric 
27456122f3e6SDimitry Andric   // AddrMode6 Offset (register)
2746dff0c46cSDimitry Andric   switch (Inst.getOpcode()) {
2747dff0c46cSDimitry Andric     default:
27486122f3e6SDimitry Andric       if (Rm == 0xD)
2749ff0cc061SDimitry Andric         Inst.addOperand(MCOperand::createReg(0));
27506122f3e6SDimitry Andric       else if (Rm != 0xF) {
27516122f3e6SDimitry Andric         if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
27526122f3e6SDimitry Andric           return MCDisassembler::Fail;
27536122f3e6SDimitry Andric       }
2754dff0c46cSDimitry Andric       break;
2755dff0c46cSDimitry Andric     case ARM::VST1d8wb_fixed:
2756dff0c46cSDimitry Andric     case ARM::VST1d16wb_fixed:
2757dff0c46cSDimitry Andric     case ARM::VST1d32wb_fixed:
2758dff0c46cSDimitry Andric     case ARM::VST1d64wb_fixed:
2759dff0c46cSDimitry Andric     case ARM::VST1q8wb_fixed:
2760dff0c46cSDimitry Andric     case ARM::VST1q16wb_fixed:
2761dff0c46cSDimitry Andric     case ARM::VST1q32wb_fixed:
2762dff0c46cSDimitry Andric     case ARM::VST1q64wb_fixed:
2763dff0c46cSDimitry Andric     case ARM::VST1d8Twb_fixed:
2764dff0c46cSDimitry Andric     case ARM::VST1d16Twb_fixed:
2765dff0c46cSDimitry Andric     case ARM::VST1d32Twb_fixed:
2766dff0c46cSDimitry Andric     case ARM::VST1d64Twb_fixed:
2767dff0c46cSDimitry Andric     case ARM::VST1d8Qwb_fixed:
2768dff0c46cSDimitry Andric     case ARM::VST1d16Qwb_fixed:
2769dff0c46cSDimitry Andric     case ARM::VST1d32Qwb_fixed:
2770dff0c46cSDimitry Andric     case ARM::VST1d64Qwb_fixed:
2771dff0c46cSDimitry Andric     case ARM::VST2d8wb_fixed:
2772dff0c46cSDimitry Andric     case ARM::VST2d16wb_fixed:
2773dff0c46cSDimitry Andric     case ARM::VST2d32wb_fixed:
2774dff0c46cSDimitry Andric     case ARM::VST2q8wb_fixed:
2775dff0c46cSDimitry Andric     case ARM::VST2q16wb_fixed:
2776dff0c46cSDimitry Andric     case ARM::VST2q32wb_fixed:
2777dff0c46cSDimitry Andric     case ARM::VST2b8wb_fixed:
2778dff0c46cSDimitry Andric     case ARM::VST2b16wb_fixed:
2779dff0c46cSDimitry Andric     case ARM::VST2b32wb_fixed:
2780dff0c46cSDimitry Andric       break;
2781dff0c46cSDimitry Andric   }
2782dff0c46cSDimitry Andric 
27836122f3e6SDimitry Andric   // First input register
27846122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
27856122f3e6SDimitry Andric   case ARM::VST1q16:
27866122f3e6SDimitry Andric   case ARM::VST1q32:
27876122f3e6SDimitry Andric   case ARM::VST1q64:
2788dff0c46cSDimitry Andric   case ARM::VST1q8:
2789dff0c46cSDimitry Andric   case ARM::VST1q16wb_fixed:
2790dff0c46cSDimitry Andric   case ARM::VST1q16wb_register:
2791dff0c46cSDimitry Andric   case ARM::VST1q32wb_fixed:
2792dff0c46cSDimitry Andric   case ARM::VST1q32wb_register:
2793dff0c46cSDimitry Andric   case ARM::VST1q64wb_fixed:
2794dff0c46cSDimitry Andric   case ARM::VST1q64wb_register:
2795dff0c46cSDimitry Andric   case ARM::VST1q8wb_fixed:
2796dff0c46cSDimitry Andric   case ARM::VST1q8wb_register:
27976122f3e6SDimitry Andric   case ARM::VST2d16:
27986122f3e6SDimitry Andric   case ARM::VST2d32:
2799dff0c46cSDimitry Andric   case ARM::VST2d8:
2800dff0c46cSDimitry Andric   case ARM::VST2d16wb_fixed:
2801dff0c46cSDimitry Andric   case ARM::VST2d16wb_register:
2802dff0c46cSDimitry Andric   case ARM::VST2d32wb_fixed:
2803dff0c46cSDimitry Andric   case ARM::VST2d32wb_register:
2804dff0c46cSDimitry Andric   case ARM::VST2d8wb_fixed:
2805dff0c46cSDimitry Andric   case ARM::VST2d8wb_register:
2806dff0c46cSDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2807dff0c46cSDimitry Andric       return MCDisassembler::Fail;
2808dff0c46cSDimitry Andric     break;
2809dff0c46cSDimitry Andric   case ARM::VST2b16:
2810dff0c46cSDimitry Andric   case ARM::VST2b32:
2811dff0c46cSDimitry Andric   case ARM::VST2b8:
2812dff0c46cSDimitry Andric   case ARM::VST2b16wb_fixed:
2813dff0c46cSDimitry Andric   case ARM::VST2b16wb_register:
2814dff0c46cSDimitry Andric   case ARM::VST2b32wb_fixed:
2815dff0c46cSDimitry Andric   case ARM::VST2b32wb_register:
2816dff0c46cSDimitry Andric   case ARM::VST2b8wb_fixed:
2817dff0c46cSDimitry Andric   case ARM::VST2b8wb_register:
2818dff0c46cSDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2819dff0c46cSDimitry Andric       return MCDisassembler::Fail;
2820dff0c46cSDimitry Andric     break;
2821dff0c46cSDimitry Andric   default:
2822dff0c46cSDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2823dff0c46cSDimitry Andric       return MCDisassembler::Fail;
2824dff0c46cSDimitry Andric   }
2825dff0c46cSDimitry Andric 
2826dff0c46cSDimitry Andric   // Second input register
2827dff0c46cSDimitry Andric   switch (Inst.getOpcode()) {
28286122f3e6SDimitry Andric     case ARM::VST3d8:
28296122f3e6SDimitry Andric     case ARM::VST3d16:
28306122f3e6SDimitry Andric     case ARM::VST3d32:
28316122f3e6SDimitry Andric     case ARM::VST3d8_UPD:
28326122f3e6SDimitry Andric     case ARM::VST3d16_UPD:
28336122f3e6SDimitry Andric     case ARM::VST3d32_UPD:
28346122f3e6SDimitry Andric     case ARM::VST4d8:
28356122f3e6SDimitry Andric     case ARM::VST4d16:
28366122f3e6SDimitry Andric     case ARM::VST4d32:
28376122f3e6SDimitry Andric     case ARM::VST4d8_UPD:
28386122f3e6SDimitry Andric     case ARM::VST4d16_UPD:
28396122f3e6SDimitry Andric     case ARM::VST4d32_UPD:
28406122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
28416122f3e6SDimitry Andric         return MCDisassembler::Fail;
28426122f3e6SDimitry Andric       break;
28436122f3e6SDimitry Andric     case ARM::VST3q8:
28446122f3e6SDimitry Andric     case ARM::VST3q16:
28456122f3e6SDimitry Andric     case ARM::VST3q32:
28466122f3e6SDimitry Andric     case ARM::VST3q8_UPD:
28476122f3e6SDimitry Andric     case ARM::VST3q16_UPD:
28486122f3e6SDimitry Andric     case ARM::VST3q32_UPD:
28496122f3e6SDimitry Andric     case ARM::VST4q8:
28506122f3e6SDimitry Andric     case ARM::VST4q16:
28516122f3e6SDimitry Andric     case ARM::VST4q32:
28526122f3e6SDimitry Andric     case ARM::VST4q8_UPD:
28536122f3e6SDimitry Andric     case ARM::VST4q16_UPD:
28546122f3e6SDimitry Andric     case ARM::VST4q32_UPD:
28556122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
28566122f3e6SDimitry Andric         return MCDisassembler::Fail;
28576122f3e6SDimitry Andric       break;
28586122f3e6SDimitry Andric     default:
28596122f3e6SDimitry Andric       break;
28606122f3e6SDimitry Andric   }
28616122f3e6SDimitry Andric 
28626122f3e6SDimitry Andric   // Third input register
28636122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
28646122f3e6SDimitry Andric     case ARM::VST3d8:
28656122f3e6SDimitry Andric     case ARM::VST3d16:
28666122f3e6SDimitry Andric     case ARM::VST3d32:
28676122f3e6SDimitry Andric     case ARM::VST3d8_UPD:
28686122f3e6SDimitry Andric     case ARM::VST3d16_UPD:
28696122f3e6SDimitry Andric     case ARM::VST3d32_UPD:
28706122f3e6SDimitry Andric     case ARM::VST4d8:
28716122f3e6SDimitry Andric     case ARM::VST4d16:
28726122f3e6SDimitry Andric     case ARM::VST4d32:
28736122f3e6SDimitry Andric     case ARM::VST4d8_UPD:
28746122f3e6SDimitry Andric     case ARM::VST4d16_UPD:
28756122f3e6SDimitry Andric     case ARM::VST4d32_UPD:
28766122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
28776122f3e6SDimitry Andric         return MCDisassembler::Fail;
28786122f3e6SDimitry Andric       break;
28796122f3e6SDimitry Andric     case ARM::VST3q8:
28806122f3e6SDimitry Andric     case ARM::VST3q16:
28816122f3e6SDimitry Andric     case ARM::VST3q32:
28826122f3e6SDimitry Andric     case ARM::VST3q8_UPD:
28836122f3e6SDimitry Andric     case ARM::VST3q16_UPD:
28846122f3e6SDimitry Andric     case ARM::VST3q32_UPD:
28856122f3e6SDimitry Andric     case ARM::VST4q8:
28866122f3e6SDimitry Andric     case ARM::VST4q16:
28876122f3e6SDimitry Andric     case ARM::VST4q32:
28886122f3e6SDimitry Andric     case ARM::VST4q8_UPD:
28896122f3e6SDimitry Andric     case ARM::VST4q16_UPD:
28906122f3e6SDimitry Andric     case ARM::VST4q32_UPD:
28916122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
28926122f3e6SDimitry Andric         return MCDisassembler::Fail;
28936122f3e6SDimitry Andric       break;
28946122f3e6SDimitry Andric     default:
28956122f3e6SDimitry Andric       break;
28966122f3e6SDimitry Andric   }
28976122f3e6SDimitry Andric 
28986122f3e6SDimitry Andric   // Fourth input register
28996122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
29006122f3e6SDimitry Andric     case ARM::VST4d8:
29016122f3e6SDimitry Andric     case ARM::VST4d16:
29026122f3e6SDimitry Andric     case ARM::VST4d32:
29036122f3e6SDimitry Andric     case ARM::VST4d8_UPD:
29046122f3e6SDimitry Andric     case ARM::VST4d16_UPD:
29056122f3e6SDimitry Andric     case ARM::VST4d32_UPD:
29066122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
29076122f3e6SDimitry Andric         return MCDisassembler::Fail;
29086122f3e6SDimitry Andric       break;
29096122f3e6SDimitry Andric     case ARM::VST4q8:
29106122f3e6SDimitry Andric     case ARM::VST4q16:
29116122f3e6SDimitry Andric     case ARM::VST4q32:
29126122f3e6SDimitry Andric     case ARM::VST4q8_UPD:
29136122f3e6SDimitry Andric     case ARM::VST4q16_UPD:
29146122f3e6SDimitry Andric     case ARM::VST4q32_UPD:
29156122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
29166122f3e6SDimitry Andric         return MCDisassembler::Fail;
29176122f3e6SDimitry Andric       break;
29186122f3e6SDimitry Andric     default:
29196122f3e6SDimitry Andric       break;
29206122f3e6SDimitry Andric   }
29216122f3e6SDimitry Andric 
29226122f3e6SDimitry Andric   return S;
29236122f3e6SDimitry Andric }
29246122f3e6SDimitry Andric 
DecodeVLD1DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2925dff0c46cSDimitry Andric static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
29266122f3e6SDimitry Andric                                     uint64_t Address, const void *Decoder) {
29276122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
29286122f3e6SDimitry Andric 
29297ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
29307ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
29317ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
29327ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
29337ae0e2c9SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
29347ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
29356122f3e6SDimitry Andric 
29363861d79fSDimitry Andric   if (size == 0 && align == 1)
29373861d79fSDimitry Andric     return MCDisassembler::Fail;
29386122f3e6SDimitry Andric   align *= (1 << size);
29396122f3e6SDimitry Andric 
2940dff0c46cSDimitry Andric   switch (Inst.getOpcode()) {
2941dff0c46cSDimitry Andric   case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
2942dff0c46cSDimitry Andric   case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
2943dff0c46cSDimitry Andric   case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
2944dff0c46cSDimitry Andric   case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
2945dff0c46cSDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2946dff0c46cSDimitry Andric       return MCDisassembler::Fail;
2947dff0c46cSDimitry Andric     break;
2948dff0c46cSDimitry Andric   default:
29496122f3e6SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
29506122f3e6SDimitry Andric       return MCDisassembler::Fail;
2951dff0c46cSDimitry Andric     break;
29526122f3e6SDimitry Andric   }
29536122f3e6SDimitry Andric   if (Rm != 0xF) {
29546122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
29556122f3e6SDimitry Andric       return MCDisassembler::Fail;
29566122f3e6SDimitry Andric   }
29576122f3e6SDimitry Andric 
29586122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
29596122f3e6SDimitry Andric     return MCDisassembler::Fail;
2960ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
29616122f3e6SDimitry Andric 
2962dff0c46cSDimitry Andric   // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2963dff0c46cSDimitry Andric   // variant encodes Rm == 0xf. Anything else is a register offset post-
2964dff0c46cSDimitry Andric   // increment and we need to add the register operand to the instruction.
2965dff0c46cSDimitry Andric   if (Rm != 0xD && Rm != 0xF &&
2966dff0c46cSDimitry Andric       !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
29676122f3e6SDimitry Andric     return MCDisassembler::Fail;
29686122f3e6SDimitry Andric 
29696122f3e6SDimitry Andric   return S;
29706122f3e6SDimitry Andric }
29716122f3e6SDimitry Andric 
DecodeVLD2DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2972dff0c46cSDimitry Andric static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
29736122f3e6SDimitry Andric                                     uint64_t Address, const void *Decoder) {
29746122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
29756122f3e6SDimitry Andric 
29767ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
29777ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
29787ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
29797ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
29807ae0e2c9SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
29817ae0e2c9SDimitry Andric   unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
29826122f3e6SDimitry Andric   align *= 2*size;
29836122f3e6SDimitry Andric 
2984dff0c46cSDimitry Andric   switch (Inst.getOpcode()) {
2985dff0c46cSDimitry Andric   case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
2986dff0c46cSDimitry Andric   case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
2987dff0c46cSDimitry Andric   case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
2988dff0c46cSDimitry Andric   case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
2989dff0c46cSDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2990dff0c46cSDimitry Andric       return MCDisassembler::Fail;
2991dff0c46cSDimitry Andric     break;
2992dff0c46cSDimitry Andric   case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
2993dff0c46cSDimitry Andric   case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
2994dff0c46cSDimitry Andric   case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
2995dff0c46cSDimitry Andric   case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
2996dff0c46cSDimitry Andric     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2997dff0c46cSDimitry Andric       return MCDisassembler::Fail;
2998dff0c46cSDimitry Andric     break;
2999dff0c46cSDimitry Andric   default:
30006122f3e6SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
30016122f3e6SDimitry Andric       return MCDisassembler::Fail;
3002dff0c46cSDimitry Andric     break;
30036122f3e6SDimitry Andric   }
30046122f3e6SDimitry Andric 
3005dff0c46cSDimitry Andric   if (Rm != 0xF)
3006ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
3007dff0c46cSDimitry Andric 
30086122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
30096122f3e6SDimitry Andric     return MCDisassembler::Fail;
3010ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
30116122f3e6SDimitry Andric 
3012cb4dff85SDimitry Andric   if (Rm != 0xD && Rm != 0xF) {
30136122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
30146122f3e6SDimitry Andric       return MCDisassembler::Fail;
30156122f3e6SDimitry Andric   }
30166122f3e6SDimitry Andric 
30176122f3e6SDimitry Andric   return S;
30186122f3e6SDimitry Andric }
30196122f3e6SDimitry Andric 
DecodeVLD3DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3020dff0c46cSDimitry Andric static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
30216122f3e6SDimitry Andric                                     uint64_t Address, const void *Decoder) {
30226122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
30236122f3e6SDimitry Andric 
30247ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
30257ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
30267ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
30277ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
30287ae0e2c9SDimitry Andric   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
30296122f3e6SDimitry Andric 
30306122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
30316122f3e6SDimitry Andric     return MCDisassembler::Fail;
30326122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
30336122f3e6SDimitry Andric     return MCDisassembler::Fail;
30346122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
30356122f3e6SDimitry Andric     return MCDisassembler::Fail;
30366122f3e6SDimitry Andric   if (Rm != 0xF) {
30376122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
30386122f3e6SDimitry Andric       return MCDisassembler::Fail;
30396122f3e6SDimitry Andric   }
30406122f3e6SDimitry Andric 
30416122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
30426122f3e6SDimitry Andric     return MCDisassembler::Fail;
3043ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
30446122f3e6SDimitry Andric 
30456122f3e6SDimitry Andric   if (Rm == 0xD)
3046ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
30476122f3e6SDimitry Andric   else if (Rm != 0xF) {
30486122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
30496122f3e6SDimitry Andric       return MCDisassembler::Fail;
30506122f3e6SDimitry Andric   }
30516122f3e6SDimitry Andric 
30526122f3e6SDimitry Andric   return S;
30536122f3e6SDimitry Andric }
30546122f3e6SDimitry Andric 
DecodeVLD4DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3055dff0c46cSDimitry Andric static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
30566122f3e6SDimitry Andric                                     uint64_t Address, const void *Decoder) {
30576122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
30586122f3e6SDimitry Andric 
30597ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
30607ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
30617ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
30627ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
30637ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 6, 2);
30647ae0e2c9SDimitry Andric   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
30657ae0e2c9SDimitry Andric   unsigned align = fieldFromInstruction(Insn, 4, 1);
30666122f3e6SDimitry Andric 
30676122f3e6SDimitry Andric   if (size == 0x3) {
30683861d79fSDimitry Andric     if (align == 0)
30693861d79fSDimitry Andric       return MCDisassembler::Fail;
30706122f3e6SDimitry Andric     align = 16;
30716122f3e6SDimitry Andric   } else {
30726122f3e6SDimitry Andric     if (size == 2) {
30736122f3e6SDimitry Andric       align *= 8;
30746122f3e6SDimitry Andric     } else {
30756122f3e6SDimitry Andric       size = 1 << size;
30766122f3e6SDimitry Andric       align *= 4*size;
30776122f3e6SDimitry Andric     }
30786122f3e6SDimitry Andric   }
30796122f3e6SDimitry Andric 
30806122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
30816122f3e6SDimitry Andric     return MCDisassembler::Fail;
30826122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
30836122f3e6SDimitry Andric     return MCDisassembler::Fail;
30846122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
30856122f3e6SDimitry Andric     return MCDisassembler::Fail;
30866122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
30876122f3e6SDimitry Andric     return MCDisassembler::Fail;
30886122f3e6SDimitry Andric   if (Rm != 0xF) {
30896122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
30906122f3e6SDimitry Andric       return MCDisassembler::Fail;
30916122f3e6SDimitry Andric   }
30926122f3e6SDimitry Andric 
30936122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
30946122f3e6SDimitry Andric     return MCDisassembler::Fail;
3095ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
30966122f3e6SDimitry Andric 
30976122f3e6SDimitry Andric   if (Rm == 0xD)
3098ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
30996122f3e6SDimitry Andric   else if (Rm != 0xF) {
31006122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
31016122f3e6SDimitry Andric       return MCDisassembler::Fail;
31026122f3e6SDimitry Andric   }
31036122f3e6SDimitry Andric 
31046122f3e6SDimitry Andric   return S;
31056122f3e6SDimitry Andric }
31066122f3e6SDimitry Andric 
31076122f3e6SDimitry Andric static DecodeStatus
DecodeNEONModImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3108dff0c46cSDimitry Andric DecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn,
31096122f3e6SDimitry Andric                             uint64_t Address, const void *Decoder) {
31106122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
31116122f3e6SDimitry Andric 
31127ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
31137ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
31147ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 4);
31157ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 3) << 4;
31167ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 24, 1) << 7;
31177ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 8, 4) << 8;
31187ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 5, 1) << 12;
31197ae0e2c9SDimitry Andric   unsigned Q = fieldFromInstruction(Insn, 6, 1);
31206122f3e6SDimitry Andric 
31216122f3e6SDimitry Andric   if (Q) {
31226122f3e6SDimitry Andric     if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
31236122f3e6SDimitry Andric     return MCDisassembler::Fail;
31246122f3e6SDimitry Andric   } else {
31256122f3e6SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
31266122f3e6SDimitry Andric     return MCDisassembler::Fail;
31276122f3e6SDimitry Andric   }
31286122f3e6SDimitry Andric 
3129ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
31306122f3e6SDimitry Andric 
31316122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
31326122f3e6SDimitry Andric     case ARM::VORRiv4i16:
31336122f3e6SDimitry Andric     case ARM::VORRiv2i32:
31346122f3e6SDimitry Andric     case ARM::VBICiv4i16:
31356122f3e6SDimitry Andric     case ARM::VBICiv2i32:
31366122f3e6SDimitry Andric       if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
31376122f3e6SDimitry Andric         return MCDisassembler::Fail;
31386122f3e6SDimitry Andric       break;
31396122f3e6SDimitry Andric     case ARM::VORRiv8i16:
31406122f3e6SDimitry Andric     case ARM::VORRiv4i32:
31416122f3e6SDimitry Andric     case ARM::VBICiv8i16:
31426122f3e6SDimitry Andric     case ARM::VBICiv4i32:
31436122f3e6SDimitry Andric       if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
31446122f3e6SDimitry Andric         return MCDisassembler::Fail;
31456122f3e6SDimitry Andric       break;
31466122f3e6SDimitry Andric     default:
31476122f3e6SDimitry Andric       break;
31486122f3e6SDimitry Andric   }
31496122f3e6SDimitry Andric 
31506122f3e6SDimitry Andric   return S;
31516122f3e6SDimitry Andric }
31526122f3e6SDimitry Andric 
DecodeVSHLMaxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3153dff0c46cSDimitry Andric static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
31546122f3e6SDimitry Andric                                         uint64_t Address, const void *Decoder) {
31556122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
31566122f3e6SDimitry Andric 
31577ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
31587ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
31597ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
31607ae0e2c9SDimitry Andric   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
31617ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 18, 2);
31626122f3e6SDimitry Andric 
31636122f3e6SDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
31646122f3e6SDimitry Andric     return MCDisassembler::Fail;
31656122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
31666122f3e6SDimitry Andric     return MCDisassembler::Fail;
3167ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(8 << size));
31686122f3e6SDimitry Andric 
31696122f3e6SDimitry Andric   return S;
31706122f3e6SDimitry Andric }
31716122f3e6SDimitry Andric 
DecodeShiftRight8Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3172dff0c46cSDimitry Andric static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
31736122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder) {
3174ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(8 - Val));
31756122f3e6SDimitry Andric   return MCDisassembler::Success;
31766122f3e6SDimitry Andric }
31776122f3e6SDimitry Andric 
DecodeShiftRight16Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3178dff0c46cSDimitry Andric static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
31796122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder) {
3180ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(16 - Val));
31816122f3e6SDimitry Andric   return MCDisassembler::Success;
31826122f3e6SDimitry Andric }
31836122f3e6SDimitry Andric 
DecodeShiftRight32Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3184dff0c46cSDimitry Andric static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
31856122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder) {
3186ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(32 - Val));
31876122f3e6SDimitry Andric   return MCDisassembler::Success;
31886122f3e6SDimitry Andric }
31896122f3e6SDimitry Andric 
DecodeShiftRight64Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3190dff0c46cSDimitry Andric static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
31916122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder) {
3192ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Val));
31936122f3e6SDimitry Andric   return MCDisassembler::Success;
31946122f3e6SDimitry Andric }
31956122f3e6SDimitry Andric 
DecodeTBLInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3196dff0c46cSDimitry Andric static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
31976122f3e6SDimitry Andric                                uint64_t Address, const void *Decoder) {
31986122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
31996122f3e6SDimitry Andric 
32007ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
32017ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
32027ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
32037ae0e2c9SDimitry Andric   Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
32047ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
32057ae0e2c9SDimitry Andric   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
32067ae0e2c9SDimitry Andric   unsigned op = fieldFromInstruction(Insn, 6, 1);
32076122f3e6SDimitry Andric 
32086122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
32096122f3e6SDimitry Andric     return MCDisassembler::Fail;
32106122f3e6SDimitry Andric   if (op) {
32116122f3e6SDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
32126122f3e6SDimitry Andric     return MCDisassembler::Fail; // Writeback
32136122f3e6SDimitry Andric   }
32146122f3e6SDimitry Andric 
3215dff0c46cSDimitry Andric   switch (Inst.getOpcode()) {
3216dff0c46cSDimitry Andric   case ARM::VTBL2:
3217dff0c46cSDimitry Andric   case ARM::VTBX2:
3218dff0c46cSDimitry Andric     if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
3219dff0c46cSDimitry Andric       return MCDisassembler::Fail;
3220dff0c46cSDimitry Andric     break;
3221dff0c46cSDimitry Andric   default:
3222dff0c46cSDimitry Andric     if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
32236122f3e6SDimitry Andric       return MCDisassembler::Fail;
32246122f3e6SDimitry Andric   }
32256122f3e6SDimitry Andric 
32266122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
32276122f3e6SDimitry Andric     return MCDisassembler::Fail;
32286122f3e6SDimitry Andric 
32296122f3e6SDimitry Andric   return S;
32306122f3e6SDimitry Andric }
32316122f3e6SDimitry Andric 
DecodeThumbAddSpecialReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)3232dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
32336122f3e6SDimitry Andric                                      uint64_t Address, const void *Decoder) {
32346122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
32356122f3e6SDimitry Andric 
32367ae0e2c9SDimitry Andric   unsigned dst = fieldFromInstruction(Insn, 8, 3);
32377ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
32386122f3e6SDimitry Andric 
32396122f3e6SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
32406122f3e6SDimitry Andric     return MCDisassembler::Fail;
32416122f3e6SDimitry Andric 
32426122f3e6SDimitry Andric   switch(Inst.getOpcode()) {
32436122f3e6SDimitry Andric     default:
32446122f3e6SDimitry Andric       return MCDisassembler::Fail;
32456122f3e6SDimitry Andric     case ARM::tADR:
32466122f3e6SDimitry Andric       break; // tADR does not explicitly represent the PC as an operand.
32476122f3e6SDimitry Andric     case ARM::tADDrSPi:
3248ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(ARM::SP));
32496122f3e6SDimitry Andric       break;
32506122f3e6SDimitry Andric   }
32516122f3e6SDimitry Andric 
3252ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
32536122f3e6SDimitry Andric   return S;
32546122f3e6SDimitry Andric }
32556122f3e6SDimitry Andric 
DecodeThumbBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3256dff0c46cSDimitry Andric static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
32576122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
3258dff0c46cSDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
3259dff0c46cSDimitry Andric                                 true, 2, Inst, Decoder))
3260ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<12>(Val << 1)));
32616122f3e6SDimitry Andric   return MCDisassembler::Success;
32626122f3e6SDimitry Andric }
32636122f3e6SDimitry Andric 
DecodeT2BROperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3264dff0c46cSDimitry Andric static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
32656122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
32667ae0e2c9SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
3267dff0c46cSDimitry Andric                                 true, 4, Inst, Decoder))
3268ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<21>(Val)));
32696122f3e6SDimitry Andric   return MCDisassembler::Success;
32706122f3e6SDimitry Andric }
32716122f3e6SDimitry Andric 
DecodeThumbCmpBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3272dff0c46cSDimitry Andric static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
32736122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
3274139f7f9bSDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
3275dff0c46cSDimitry Andric                                 true, 2, Inst, Decoder))
3276ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(Val << 1));
32776122f3e6SDimitry Andric   return MCDisassembler::Success;
32786122f3e6SDimitry Andric }
32796122f3e6SDimitry Andric 
DecodeThumbAddrModeRR(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3280dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
32816122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
32826122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
32836122f3e6SDimitry Andric 
32847ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 0, 3);
32857ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 3, 3);
32866122f3e6SDimitry Andric 
32876122f3e6SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
32886122f3e6SDimitry Andric     return MCDisassembler::Fail;
32896122f3e6SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
32906122f3e6SDimitry Andric     return MCDisassembler::Fail;
32916122f3e6SDimitry Andric 
32926122f3e6SDimitry Andric   return S;
32936122f3e6SDimitry Andric }
32946122f3e6SDimitry Andric 
DecodeThumbAddrModeIS(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3295dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
32966122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
32976122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
32986122f3e6SDimitry Andric 
32997ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 0, 3);
33007ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 3, 5);
33016122f3e6SDimitry Andric 
33026122f3e6SDimitry Andric   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
33036122f3e6SDimitry Andric     return MCDisassembler::Fail;
3304ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
33056122f3e6SDimitry Andric 
33066122f3e6SDimitry Andric   return S;
33076122f3e6SDimitry Andric }
33086122f3e6SDimitry Andric 
DecodeThumbAddrModePC(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3309dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
33106122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
33116122f3e6SDimitry Andric   unsigned imm = Val << 2;
33126122f3e6SDimitry Andric 
3313ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
33146122f3e6SDimitry Andric   tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
33156122f3e6SDimitry Andric 
33166122f3e6SDimitry Andric   return MCDisassembler::Success;
33176122f3e6SDimitry Andric }
33186122f3e6SDimitry Andric 
DecodeThumbAddrModeSP(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3319dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
33206122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
3321ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
3322ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
33236122f3e6SDimitry Andric 
33246122f3e6SDimitry Andric   return MCDisassembler::Success;
33256122f3e6SDimitry Andric }
33266122f3e6SDimitry Andric 
DecodeT2AddrModeSOReg(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3327dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
33286122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
33296122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
33306122f3e6SDimitry Andric 
33317ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 6, 4);
33327ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 2, 4);
33337ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 2);
33346122f3e6SDimitry Andric 
3335f785676fSDimitry Andric   // Thumb stores cannot use PC as dest register.
3336f785676fSDimitry Andric   switch (Inst.getOpcode()) {
3337f785676fSDimitry Andric   case ARM::t2STRHs:
3338f785676fSDimitry Andric   case ARM::t2STRBs:
3339f785676fSDimitry Andric   case ARM::t2STRs:
3340f785676fSDimitry Andric     if (Rn == 15)
3341f785676fSDimitry Andric       return MCDisassembler::Fail;
3342da09e106SDimitry Andric     break;
3343f785676fSDimitry Andric   default:
3344f785676fSDimitry Andric     break;
3345f785676fSDimitry Andric   }
3346f785676fSDimitry Andric 
33476122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
33486122f3e6SDimitry Andric     return MCDisassembler::Fail;
33496122f3e6SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
33506122f3e6SDimitry Andric     return MCDisassembler::Fail;
3351ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
33526122f3e6SDimitry Andric 
33536122f3e6SDimitry Andric   return S;
33546122f3e6SDimitry Andric }
33556122f3e6SDimitry Andric 
DecodeT2LoadShift(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3356dff0c46cSDimitry Andric static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
33576122f3e6SDimitry Andric                               uint64_t Address, const void *Decoder) {
33586122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
33596122f3e6SDimitry Andric 
33607ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
33617ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3362f785676fSDimitry Andric 
3363ff0cc061SDimitry Andric   const FeatureBitset &featureBits =
3364ff0cc061SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3365ff0cc061SDimitry Andric 
3366ff0cc061SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
3367ff0cc061SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
336839d628a0SDimitry Andric 
3369f785676fSDimitry Andric   if (Rn == 15) {
33706122f3e6SDimitry Andric     switch (Inst.getOpcode()) {
33716122f3e6SDimitry Andric     case ARM::t2LDRBs:
33726122f3e6SDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
33736122f3e6SDimitry Andric       break;
33746122f3e6SDimitry Andric     case ARM::t2LDRHs:
33756122f3e6SDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
33766122f3e6SDimitry Andric       break;
33776122f3e6SDimitry Andric     case ARM::t2LDRSHs:
33786122f3e6SDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
33796122f3e6SDimitry Andric       break;
33806122f3e6SDimitry Andric     case ARM::t2LDRSBs:
33816122f3e6SDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
33826122f3e6SDimitry Andric       break;
3383f785676fSDimitry Andric     case ARM::t2LDRs:
3384f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
3385f785676fSDimitry Andric       break;
33866122f3e6SDimitry Andric     case ARM::t2PLDs:
3387f785676fSDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
3388f785676fSDimitry Andric       break;
3389f785676fSDimitry Andric     case ARM::t2PLIs:
3390f785676fSDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
33916122f3e6SDimitry Andric       break;
33926122f3e6SDimitry Andric     default:
33936122f3e6SDimitry Andric       return MCDisassembler::Fail;
33946122f3e6SDimitry Andric     }
33956122f3e6SDimitry Andric 
3396f785676fSDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3397f785676fSDimitry Andric   }
33986122f3e6SDimitry Andric 
3399f785676fSDimitry Andric   if (Rt == 15) {
3400f785676fSDimitry Andric     switch (Inst.getOpcode()) {
3401f785676fSDimitry Andric     case ARM::t2LDRSHs:
3402f785676fSDimitry Andric       return MCDisassembler::Fail;
3403f785676fSDimitry Andric     case ARM::t2LDRHs:
3404f785676fSDimitry Andric       Inst.setOpcode(ARM::t2PLDWs);
3405f785676fSDimitry Andric       break;
340639d628a0SDimitry Andric     case ARM::t2LDRSBs:
340739d628a0SDimitry Andric       Inst.setOpcode(ARM::t2PLIs);
3408da09e106SDimitry Andric       break;
3409f785676fSDimitry Andric     default:
3410f785676fSDimitry Andric       break;
3411f785676fSDimitry Andric     }
3412f785676fSDimitry Andric   }
3413f785676fSDimitry Andric 
3414f785676fSDimitry Andric   switch (Inst.getOpcode()) {
3415f785676fSDimitry Andric     case ARM::t2PLDs:
341639d628a0SDimitry Andric       break;
3417f785676fSDimitry Andric     case ARM::t2PLIs:
341839d628a0SDimitry Andric       if (!hasV7Ops)
341939d628a0SDimitry Andric         return MCDisassembler::Fail;
342039d628a0SDimitry Andric       break;
342139d628a0SDimitry Andric     case ARM::t2PLDWs:
342239d628a0SDimitry Andric       if (!hasV7Ops || !hasMP)
342339d628a0SDimitry Andric         return MCDisassembler::Fail;
3424f785676fSDimitry Andric       break;
3425f785676fSDimitry Andric     default:
3426f785676fSDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3427f785676fSDimitry Andric         return MCDisassembler::Fail;
34286122f3e6SDimitry Andric   }
34296122f3e6SDimitry Andric 
34307ae0e2c9SDimitry Andric   unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
34317ae0e2c9SDimitry Andric   addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
34327ae0e2c9SDimitry Andric   addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
34336122f3e6SDimitry Andric   if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
34346122f3e6SDimitry Andric     return MCDisassembler::Fail;
34356122f3e6SDimitry Andric 
34366122f3e6SDimitry Andric   return S;
34376122f3e6SDimitry Andric }
34386122f3e6SDimitry Andric 
DecodeT2LoadImm8(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3439f785676fSDimitry Andric static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
3440f785676fSDimitry Andric                                 uint64_t Address, const void* Decoder) {
3441f785676fSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
3442f785676fSDimitry Andric 
3443f785676fSDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3444f785676fSDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3445f785676fSDimitry Andric   unsigned U = fieldFromInstruction(Insn, 9, 1);
3446f785676fSDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
3447f785676fSDimitry Andric   imm |= (U << 8);
3448f785676fSDimitry Andric   imm |= (Rn << 9);
344939d628a0SDimitry Andric   unsigned add = fieldFromInstruction(Insn, 9, 1);
345039d628a0SDimitry Andric 
3451ff0cc061SDimitry Andric   const FeatureBitset &featureBits =
3452ff0cc061SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3453ff0cc061SDimitry Andric 
3454ff0cc061SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
3455ff0cc061SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
3456f785676fSDimitry Andric 
3457f785676fSDimitry Andric   if (Rn == 15) {
3458f785676fSDimitry Andric     switch (Inst.getOpcode()) {
3459f785676fSDimitry Andric     case ARM::t2LDRi8:
3460f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
3461f785676fSDimitry Andric       break;
3462f785676fSDimitry Andric     case ARM::t2LDRBi8:
3463f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
3464f785676fSDimitry Andric       break;
3465f785676fSDimitry Andric     case ARM::t2LDRSBi8:
3466f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
3467f785676fSDimitry Andric       break;
3468f785676fSDimitry Andric     case ARM::t2LDRHi8:
3469f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
3470f785676fSDimitry Andric       break;
3471f785676fSDimitry Andric     case ARM::t2LDRSHi8:
3472f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
3473f785676fSDimitry Andric       break;
3474f785676fSDimitry Andric     case ARM::t2PLDi8:
3475f785676fSDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
3476f785676fSDimitry Andric       break;
3477f785676fSDimitry Andric     case ARM::t2PLIi8:
3478f785676fSDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
3479f785676fSDimitry Andric       break;
3480f785676fSDimitry Andric     default:
3481f785676fSDimitry Andric       return MCDisassembler::Fail;
3482f785676fSDimitry Andric     }
3483f785676fSDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3484f785676fSDimitry Andric   }
3485f785676fSDimitry Andric 
3486f785676fSDimitry Andric   if (Rt == 15) {
3487f785676fSDimitry Andric     switch (Inst.getOpcode()) {
3488f785676fSDimitry Andric     case ARM::t2LDRSHi8:
3489f785676fSDimitry Andric       return MCDisassembler::Fail;
349039d628a0SDimitry Andric     case ARM::t2LDRHi8:
349139d628a0SDimitry Andric       if (!add)
349239d628a0SDimitry Andric         Inst.setOpcode(ARM::t2PLDWi8);
349339d628a0SDimitry Andric       break;
349439d628a0SDimitry Andric     case ARM::t2LDRSBi8:
349539d628a0SDimitry Andric       Inst.setOpcode(ARM::t2PLIi8);
349639d628a0SDimitry Andric       break;
3497f785676fSDimitry Andric     default:
3498f785676fSDimitry Andric       break;
3499f785676fSDimitry Andric     }
3500f785676fSDimitry Andric   }
3501f785676fSDimitry Andric 
3502f785676fSDimitry Andric   switch (Inst.getOpcode()) {
3503f785676fSDimitry Andric   case ARM::t2PLDi8:
350439d628a0SDimitry Andric     break;
3505f785676fSDimitry Andric   case ARM::t2PLIi8:
350639d628a0SDimitry Andric     if (!hasV7Ops)
350739d628a0SDimitry Andric       return MCDisassembler::Fail;
350839d628a0SDimitry Andric     break;
3509f785676fSDimitry Andric   case ARM::t2PLDWi8:
351039d628a0SDimitry Andric       if (!hasV7Ops || !hasMP)
351139d628a0SDimitry Andric         return MCDisassembler::Fail;
3512f785676fSDimitry Andric       break;
3513f785676fSDimitry Andric   default:
3514f785676fSDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3515f785676fSDimitry Andric       return MCDisassembler::Fail;
3516f785676fSDimitry Andric   }
3517f785676fSDimitry Andric 
3518f785676fSDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3519f785676fSDimitry Andric     return MCDisassembler::Fail;
3520f785676fSDimitry Andric   return S;
3521f785676fSDimitry Andric }
3522f785676fSDimitry Andric 
DecodeT2LoadImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3523f785676fSDimitry Andric static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
3524f785676fSDimitry Andric                                 uint64_t Address, const void* Decoder) {
3525f785676fSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
3526f785676fSDimitry Andric 
3527f785676fSDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3528f785676fSDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3529f785676fSDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
3530f785676fSDimitry Andric   imm |= (Rn << 13);
3531f785676fSDimitry Andric 
3532ff0cc061SDimitry Andric   const FeatureBitset &featureBits =
3533ff0cc061SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3534ff0cc061SDimitry Andric 
3535ff0cc061SDimitry Andric   bool hasMP = featureBits[ARM::FeatureMP];
3536ff0cc061SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
353739d628a0SDimitry Andric 
3538f785676fSDimitry Andric   if (Rn == 15) {
3539f785676fSDimitry Andric     switch (Inst.getOpcode()) {
3540f785676fSDimitry Andric     case ARM::t2LDRi12:
3541f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
3542f785676fSDimitry Andric       break;
3543f785676fSDimitry Andric     case ARM::t2LDRHi12:
3544f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
3545f785676fSDimitry Andric       break;
3546f785676fSDimitry Andric     case ARM::t2LDRSHi12:
3547f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
3548f785676fSDimitry Andric       break;
3549f785676fSDimitry Andric     case ARM::t2LDRBi12:
3550f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
3551f785676fSDimitry Andric       break;
3552f785676fSDimitry Andric     case ARM::t2LDRSBi12:
3553f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
3554f785676fSDimitry Andric       break;
3555f785676fSDimitry Andric     case ARM::t2PLDi12:
3556f785676fSDimitry Andric       Inst.setOpcode(ARM::t2PLDpci);
3557f785676fSDimitry Andric       break;
3558f785676fSDimitry Andric     case ARM::t2PLIi12:
3559f785676fSDimitry Andric       Inst.setOpcode(ARM::t2PLIpci);
3560f785676fSDimitry Andric       break;
3561f785676fSDimitry Andric     default:
3562f785676fSDimitry Andric       return MCDisassembler::Fail;
3563f785676fSDimitry Andric     }
3564f785676fSDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3565f785676fSDimitry Andric   }
3566f785676fSDimitry Andric 
3567f785676fSDimitry Andric   if (Rt == 15) {
3568f785676fSDimitry Andric     switch (Inst.getOpcode()) {
3569f785676fSDimitry Andric     case ARM::t2LDRSHi12:
3570f785676fSDimitry Andric       return MCDisassembler::Fail;
3571f785676fSDimitry Andric     case ARM::t2LDRHi12:
357239d628a0SDimitry Andric       Inst.setOpcode(ARM::t2PLDWi12);
357339d628a0SDimitry Andric       break;
357439d628a0SDimitry Andric     case ARM::t2LDRSBi12:
357539d628a0SDimitry Andric       Inst.setOpcode(ARM::t2PLIi12);
3576f785676fSDimitry Andric       break;
3577f785676fSDimitry Andric     default:
3578f785676fSDimitry Andric       break;
3579f785676fSDimitry Andric     }
3580f785676fSDimitry Andric   }
3581f785676fSDimitry Andric 
3582f785676fSDimitry Andric   switch (Inst.getOpcode()) {
3583f785676fSDimitry Andric   case ARM::t2PLDi12:
358439d628a0SDimitry Andric     break;
3585f785676fSDimitry Andric   case ARM::t2PLIi12:
358639d628a0SDimitry Andric     if (!hasV7Ops)
358739d628a0SDimitry Andric       return MCDisassembler::Fail;
358839d628a0SDimitry Andric     break;
358939d628a0SDimitry Andric   case ARM::t2PLDWi12:
359039d628a0SDimitry Andric       if (!hasV7Ops || !hasMP)
359139d628a0SDimitry Andric         return MCDisassembler::Fail;
3592f785676fSDimitry Andric       break;
3593f785676fSDimitry Andric   default:
3594f785676fSDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3595f785676fSDimitry Andric       return MCDisassembler::Fail;
3596f785676fSDimitry Andric   }
3597f785676fSDimitry Andric 
3598f785676fSDimitry Andric   if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
3599f785676fSDimitry Andric     return MCDisassembler::Fail;
3600f785676fSDimitry Andric   return S;
3601f785676fSDimitry Andric }
3602f785676fSDimitry Andric 
DecodeT2LoadT(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3603f785676fSDimitry Andric static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
3604f785676fSDimitry Andric                                 uint64_t Address, const void* Decoder) {
3605f785676fSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
3606f785676fSDimitry Andric 
3607f785676fSDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3608f785676fSDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3609f785676fSDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 8);
3610f785676fSDimitry Andric   imm |= (Rn << 9);
3611f785676fSDimitry Andric 
3612f785676fSDimitry Andric   if (Rn == 15) {
3613f785676fSDimitry Andric     switch (Inst.getOpcode()) {
3614f785676fSDimitry Andric     case ARM::t2LDRT:
3615f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
3616f785676fSDimitry Andric       break;
3617f785676fSDimitry Andric     case ARM::t2LDRBT:
3618f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
3619f785676fSDimitry Andric       break;
3620f785676fSDimitry Andric     case ARM::t2LDRHT:
3621f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
3622f785676fSDimitry Andric       break;
3623f785676fSDimitry Andric     case ARM::t2LDRSBT:
3624f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRSBpci);
3625f785676fSDimitry Andric       break;
3626f785676fSDimitry Andric     case ARM::t2LDRSHT:
3627f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
3628f785676fSDimitry Andric       break;
3629f785676fSDimitry Andric     default:
3630f785676fSDimitry Andric       return MCDisassembler::Fail;
3631f785676fSDimitry Andric     }
3632f785676fSDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3633f785676fSDimitry Andric   }
3634f785676fSDimitry Andric 
3635f785676fSDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3636f785676fSDimitry Andric     return MCDisassembler::Fail;
3637f785676fSDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3638f785676fSDimitry Andric     return MCDisassembler::Fail;
3639f785676fSDimitry Andric   return S;
3640f785676fSDimitry Andric }
3641f785676fSDimitry Andric 
DecodeT2LoadLabel(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3642f785676fSDimitry Andric static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
3643f785676fSDimitry Andric                                 uint64_t Address, const void* Decoder) {
3644f785676fSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
3645f785676fSDimitry Andric 
3646f785676fSDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3647f785676fSDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
3648f785676fSDimitry Andric   int imm = fieldFromInstruction(Insn, 0, 12);
3649f785676fSDimitry Andric 
3650ff0cc061SDimitry Andric   const FeatureBitset &featureBits =
3651ff0cc061SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3652ff0cc061SDimitry Andric 
3653ff0cc061SDimitry Andric   bool hasV7Ops = featureBits[ARM::HasV7Ops];
365439d628a0SDimitry Andric 
3655f785676fSDimitry Andric   if (Rt == 15) {
3656f785676fSDimitry Andric     switch (Inst.getOpcode()) {
3657f785676fSDimitry Andric       case ARM::t2LDRBpci:
3658f785676fSDimitry Andric       case ARM::t2LDRHpci:
3659f785676fSDimitry Andric         Inst.setOpcode(ARM::t2PLDpci);
3660f785676fSDimitry Andric         break;
3661f785676fSDimitry Andric       case ARM::t2LDRSBpci:
3662f785676fSDimitry Andric         Inst.setOpcode(ARM::t2PLIpci);
3663f785676fSDimitry Andric         break;
3664f785676fSDimitry Andric       case ARM::t2LDRSHpci:
3665f785676fSDimitry Andric         return MCDisassembler::Fail;
3666f785676fSDimitry Andric       default:
3667f785676fSDimitry Andric         break;
3668f785676fSDimitry Andric     }
3669f785676fSDimitry Andric   }
3670f785676fSDimitry Andric 
3671f785676fSDimitry Andric   switch(Inst.getOpcode()) {
3672f785676fSDimitry Andric   case ARM::t2PLDpci:
367339d628a0SDimitry Andric     break;
3674f785676fSDimitry Andric   case ARM::t2PLIpci:
367539d628a0SDimitry Andric     if (!hasV7Ops)
367639d628a0SDimitry Andric       return MCDisassembler::Fail;
3677f785676fSDimitry Andric     break;
3678f785676fSDimitry Andric   default:
3679f785676fSDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3680f785676fSDimitry Andric       return MCDisassembler::Fail;
3681f785676fSDimitry Andric   }
3682f785676fSDimitry Andric 
3683f785676fSDimitry Andric   if (!U) {
3684f785676fSDimitry Andric     // Special case for #-0.
3685f785676fSDimitry Andric     if (imm == 0)
3686f785676fSDimitry Andric       imm = INT32_MIN;
3687f785676fSDimitry Andric     else
3688f785676fSDimitry Andric       imm = -imm;
3689f785676fSDimitry Andric   }
3690ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
3691f785676fSDimitry Andric 
3692f785676fSDimitry Andric   return S;
3693f785676fSDimitry Andric }
3694f785676fSDimitry Andric 
DecodeT2Imm8S4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3695dff0c46cSDimitry Andric static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
36966122f3e6SDimitry Andric                            uint64_t Address, const void *Decoder) {
36977ae0e2c9SDimitry Andric   if (Val == 0)
3698ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(INT32_MIN));
36997ae0e2c9SDimitry Andric   else {
37006122f3e6SDimitry Andric     int imm = Val & 0xFF;
37017ae0e2c9SDimitry Andric 
37026122f3e6SDimitry Andric     if (!(Val & 0x100)) imm *= -1;
3703ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm * 4));
37047ae0e2c9SDimitry Andric   }
37056122f3e6SDimitry Andric 
37066122f3e6SDimitry Andric   return MCDisassembler::Success;
37076122f3e6SDimitry Andric }
37086122f3e6SDimitry Andric 
DecodeT2AddrModeImm8s4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3709dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
37106122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
37116122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37126122f3e6SDimitry Andric 
37137ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
37147ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 9);
37156122f3e6SDimitry Andric 
37166122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
37176122f3e6SDimitry Andric     return MCDisassembler::Fail;
37186122f3e6SDimitry Andric   if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
37196122f3e6SDimitry Andric     return MCDisassembler::Fail;
37206122f3e6SDimitry Andric 
37216122f3e6SDimitry Andric   return S;
37226122f3e6SDimitry Andric }
37236122f3e6SDimitry Andric 
DecodeT2AddrModeImm0_1020s4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3724dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
37256122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
37266122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37276122f3e6SDimitry Andric 
37287ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 8, 4);
37297ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 8);
37306122f3e6SDimitry Andric 
37316122f3e6SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
37326122f3e6SDimitry Andric     return MCDisassembler::Fail;
37336122f3e6SDimitry Andric 
3734ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
37356122f3e6SDimitry Andric 
37366122f3e6SDimitry Andric   return S;
37376122f3e6SDimitry Andric }
37386122f3e6SDimitry Andric 
DecodeT2Imm8(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3739dff0c46cSDimitry Andric static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
37406122f3e6SDimitry Andric                          uint64_t Address, const void *Decoder) {
37416122f3e6SDimitry Andric   int imm = Val & 0xFF;
37426122f3e6SDimitry Andric   if (Val == 0)
37436122f3e6SDimitry Andric     imm = INT32_MIN;
37446122f3e6SDimitry Andric   else if (!(Val & 0x100))
37456122f3e6SDimitry Andric     imm *= -1;
3746ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
37476122f3e6SDimitry Andric 
37486122f3e6SDimitry Andric   return MCDisassembler::Success;
37496122f3e6SDimitry Andric }
37506122f3e6SDimitry Andric 
DecodeT2AddrModeImm8(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3751dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
37526122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
37536122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
37546122f3e6SDimitry Andric 
37557ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 9, 4);
37567ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 9);
37576122f3e6SDimitry Andric 
3758f785676fSDimitry Andric   // Thumb stores cannot use PC as dest register.
3759f785676fSDimitry Andric   switch (Inst.getOpcode()) {
3760f785676fSDimitry Andric   case ARM::t2STRT:
3761f785676fSDimitry Andric   case ARM::t2STRBT:
3762f785676fSDimitry Andric   case ARM::t2STRHT:
3763f785676fSDimitry Andric   case ARM::t2STRi8:
3764f785676fSDimitry Andric   case ARM::t2STRHi8:
3765f785676fSDimitry Andric   case ARM::t2STRBi8:
3766f785676fSDimitry Andric     if (Rn == 15)
3767f785676fSDimitry Andric       return MCDisassembler::Fail;
3768f785676fSDimitry Andric     break;
3769f785676fSDimitry Andric   default:
3770f785676fSDimitry Andric     break;
3771f785676fSDimitry Andric   }
3772f785676fSDimitry Andric 
37736122f3e6SDimitry Andric   // Some instructions always use an additive offset.
37746122f3e6SDimitry Andric   switch (Inst.getOpcode()) {
37756122f3e6SDimitry Andric     case ARM::t2LDRT:
37766122f3e6SDimitry Andric     case ARM::t2LDRBT:
37776122f3e6SDimitry Andric     case ARM::t2LDRHT:
37786122f3e6SDimitry Andric     case ARM::t2LDRSBT:
37796122f3e6SDimitry Andric     case ARM::t2LDRSHT:
37806122f3e6SDimitry Andric     case ARM::t2STRT:
37816122f3e6SDimitry Andric     case ARM::t2STRBT:
37826122f3e6SDimitry Andric     case ARM::t2STRHT:
37836122f3e6SDimitry Andric       imm |= 0x100;
37846122f3e6SDimitry Andric       break;
37856122f3e6SDimitry Andric     default:
37866122f3e6SDimitry Andric       break;
37876122f3e6SDimitry Andric   }
37886122f3e6SDimitry Andric 
37896122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
37906122f3e6SDimitry Andric     return MCDisassembler::Fail;
37916122f3e6SDimitry Andric   if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
37926122f3e6SDimitry Andric     return MCDisassembler::Fail;
37936122f3e6SDimitry Andric 
37946122f3e6SDimitry Andric   return S;
37956122f3e6SDimitry Andric }
37966122f3e6SDimitry Andric 
DecodeT2LdStPre(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3797dff0c46cSDimitry Andric static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
37986122f3e6SDimitry Andric                                     uint64_t Address, const void *Decoder) {
37996122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
38006122f3e6SDimitry Andric 
38017ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
38027ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
38037ae0e2c9SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
38047ae0e2c9SDimitry Andric   addr |= fieldFromInstruction(Insn, 9, 1) << 8;
38056122f3e6SDimitry Andric   addr |= Rn << 9;
38067ae0e2c9SDimitry Andric   unsigned load = fieldFromInstruction(Insn, 20, 1);
38076122f3e6SDimitry Andric 
3808f785676fSDimitry Andric   if (Rn == 15) {
3809f785676fSDimitry Andric     switch (Inst.getOpcode()) {
3810f785676fSDimitry Andric     case ARM::t2LDR_PRE:
3811f785676fSDimitry Andric     case ARM::t2LDR_POST:
3812f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRpci);
3813f785676fSDimitry Andric       break;
3814f785676fSDimitry Andric     case ARM::t2LDRB_PRE:
3815f785676fSDimitry Andric     case ARM::t2LDRB_POST:
3816f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRBpci);
3817f785676fSDimitry Andric       break;
3818f785676fSDimitry Andric     case ARM::t2LDRH_PRE:
3819f785676fSDimitry Andric     case ARM::t2LDRH_POST:
3820f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRHpci);
3821f785676fSDimitry Andric       break;
3822f785676fSDimitry Andric     case ARM::t2LDRSB_PRE:
3823f785676fSDimitry Andric     case ARM::t2LDRSB_POST:
3824f785676fSDimitry Andric       if (Rt == 15)
3825f785676fSDimitry Andric         Inst.setOpcode(ARM::t2PLIpci);
3826f785676fSDimitry Andric       else
3827f785676fSDimitry Andric         Inst.setOpcode(ARM::t2LDRSBpci);
3828f785676fSDimitry Andric       break;
3829f785676fSDimitry Andric     case ARM::t2LDRSH_PRE:
3830f785676fSDimitry Andric     case ARM::t2LDRSH_POST:
3831f785676fSDimitry Andric       Inst.setOpcode(ARM::t2LDRSHpci);
3832f785676fSDimitry Andric       break;
3833f785676fSDimitry Andric     default:
3834f785676fSDimitry Andric       return MCDisassembler::Fail;
3835f785676fSDimitry Andric     }
3836f785676fSDimitry Andric     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3837f785676fSDimitry Andric   }
3838f785676fSDimitry Andric 
38396122f3e6SDimitry Andric   if (!load) {
38406122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
38416122f3e6SDimitry Andric       return MCDisassembler::Fail;
38426122f3e6SDimitry Andric   }
38436122f3e6SDimitry Andric 
3844139f7f9bSDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
38456122f3e6SDimitry Andric     return MCDisassembler::Fail;
38466122f3e6SDimitry Andric 
38476122f3e6SDimitry Andric   if (load) {
38486122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
38496122f3e6SDimitry Andric       return MCDisassembler::Fail;
38506122f3e6SDimitry Andric   }
38516122f3e6SDimitry Andric 
38526122f3e6SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
38536122f3e6SDimitry Andric     return MCDisassembler::Fail;
38546122f3e6SDimitry Andric 
38556122f3e6SDimitry Andric   return S;
38566122f3e6SDimitry Andric }
38576122f3e6SDimitry Andric 
DecodeT2AddrModeImm12(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3858dff0c46cSDimitry Andric static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
38596122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
38606122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
38616122f3e6SDimitry Andric 
38627ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 13, 4);
38637ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Val, 0, 12);
38646122f3e6SDimitry Andric 
3865f785676fSDimitry Andric   // Thumb stores cannot use PC as dest register.
3866f785676fSDimitry Andric   switch (Inst.getOpcode()) {
3867f785676fSDimitry Andric   case ARM::t2STRi12:
3868f785676fSDimitry Andric   case ARM::t2STRBi12:
3869f785676fSDimitry Andric   case ARM::t2STRHi12:
3870f785676fSDimitry Andric     if (Rn == 15)
3871f785676fSDimitry Andric       return MCDisassembler::Fail;
3872da09e106SDimitry Andric     break;
3873f785676fSDimitry Andric   default:
3874f785676fSDimitry Andric     break;
3875f785676fSDimitry Andric   }
3876f785676fSDimitry Andric 
38776122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
38786122f3e6SDimitry Andric     return MCDisassembler::Fail;
3879ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
38806122f3e6SDimitry Andric 
38816122f3e6SDimitry Andric   return S;
38826122f3e6SDimitry Andric }
38836122f3e6SDimitry Andric 
DecodeThumbAddSPImm(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)3884dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
38856122f3e6SDimitry Andric                                 uint64_t Address, const void *Decoder) {
38867ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 7);
38876122f3e6SDimitry Andric 
3888ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
3889ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(ARM::SP));
3890ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
38916122f3e6SDimitry Andric 
38926122f3e6SDimitry Andric   return MCDisassembler::Success;
38936122f3e6SDimitry Andric }
38946122f3e6SDimitry Andric 
DecodeThumbAddSPReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)3895dff0c46cSDimitry Andric static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
38966122f3e6SDimitry Andric                                 uint64_t Address, const void *Decoder) {
38976122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
38986122f3e6SDimitry Andric 
38996122f3e6SDimitry Andric   if (Inst.getOpcode() == ARM::tADDrSP) {
39007ae0e2c9SDimitry Andric     unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
39017ae0e2c9SDimitry Andric     Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
39026122f3e6SDimitry Andric 
39036122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
39046122f3e6SDimitry Andric     return MCDisassembler::Fail;
3905ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
39066122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
39076122f3e6SDimitry Andric     return MCDisassembler::Fail;
39086122f3e6SDimitry Andric   } else if (Inst.getOpcode() == ARM::tADDspr) {
39097ae0e2c9SDimitry Andric     unsigned Rm = fieldFromInstruction(Insn, 3, 4);
39106122f3e6SDimitry Andric 
3911ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
3912ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createReg(ARM::SP));
39136122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
39146122f3e6SDimitry Andric     return MCDisassembler::Fail;
39156122f3e6SDimitry Andric   }
39166122f3e6SDimitry Andric 
39176122f3e6SDimitry Andric   return S;
39186122f3e6SDimitry Andric }
39196122f3e6SDimitry Andric 
DecodeThumbCPS(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)3920dff0c46cSDimitry Andric static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
39216122f3e6SDimitry Andric                            uint64_t Address, const void *Decoder) {
39227ae0e2c9SDimitry Andric   unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
39237ae0e2c9SDimitry Andric   unsigned flags = fieldFromInstruction(Insn, 0, 3);
39246122f3e6SDimitry Andric 
3925ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(imod));
3926ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(flags));
39276122f3e6SDimitry Andric 
39286122f3e6SDimitry Andric   return MCDisassembler::Success;
39296122f3e6SDimitry Andric }
39306122f3e6SDimitry Andric 
DecodePostIdxReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3931dff0c46cSDimitry Andric static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
39326122f3e6SDimitry Andric                              uint64_t Address, const void *Decoder) {
39336122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
39347ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
39357ae0e2c9SDimitry Andric   unsigned add = fieldFromInstruction(Insn, 4, 1);
39366122f3e6SDimitry Andric 
3937dff0c46cSDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
39386122f3e6SDimitry Andric     return MCDisassembler::Fail;
3939ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(add));
39406122f3e6SDimitry Andric 
39416122f3e6SDimitry Andric   return S;
39426122f3e6SDimitry Andric }
39436122f3e6SDimitry Andric 
DecodeThumbBLXOffset(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3944dff0c46cSDimitry Andric static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
39456122f3e6SDimitry Andric                                  uint64_t Address, const void *Decoder) {
39467ae0e2c9SDimitry Andric   // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
39477ae0e2c9SDimitry Andric   // Note only one trailing zero not two.  Also the J1 and J2 values are from
39487ae0e2c9SDimitry Andric   // the encoded instruction.  So here change to I1 and I2 values via:
39497ae0e2c9SDimitry Andric   // I1 = NOT(J1 EOR S);
39507ae0e2c9SDimitry Andric   // I2 = NOT(J2 EOR S);
39517ae0e2c9SDimitry Andric   // and build the imm32 with two trailing zeros as documented:
39527ae0e2c9SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
39537ae0e2c9SDimitry Andric   unsigned S = (Val >> 23) & 1;
39547ae0e2c9SDimitry Andric   unsigned J1 = (Val >> 22) & 1;
39557ae0e2c9SDimitry Andric   unsigned J2 = (Val >> 21) & 1;
39567ae0e2c9SDimitry Andric   unsigned I1 = !(J1 ^ S);
39577ae0e2c9SDimitry Andric   unsigned I2 = !(J2 ^ S);
39587ae0e2c9SDimitry Andric   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
39597ae0e2c9SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
39607ae0e2c9SDimitry Andric 
39616122f3e6SDimitry Andric   if (!tryAddingSymbolicOperand(Address,
39627ae0e2c9SDimitry Andric                                 (Address & ~2u) + imm32 + 4,
39636122f3e6SDimitry Andric                                 true, 4, Inst, Decoder))
3964ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
39656122f3e6SDimitry Andric   return MCDisassembler::Success;
39666122f3e6SDimitry Andric }
39676122f3e6SDimitry Andric 
DecodeCoprocessor(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3968dff0c46cSDimitry Andric static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
39696122f3e6SDimitry Andric                               uint64_t Address, const void *Decoder) {
39706122f3e6SDimitry Andric   if (Val == 0xA || Val == 0xB)
39716122f3e6SDimitry Andric     return MCDisassembler::Fail;
39726122f3e6SDimitry Andric 
3973ff0cc061SDimitry Andric   const FeatureBitset &featureBits =
3974ff0cc061SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3975ff0cc061SDimitry Andric 
3976ff0cc061SDimitry Andric   if (featureBits[ARM::HasV8Ops] && !(Val == 14 || Val == 15))
3977f785676fSDimitry Andric     return MCDisassembler::Fail;
3978f785676fSDimitry Andric 
3979ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
39806122f3e6SDimitry Andric   return MCDisassembler::Success;
39816122f3e6SDimitry Andric }
39826122f3e6SDimitry Andric 
39836122f3e6SDimitry Andric static DecodeStatus
DecodeThumbTableBranch(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3984dff0c46cSDimitry Andric DecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
39856122f3e6SDimitry Andric                        uint64_t Address, const void *Decoder) {
39866122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
39876122f3e6SDimitry Andric 
39887ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
39897ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
39906122f3e6SDimitry Andric 
39916122f3e6SDimitry Andric   if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
39926122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
39936122f3e6SDimitry Andric     return MCDisassembler::Fail;
39946122f3e6SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
39956122f3e6SDimitry Andric     return MCDisassembler::Fail;
39966122f3e6SDimitry Andric   return S;
39976122f3e6SDimitry Andric }
39986122f3e6SDimitry Andric 
39996122f3e6SDimitry Andric static DecodeStatus
DecodeThumb2BCCInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4000dff0c46cSDimitry Andric DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
40016122f3e6SDimitry Andric                            uint64_t Address, const void *Decoder) {
40026122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
40036122f3e6SDimitry Andric 
40047ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 22, 4);
40056122f3e6SDimitry Andric   if (pred == 0xE || pred == 0xF) {
40067ae0e2c9SDimitry Andric     unsigned opc = fieldFromInstruction(Insn, 4, 28);
40076122f3e6SDimitry Andric     switch (opc) {
40086122f3e6SDimitry Andric       default:
40096122f3e6SDimitry Andric         return MCDisassembler::Fail;
40106122f3e6SDimitry Andric       case 0xf3bf8f4:
40116122f3e6SDimitry Andric         Inst.setOpcode(ARM::t2DSB);
40126122f3e6SDimitry Andric         break;
40136122f3e6SDimitry Andric       case 0xf3bf8f5:
40146122f3e6SDimitry Andric         Inst.setOpcode(ARM::t2DMB);
40156122f3e6SDimitry Andric         break;
40166122f3e6SDimitry Andric       case 0xf3bf8f6:
40176122f3e6SDimitry Andric         Inst.setOpcode(ARM::t2ISB);
40186122f3e6SDimitry Andric         break;
40196122f3e6SDimitry Andric     }
40206122f3e6SDimitry Andric 
40217ae0e2c9SDimitry Andric     unsigned imm = fieldFromInstruction(Insn, 0, 4);
40226122f3e6SDimitry Andric     return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
40236122f3e6SDimitry Andric   }
40246122f3e6SDimitry Andric 
40257ae0e2c9SDimitry Andric   unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
40267ae0e2c9SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
40277ae0e2c9SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
40287ae0e2c9SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
40297ae0e2c9SDimitry Andric   brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
40306122f3e6SDimitry Andric 
40316122f3e6SDimitry Andric   if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
40326122f3e6SDimitry Andric     return MCDisassembler::Fail;
40336122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
40346122f3e6SDimitry Andric     return MCDisassembler::Fail;
40356122f3e6SDimitry Andric 
40366122f3e6SDimitry Andric   return S;
40376122f3e6SDimitry Andric }
40386122f3e6SDimitry Andric 
40396122f3e6SDimitry Andric // Decode a shifted immediate operand.  These basically consist
40406122f3e6SDimitry Andric // of an 8-bit value, and a 4-bit directive that specifies either
40416122f3e6SDimitry Andric // a splat operation or a rotation.
DecodeT2SOImm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4042dff0c46cSDimitry Andric static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
40436122f3e6SDimitry Andric                           uint64_t Address, const void *Decoder) {
40447ae0e2c9SDimitry Andric   unsigned ctrl = fieldFromInstruction(Val, 10, 2);
40456122f3e6SDimitry Andric   if (ctrl == 0) {
40467ae0e2c9SDimitry Andric     unsigned byte = fieldFromInstruction(Val, 8, 2);
40477ae0e2c9SDimitry Andric     unsigned imm = fieldFromInstruction(Val, 0, 8);
40486122f3e6SDimitry Andric     switch (byte) {
40496122f3e6SDimitry Andric       case 0:
4050ff0cc061SDimitry Andric         Inst.addOperand(MCOperand::createImm(imm));
40516122f3e6SDimitry Andric         break;
40526122f3e6SDimitry Andric       case 1:
4053ff0cc061SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 16) | imm));
40546122f3e6SDimitry Andric         break;
40556122f3e6SDimitry Andric       case 2:
4056ff0cc061SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 8)));
40576122f3e6SDimitry Andric         break;
40586122f3e6SDimitry Andric       case 3:
4059ff0cc061SDimitry Andric         Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 16) |
40606122f3e6SDimitry Andric                                              (imm << 8)  |  imm));
40616122f3e6SDimitry Andric         break;
40626122f3e6SDimitry Andric     }
40636122f3e6SDimitry Andric   } else {
40647ae0e2c9SDimitry Andric     unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
40657ae0e2c9SDimitry Andric     unsigned rot = fieldFromInstruction(Val, 7, 5);
40666122f3e6SDimitry Andric     unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
4067ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
40686122f3e6SDimitry Andric   }
40696122f3e6SDimitry Andric 
40706122f3e6SDimitry Andric   return MCDisassembler::Success;
40716122f3e6SDimitry Andric }
40726122f3e6SDimitry Andric 
40736122f3e6SDimitry Andric static DecodeStatus
DecodeThumbBCCTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4074dff0c46cSDimitry Andric DecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
40756122f3e6SDimitry Andric                             uint64_t Address, const void *Decoder) {
40767ae0e2c9SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
4077dff0c46cSDimitry Andric                                 true, 2, Inst, Decoder))
4078ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(SignExtend32<9>(Val << 1)));
40796122f3e6SDimitry Andric   return MCDisassembler::Success;
40806122f3e6SDimitry Andric }
40816122f3e6SDimitry Andric 
DecodeThumbBLTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4082dff0c46cSDimitry Andric static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
40837a7e6055SDimitry Andric                                                uint64_t Address,
40847a7e6055SDimitry Andric                                                const void *Decoder) {
40857ae0e2c9SDimitry Andric   // Val is passed in as S:J1:J2:imm10:imm11
40867ae0e2c9SDimitry Andric   // Note no trailing zero after imm11.  Also the J1 and J2 values are from
40877ae0e2c9SDimitry Andric   // the encoded instruction.  So here change to I1 and I2 values via:
40887ae0e2c9SDimitry Andric   // I1 = NOT(J1 EOR S);
40897ae0e2c9SDimitry Andric   // I2 = NOT(J2 EOR S);
40907ae0e2c9SDimitry Andric   // and build the imm32 with one trailing zero as documented:
40917ae0e2c9SDimitry Andric   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
40927ae0e2c9SDimitry Andric   unsigned S = (Val >> 23) & 1;
40937ae0e2c9SDimitry Andric   unsigned J1 = (Val >> 22) & 1;
40947ae0e2c9SDimitry Andric   unsigned J2 = (Val >> 21) & 1;
40957ae0e2c9SDimitry Andric   unsigned I1 = !(J1 ^ S);
40967ae0e2c9SDimitry Andric   unsigned I2 = !(J2 ^ S);
40977ae0e2c9SDimitry Andric   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
40987ae0e2c9SDimitry Andric   int imm32 = SignExtend32<25>(tmp << 1);
40997ae0e2c9SDimitry Andric 
41007ae0e2c9SDimitry Andric   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
4101dff0c46cSDimitry Andric                                 true, 4, Inst, Decoder))
4102ff0cc061SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm32));
41036122f3e6SDimitry Andric   return MCDisassembler::Success;
41046122f3e6SDimitry Andric }
41056122f3e6SDimitry Andric 
DecodeMemBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4106dff0c46cSDimitry Andric static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
41076122f3e6SDimitry Andric                                    uint64_t Address, const void *Decoder) {
41087ae0e2c9SDimitry Andric   if (Val & ~0xf)
41096122f3e6SDimitry Andric     return MCDisassembler::Fail;
41106122f3e6SDimitry Andric 
4111ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
41126122f3e6SDimitry Andric   return MCDisassembler::Success;
41136122f3e6SDimitry Andric }
41146122f3e6SDimitry Andric 
DecodeInstSyncBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4115f785676fSDimitry Andric static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
4116f785676fSDimitry Andric                                         uint64_t Address, const void *Decoder) {
4117f785676fSDimitry Andric   if (Val & ~0xf)
4118f785676fSDimitry Andric     return MCDisassembler::Fail;
4119f785676fSDimitry Andric 
4120ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
4121f785676fSDimitry Andric   return MCDisassembler::Success;
4122f785676fSDimitry Andric }
4123f785676fSDimitry Andric 
DecodeMSRMask(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4124dff0c46cSDimitry Andric static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
41256122f3e6SDimitry Andric                           uint64_t Address, const void *Decoder) {
412639d628a0SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
4127ff0cc061SDimitry Andric   const FeatureBitset &FeatureBits =
4128ff0cc061SDimitry Andric     ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
4129ff0cc061SDimitry Andric 
4130ff0cc061SDimitry Andric   if (FeatureBits[ARM::FeatureMClass]) {
413139d628a0SDimitry Andric     unsigned ValLow = Val & 0xff;
413239d628a0SDimitry Andric 
413339d628a0SDimitry Andric     // Validate the SYSm value first.
413439d628a0SDimitry Andric     switch (ValLow) {
413539d628a0SDimitry Andric     case  0: // apsr
413639d628a0SDimitry Andric     case  1: // iapsr
413739d628a0SDimitry Andric     case  2: // eapsr
413839d628a0SDimitry Andric     case  3: // xpsr
413939d628a0SDimitry Andric     case  5: // ipsr
414039d628a0SDimitry Andric     case  6: // epsr
414139d628a0SDimitry Andric     case  7: // iepsr
414239d628a0SDimitry Andric     case  8: // msp
414339d628a0SDimitry Andric     case  9: // psp
414439d628a0SDimitry Andric     case 16: // primask
414539d628a0SDimitry Andric     case 20: // control
414639d628a0SDimitry Andric       break;
414739d628a0SDimitry Andric     case 17: // basepri
414839d628a0SDimitry Andric     case 18: // basepri_max
414939d628a0SDimitry Andric     case 19: // faultmask
4150ff0cc061SDimitry Andric       if (!(FeatureBits[ARM::HasV7Ops]))
415139d628a0SDimitry Andric         // Values basepri, basepri_max and faultmask are only valid for v7m.
415239d628a0SDimitry Andric         return MCDisassembler::Fail;
415339d628a0SDimitry Andric       break;
41543ca95b02SDimitry Andric     case 0x8a: // msplim_ns
41553ca95b02SDimitry Andric     case 0x8b: // psplim_ns
41563ca95b02SDimitry Andric     case 0x91: // basepri_ns
41573ca95b02SDimitry Andric     case 0x93: // faultmask_ns
41583ca95b02SDimitry Andric       if (!(FeatureBits[ARM::HasV8MMainlineOps]))
41593ca95b02SDimitry Andric         return MCDisassembler::Fail;
4160d88c1a5aSDimitry Andric       LLVM_FALLTHROUGH;
41613ca95b02SDimitry Andric     case 10:   // msplim
41623ca95b02SDimitry Andric     case 11:   // psplim
41633ca95b02SDimitry Andric     case 0x88: // msp_ns
41643ca95b02SDimitry Andric     case 0x89: // psp_ns
41653ca95b02SDimitry Andric     case 0x90: // primask_ns
41663ca95b02SDimitry Andric     case 0x94: // control_ns
41673ca95b02SDimitry Andric     case 0x98: // sp_ns
41683ca95b02SDimitry Andric       if (!(FeatureBits[ARM::Feature8MSecExt]))
41693ca95b02SDimitry Andric         return MCDisassembler::Fail;
41703ca95b02SDimitry Andric       break;
417139d628a0SDimitry Andric     default:
4172*4ba319b5SDimitry Andric       // Architecturally defined as unpredictable
4173*4ba319b5SDimitry Andric       S = MCDisassembler::SoftFail;
4174*4ba319b5SDimitry Andric       break;
417539d628a0SDimitry Andric     }
417639d628a0SDimitry Andric 
417739d628a0SDimitry Andric     if (Inst.getOpcode() == ARM::t2MSR_M) {
417839d628a0SDimitry Andric       unsigned Mask = fieldFromInstruction(Val, 10, 2);
4179ff0cc061SDimitry Andric       if (!(FeatureBits[ARM::HasV7Ops])) {
418039d628a0SDimitry Andric         // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
418139d628a0SDimitry Andric         // unpredictable.
418239d628a0SDimitry Andric         if (Mask != 2)
418339d628a0SDimitry Andric           S = MCDisassembler::SoftFail;
418439d628a0SDimitry Andric       }
418539d628a0SDimitry Andric       else {
418639d628a0SDimitry Andric         // The ARMv7-M architecture stores an additional 2-bit mask value in
418739d628a0SDimitry Andric         // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
418839d628a0SDimitry Andric         // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
418939d628a0SDimitry Andric         // the NZCVQ bits should be moved by the instruction. Bit mask{0}
419039d628a0SDimitry Andric         // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
419139d628a0SDimitry Andric         // only if the processor includes the DSP extension.
419239d628a0SDimitry Andric         if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
41937d523365SDimitry Andric             (!(FeatureBits[ARM::FeatureDSP]) && (Mask & 1)))
419439d628a0SDimitry Andric           S = MCDisassembler::SoftFail;
419539d628a0SDimitry Andric       }
419639d628a0SDimitry Andric     }
419739d628a0SDimitry Andric   } else {
419839d628a0SDimitry Andric     // A/R class
419939d628a0SDimitry Andric     if (Val == 0)
420039d628a0SDimitry Andric       return MCDisassembler::Fail;
420139d628a0SDimitry Andric   }
4202ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
420339d628a0SDimitry Andric   return S;
420439d628a0SDimitry Andric }
420539d628a0SDimitry Andric 
DecodeBankedReg(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)420639d628a0SDimitry Andric static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
420739d628a0SDimitry Andric                                     uint64_t Address, const void *Decoder) {
420839d628a0SDimitry Andric   unsigned R = fieldFromInstruction(Val, 5, 1);
420939d628a0SDimitry Andric   unsigned SysM = fieldFromInstruction(Val, 0, 5);
421039d628a0SDimitry Andric 
421139d628a0SDimitry Andric   // The table of encodings for these banked registers comes from B9.2.3 of the
421239d628a0SDimitry Andric   // ARM ARM. There are patterns, but nothing regular enough to make this logic
421339d628a0SDimitry Andric   // neater. So by fiat, these values are UNPREDICTABLE:
4214*4ba319b5SDimitry Andric   if (!ARMBankedReg::lookupBankedRegByEncoding((R << 5) | SysM))
4215*4ba319b5SDimitry Andric     return MCDisassembler::Fail;
421639d628a0SDimitry Andric 
4217ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
42186122f3e6SDimitry Andric   return MCDisassembler::Success;
42196122f3e6SDimitry Andric }
42206122f3e6SDimitry Andric 
DecodeDoubleRegLoad(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4221dff0c46cSDimitry Andric static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
42226122f3e6SDimitry Andric                                         uint64_t Address, const void *Decoder) {
42236122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
42246122f3e6SDimitry Andric 
42257ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
42267ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
42277ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
42286122f3e6SDimitry Andric 
4229f785676fSDimitry Andric   if (Rn == 0xF)
4230f785676fSDimitry Andric     S = MCDisassembler::SoftFail;
42316122f3e6SDimitry Andric 
4232f785676fSDimitry Andric   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
42336122f3e6SDimitry Andric     return MCDisassembler::Fail;
42346122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
42356122f3e6SDimitry Andric     return MCDisassembler::Fail;
42366122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
42376122f3e6SDimitry Andric     return MCDisassembler::Fail;
42386122f3e6SDimitry Andric 
42396122f3e6SDimitry Andric   return S;
42406122f3e6SDimitry Andric }
42416122f3e6SDimitry Andric 
DecodeDoubleRegStore(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4242dff0c46cSDimitry Andric static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
42437a7e6055SDimitry Andric                                          uint64_t Address,
42447a7e6055SDimitry Andric                                          const void *Decoder) {
42456122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
42466122f3e6SDimitry Andric 
42477ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
42487ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
42497ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
42507ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
42516122f3e6SDimitry Andric 
4252284c1978SDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
42536122f3e6SDimitry Andric     return MCDisassembler::Fail;
42546122f3e6SDimitry Andric 
4255f785676fSDimitry Andric   if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
4256f785676fSDimitry Andric     S = MCDisassembler::SoftFail;
42576122f3e6SDimitry Andric 
4258f785676fSDimitry Andric   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
42596122f3e6SDimitry Andric     return MCDisassembler::Fail;
42606122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
42616122f3e6SDimitry Andric     return MCDisassembler::Fail;
42626122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
42636122f3e6SDimitry Andric     return MCDisassembler::Fail;
42646122f3e6SDimitry Andric 
42656122f3e6SDimitry Andric   return S;
42666122f3e6SDimitry Andric }
42676122f3e6SDimitry Andric 
DecodeLDRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4268dff0c46cSDimitry Andric static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
42696122f3e6SDimitry Andric                             uint64_t Address, const void *Decoder) {
42706122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
42716122f3e6SDimitry Andric 
42727ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
42737ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
42747ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
42757ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
42767ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
42777ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
42786122f3e6SDimitry Andric 
42796122f3e6SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
42806122f3e6SDimitry Andric 
42816122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
42826122f3e6SDimitry Andric     return MCDisassembler::Fail;
42836122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
42846122f3e6SDimitry Andric     return MCDisassembler::Fail;
42856122f3e6SDimitry Andric   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
42866122f3e6SDimitry Andric     return MCDisassembler::Fail;
42876122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
42886122f3e6SDimitry Andric     return MCDisassembler::Fail;
42896122f3e6SDimitry Andric 
42906122f3e6SDimitry Andric   return S;
42916122f3e6SDimitry Andric }
42926122f3e6SDimitry Andric 
DecodeLDRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4293dff0c46cSDimitry Andric static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
42946122f3e6SDimitry Andric                             uint64_t Address, const void *Decoder) {
42956122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
42966122f3e6SDimitry Andric 
42977ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
42987ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
42997ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
43007ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
43017ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
43027ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
43037ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
43046122f3e6SDimitry Andric 
43056122f3e6SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
43066122f3e6SDimitry Andric   if (Rm == 0xF) S = MCDisassembler::SoftFail;
43076122f3e6SDimitry Andric 
43086122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
43096122f3e6SDimitry Andric     return MCDisassembler::Fail;
43106122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
43116122f3e6SDimitry Andric     return MCDisassembler::Fail;
43126122f3e6SDimitry Andric   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
43136122f3e6SDimitry Andric     return MCDisassembler::Fail;
43146122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
43156122f3e6SDimitry Andric     return MCDisassembler::Fail;
43166122f3e6SDimitry Andric 
43176122f3e6SDimitry Andric   return S;
43186122f3e6SDimitry Andric }
43196122f3e6SDimitry Andric 
DecodeSTRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4320dff0c46cSDimitry Andric static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
43216122f3e6SDimitry Andric                             uint64_t Address, const void *Decoder) {
43226122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
43236122f3e6SDimitry Andric 
43247ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
43257ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
43267ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
43277ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
43287ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
43297ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
43306122f3e6SDimitry Andric 
43316122f3e6SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
43326122f3e6SDimitry Andric 
43336122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
43346122f3e6SDimitry Andric     return MCDisassembler::Fail;
43356122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
43366122f3e6SDimitry Andric     return MCDisassembler::Fail;
43376122f3e6SDimitry Andric   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
43386122f3e6SDimitry Andric     return MCDisassembler::Fail;
43396122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
43406122f3e6SDimitry Andric     return MCDisassembler::Fail;
43416122f3e6SDimitry Andric 
43426122f3e6SDimitry Andric   return S;
43436122f3e6SDimitry Andric }
43446122f3e6SDimitry Andric 
DecodeSTRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4345dff0c46cSDimitry Andric static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
43466122f3e6SDimitry Andric                             uint64_t Address, const void *Decoder) {
43476122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
43486122f3e6SDimitry Andric 
43497ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
43507ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
43517ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 0, 12);
43527ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
43537ae0e2c9SDimitry Andric   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
43547ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
43556122f3e6SDimitry Andric 
43566122f3e6SDimitry Andric   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
43576122f3e6SDimitry Andric 
43586122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
43596122f3e6SDimitry Andric     return MCDisassembler::Fail;
43606122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
43616122f3e6SDimitry Andric     return MCDisassembler::Fail;
43626122f3e6SDimitry Andric   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
43636122f3e6SDimitry Andric     return MCDisassembler::Fail;
43646122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
43656122f3e6SDimitry Andric     return MCDisassembler::Fail;
43666122f3e6SDimitry Andric 
43676122f3e6SDimitry Andric   return S;
43686122f3e6SDimitry Andric }
43696122f3e6SDimitry Andric 
DecodeVLD1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4370dff0c46cSDimitry Andric static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
43716122f3e6SDimitry Andric                          uint64_t Address, const void *Decoder) {
43726122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
43736122f3e6SDimitry Andric 
43747ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
43757ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
43767ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
43777ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
43787ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
43796122f3e6SDimitry Andric 
43806122f3e6SDimitry Andric   unsigned align = 0;
43816122f3e6SDimitry Andric   unsigned index = 0;
43826122f3e6SDimitry Andric   switch (size) {
43836122f3e6SDimitry Andric     default:
43846122f3e6SDimitry Andric       return MCDisassembler::Fail;
43856122f3e6SDimitry Andric     case 0:
43867ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
43876122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
43887ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
43896122f3e6SDimitry Andric       break;
43906122f3e6SDimitry Andric     case 1:
43917ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
43926122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
43937ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
43947ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
43956122f3e6SDimitry Andric         align = 2;
43966122f3e6SDimitry Andric       break;
43976122f3e6SDimitry Andric     case 2:
43987ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
43996122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
44007ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
44013861d79fSDimitry Andric 
44023861d79fSDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
44033861d79fSDimitry Andric         case 0 :
44043861d79fSDimitry Andric           align = 0; break;
44053861d79fSDimitry Andric         case 3:
44063861d79fSDimitry Andric           align = 4; break;
44073861d79fSDimitry Andric         default:
44083861d79fSDimitry Andric           return MCDisassembler::Fail;
44093861d79fSDimitry Andric       }
44103861d79fSDimitry Andric       break;
44116122f3e6SDimitry Andric   }
44126122f3e6SDimitry Andric 
44136122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
44146122f3e6SDimitry Andric     return MCDisassembler::Fail;
44156122f3e6SDimitry Andric   if (Rm != 0xF) { // Writeback
44166122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
44176122f3e6SDimitry Andric       return MCDisassembler::Fail;
44186122f3e6SDimitry Andric   }
44196122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
44206122f3e6SDimitry Andric     return MCDisassembler::Fail;
4421ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
44226122f3e6SDimitry Andric   if (Rm != 0xF) {
44236122f3e6SDimitry Andric     if (Rm != 0xD) {
44246122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
44256122f3e6SDimitry Andric         return MCDisassembler::Fail;
44266122f3e6SDimitry Andric     } else
4427ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
44286122f3e6SDimitry Andric   }
44296122f3e6SDimitry Andric 
44306122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
44316122f3e6SDimitry Andric     return MCDisassembler::Fail;
4432ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
44336122f3e6SDimitry Andric 
44346122f3e6SDimitry Andric   return S;
44356122f3e6SDimitry Andric }
44366122f3e6SDimitry Andric 
DecodeVST1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4437dff0c46cSDimitry Andric static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
44386122f3e6SDimitry Andric                          uint64_t Address, const void *Decoder) {
44396122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
44406122f3e6SDimitry Andric 
44417ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
44427ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
44437ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
44447ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
44457ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
44466122f3e6SDimitry Andric 
44476122f3e6SDimitry Andric   unsigned align = 0;
44486122f3e6SDimitry Andric   unsigned index = 0;
44496122f3e6SDimitry Andric   switch (size) {
44506122f3e6SDimitry Andric     default:
44516122f3e6SDimitry Andric       return MCDisassembler::Fail;
44526122f3e6SDimitry Andric     case 0:
44537ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
44546122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
44557ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
44566122f3e6SDimitry Andric       break;
44576122f3e6SDimitry Andric     case 1:
44587ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
44596122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
44607ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
44617ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
44626122f3e6SDimitry Andric         align = 2;
44636122f3e6SDimitry Andric       break;
44646122f3e6SDimitry Andric     case 2:
44657ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
44666122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
44677ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
44683861d79fSDimitry Andric 
44693861d79fSDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
44703861d79fSDimitry Andric         case 0:
44713861d79fSDimitry Andric           align = 0; break;
44723861d79fSDimitry Andric         case 3:
44733861d79fSDimitry Andric           align = 4; break;
44743861d79fSDimitry Andric         default:
44753861d79fSDimitry Andric           return MCDisassembler::Fail;
44763861d79fSDimitry Andric       }
44773861d79fSDimitry Andric       break;
44786122f3e6SDimitry Andric   }
44796122f3e6SDimitry Andric 
44806122f3e6SDimitry Andric   if (Rm != 0xF) { // Writeback
44816122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
44826122f3e6SDimitry Andric     return MCDisassembler::Fail;
44836122f3e6SDimitry Andric   }
44846122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
44856122f3e6SDimitry Andric     return MCDisassembler::Fail;
4486ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
44876122f3e6SDimitry Andric   if (Rm != 0xF) {
44886122f3e6SDimitry Andric     if (Rm != 0xD) {
44896122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
44906122f3e6SDimitry Andric     return MCDisassembler::Fail;
44916122f3e6SDimitry Andric     } else
4492ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
44936122f3e6SDimitry Andric   }
44946122f3e6SDimitry Andric 
44956122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
44966122f3e6SDimitry Andric     return MCDisassembler::Fail;
4497ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
44986122f3e6SDimitry Andric 
44996122f3e6SDimitry Andric   return S;
45006122f3e6SDimitry Andric }
45016122f3e6SDimitry Andric 
DecodeVLD2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4502dff0c46cSDimitry Andric static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
45036122f3e6SDimitry Andric                          uint64_t Address, const void *Decoder) {
45046122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45056122f3e6SDimitry Andric 
45067ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
45077ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
45087ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
45097ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
45107ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
45116122f3e6SDimitry Andric 
45126122f3e6SDimitry Andric   unsigned align = 0;
45136122f3e6SDimitry Andric   unsigned index = 0;
45146122f3e6SDimitry Andric   unsigned inc = 1;
45156122f3e6SDimitry Andric   switch (size) {
45166122f3e6SDimitry Andric     default:
45176122f3e6SDimitry Andric       return MCDisassembler::Fail;
45186122f3e6SDimitry Andric     case 0:
45197ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
45207ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
45216122f3e6SDimitry Andric         align = 2;
45226122f3e6SDimitry Andric       break;
45236122f3e6SDimitry Andric     case 1:
45247ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
45257ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
45266122f3e6SDimitry Andric         align = 4;
45277ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
45286122f3e6SDimitry Andric         inc = 2;
45296122f3e6SDimitry Andric       break;
45306122f3e6SDimitry Andric     case 2:
45317ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
45326122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
45337ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
45347ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1) != 0)
45356122f3e6SDimitry Andric         align = 8;
45367ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
45376122f3e6SDimitry Andric         inc = 2;
45386122f3e6SDimitry Andric       break;
45396122f3e6SDimitry Andric   }
45406122f3e6SDimitry Andric 
45416122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
45426122f3e6SDimitry Andric     return MCDisassembler::Fail;
45436122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
45446122f3e6SDimitry Andric     return MCDisassembler::Fail;
45456122f3e6SDimitry Andric   if (Rm != 0xF) { // Writeback
45466122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
45476122f3e6SDimitry Andric       return MCDisassembler::Fail;
45486122f3e6SDimitry Andric   }
45496122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
45506122f3e6SDimitry Andric     return MCDisassembler::Fail;
4551ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
45526122f3e6SDimitry Andric   if (Rm != 0xF) {
45536122f3e6SDimitry Andric     if (Rm != 0xD) {
45546122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
45556122f3e6SDimitry Andric         return MCDisassembler::Fail;
45566122f3e6SDimitry Andric     } else
4557ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
45586122f3e6SDimitry Andric   }
45596122f3e6SDimitry Andric 
45606122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
45616122f3e6SDimitry Andric     return MCDisassembler::Fail;
45626122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
45636122f3e6SDimitry Andric     return MCDisassembler::Fail;
4564ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
45656122f3e6SDimitry Andric 
45666122f3e6SDimitry Andric   return S;
45676122f3e6SDimitry Andric }
45686122f3e6SDimitry Andric 
DecodeVST2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4569dff0c46cSDimitry Andric static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
45706122f3e6SDimitry Andric                          uint64_t Address, const void *Decoder) {
45716122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
45726122f3e6SDimitry Andric 
45737ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
45747ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
45757ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
45767ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
45777ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
45786122f3e6SDimitry Andric 
45796122f3e6SDimitry Andric   unsigned align = 0;
45806122f3e6SDimitry Andric   unsigned index = 0;
45816122f3e6SDimitry Andric   unsigned inc = 1;
45826122f3e6SDimitry Andric   switch (size) {
45836122f3e6SDimitry Andric     default:
45846122f3e6SDimitry Andric       return MCDisassembler::Fail;
45856122f3e6SDimitry Andric     case 0:
45867ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
45877ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
45886122f3e6SDimitry Andric         align = 2;
45896122f3e6SDimitry Andric       break;
45906122f3e6SDimitry Andric     case 1:
45917ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
45927ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
45936122f3e6SDimitry Andric         align = 4;
45947ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
45956122f3e6SDimitry Andric         inc = 2;
45966122f3e6SDimitry Andric       break;
45976122f3e6SDimitry Andric     case 2:
45987ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
45996122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
46007ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
46017ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1) != 0)
46026122f3e6SDimitry Andric         align = 8;
46037ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
46046122f3e6SDimitry Andric         inc = 2;
46056122f3e6SDimitry Andric       break;
46066122f3e6SDimitry Andric   }
46076122f3e6SDimitry Andric 
46086122f3e6SDimitry Andric   if (Rm != 0xF) { // Writeback
46096122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46106122f3e6SDimitry Andric       return MCDisassembler::Fail;
46116122f3e6SDimitry Andric   }
46126122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46136122f3e6SDimitry Andric     return MCDisassembler::Fail;
4614ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
46156122f3e6SDimitry Andric   if (Rm != 0xF) {
46166122f3e6SDimitry Andric     if (Rm != 0xD) {
46176122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
46186122f3e6SDimitry Andric         return MCDisassembler::Fail;
46196122f3e6SDimitry Andric     } else
4620ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
46216122f3e6SDimitry Andric   }
46226122f3e6SDimitry Andric 
46236122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
46246122f3e6SDimitry Andric     return MCDisassembler::Fail;
46256122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
46266122f3e6SDimitry Andric     return MCDisassembler::Fail;
4627ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
46286122f3e6SDimitry Andric 
46296122f3e6SDimitry Andric   return S;
46306122f3e6SDimitry Andric }
46316122f3e6SDimitry Andric 
DecodeVLD3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4632dff0c46cSDimitry Andric static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
46336122f3e6SDimitry Andric                          uint64_t Address, const void *Decoder) {
46346122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
46356122f3e6SDimitry Andric 
46367ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
46377ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
46387ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
46397ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
46407ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
46416122f3e6SDimitry Andric 
46426122f3e6SDimitry Andric   unsigned align = 0;
46436122f3e6SDimitry Andric   unsigned index = 0;
46446122f3e6SDimitry Andric   unsigned inc = 1;
46456122f3e6SDimitry Andric   switch (size) {
46466122f3e6SDimitry Andric     default:
46476122f3e6SDimitry Andric       return MCDisassembler::Fail;
46486122f3e6SDimitry Andric     case 0:
46497ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
46506122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
46517ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
46526122f3e6SDimitry Andric       break;
46536122f3e6SDimitry Andric     case 1:
46547ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
46556122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
46567ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
46577ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
46586122f3e6SDimitry Andric         inc = 2;
46596122f3e6SDimitry Andric       break;
46606122f3e6SDimitry Andric     case 2:
46617ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 2))
46626122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
46637ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
46647ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
46656122f3e6SDimitry Andric         inc = 2;
46666122f3e6SDimitry Andric       break;
46676122f3e6SDimitry Andric   }
46686122f3e6SDimitry Andric 
46696122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
46706122f3e6SDimitry Andric     return MCDisassembler::Fail;
46716122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
46726122f3e6SDimitry Andric     return MCDisassembler::Fail;
46736122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
46746122f3e6SDimitry Andric     return MCDisassembler::Fail;
46756122f3e6SDimitry Andric 
46766122f3e6SDimitry Andric   if (Rm != 0xF) { // Writeback
46776122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46786122f3e6SDimitry Andric     return MCDisassembler::Fail;
46796122f3e6SDimitry Andric   }
46806122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
46816122f3e6SDimitry Andric     return MCDisassembler::Fail;
4682ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
46836122f3e6SDimitry Andric   if (Rm != 0xF) {
46846122f3e6SDimitry Andric     if (Rm != 0xD) {
46856122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
46866122f3e6SDimitry Andric     return MCDisassembler::Fail;
46876122f3e6SDimitry Andric     } else
4688ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
46896122f3e6SDimitry Andric   }
46906122f3e6SDimitry Andric 
46916122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
46926122f3e6SDimitry Andric     return MCDisassembler::Fail;
46936122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
46946122f3e6SDimitry Andric     return MCDisassembler::Fail;
46956122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
46966122f3e6SDimitry Andric     return MCDisassembler::Fail;
4697ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
46986122f3e6SDimitry Andric 
46996122f3e6SDimitry Andric   return S;
47006122f3e6SDimitry Andric }
47016122f3e6SDimitry Andric 
DecodeVST3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4702dff0c46cSDimitry Andric static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
47036122f3e6SDimitry Andric                          uint64_t Address, const void *Decoder) {
47046122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47056122f3e6SDimitry Andric 
47067ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
47077ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
47087ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
47097ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
47107ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
47116122f3e6SDimitry Andric 
47126122f3e6SDimitry Andric   unsigned align = 0;
47136122f3e6SDimitry Andric   unsigned index = 0;
47146122f3e6SDimitry Andric   unsigned inc = 1;
47156122f3e6SDimitry Andric   switch (size) {
47166122f3e6SDimitry Andric     default:
47176122f3e6SDimitry Andric       return MCDisassembler::Fail;
47186122f3e6SDimitry Andric     case 0:
47197ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
47206122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
47217ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
47226122f3e6SDimitry Andric       break;
47236122f3e6SDimitry Andric     case 1:
47247ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
47256122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
47267ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
47277ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
47286122f3e6SDimitry Andric         inc = 2;
47296122f3e6SDimitry Andric       break;
47306122f3e6SDimitry Andric     case 2:
47317ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 2))
47326122f3e6SDimitry Andric         return MCDisassembler::Fail; // UNDEFINED
47337ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
47347ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
47356122f3e6SDimitry Andric         inc = 2;
47366122f3e6SDimitry Andric       break;
47376122f3e6SDimitry Andric   }
47386122f3e6SDimitry Andric 
47396122f3e6SDimitry Andric   if (Rm != 0xF) { // Writeback
47406122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
47416122f3e6SDimitry Andric     return MCDisassembler::Fail;
47426122f3e6SDimitry Andric   }
47436122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
47446122f3e6SDimitry Andric     return MCDisassembler::Fail;
4745ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
47466122f3e6SDimitry Andric   if (Rm != 0xF) {
47476122f3e6SDimitry Andric     if (Rm != 0xD) {
47486122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
47496122f3e6SDimitry Andric     return MCDisassembler::Fail;
47506122f3e6SDimitry Andric     } else
4751ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
47526122f3e6SDimitry Andric   }
47536122f3e6SDimitry Andric 
47546122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
47556122f3e6SDimitry Andric     return MCDisassembler::Fail;
47566122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
47576122f3e6SDimitry Andric     return MCDisassembler::Fail;
47586122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
47596122f3e6SDimitry Andric     return MCDisassembler::Fail;
4760ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
47616122f3e6SDimitry Andric 
47626122f3e6SDimitry Andric   return S;
47636122f3e6SDimitry Andric }
47646122f3e6SDimitry Andric 
DecodeVLD4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4765dff0c46cSDimitry Andric static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
47666122f3e6SDimitry Andric                          uint64_t Address, const void *Decoder) {
47676122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
47686122f3e6SDimitry Andric 
47697ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
47707ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
47717ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
47727ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
47737ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
47746122f3e6SDimitry Andric 
47756122f3e6SDimitry Andric   unsigned align = 0;
47766122f3e6SDimitry Andric   unsigned index = 0;
47776122f3e6SDimitry Andric   unsigned inc = 1;
47786122f3e6SDimitry Andric   switch (size) {
47796122f3e6SDimitry Andric     default:
47806122f3e6SDimitry Andric       return MCDisassembler::Fail;
47816122f3e6SDimitry Andric     case 0:
47827ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
47836122f3e6SDimitry Andric         align = 4;
47847ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
47856122f3e6SDimitry Andric       break;
47866122f3e6SDimitry Andric     case 1:
47877ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
47886122f3e6SDimitry Andric         align = 8;
47897ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
47907ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
47916122f3e6SDimitry Andric         inc = 2;
47926122f3e6SDimitry Andric       break;
47936122f3e6SDimitry Andric     case 2:
47943861d79fSDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
47953861d79fSDimitry Andric         case 0:
47963861d79fSDimitry Andric           align = 0; break;
47973861d79fSDimitry Andric         case 3:
47983861d79fSDimitry Andric           return MCDisassembler::Fail;
47993861d79fSDimitry Andric         default:
48003861d79fSDimitry Andric           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
48013861d79fSDimitry Andric       }
48023861d79fSDimitry Andric 
48037ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
48047ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
48056122f3e6SDimitry Andric         inc = 2;
48066122f3e6SDimitry Andric       break;
48076122f3e6SDimitry Andric   }
48086122f3e6SDimitry Andric 
48096122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
48106122f3e6SDimitry Andric     return MCDisassembler::Fail;
48116122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
48126122f3e6SDimitry Andric     return MCDisassembler::Fail;
48136122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
48146122f3e6SDimitry Andric     return MCDisassembler::Fail;
48156122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
48166122f3e6SDimitry Andric     return MCDisassembler::Fail;
48176122f3e6SDimitry Andric 
48186122f3e6SDimitry Andric   if (Rm != 0xF) { // Writeback
48196122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48206122f3e6SDimitry Andric       return MCDisassembler::Fail;
48216122f3e6SDimitry Andric   }
48226122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48236122f3e6SDimitry Andric     return MCDisassembler::Fail;
4824ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
48256122f3e6SDimitry Andric   if (Rm != 0xF) {
48266122f3e6SDimitry Andric     if (Rm != 0xD) {
48276122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
48286122f3e6SDimitry Andric         return MCDisassembler::Fail;
48296122f3e6SDimitry Andric     } else
4830ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
48316122f3e6SDimitry Andric   }
48326122f3e6SDimitry Andric 
48336122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
48346122f3e6SDimitry Andric     return MCDisassembler::Fail;
48356122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
48366122f3e6SDimitry Andric     return MCDisassembler::Fail;
48376122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
48386122f3e6SDimitry Andric     return MCDisassembler::Fail;
48396122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
48406122f3e6SDimitry Andric     return MCDisassembler::Fail;
4841ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
48426122f3e6SDimitry Andric 
48436122f3e6SDimitry Andric   return S;
48446122f3e6SDimitry Andric }
48456122f3e6SDimitry Andric 
DecodeVST4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4846dff0c46cSDimitry Andric static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
48476122f3e6SDimitry Andric                          uint64_t Address, const void *Decoder) {
48486122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
48496122f3e6SDimitry Andric 
48507ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
48517ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
48527ae0e2c9SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
48537ae0e2c9SDimitry Andric   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
48547ae0e2c9SDimitry Andric   unsigned size = fieldFromInstruction(Insn, 10, 2);
48556122f3e6SDimitry Andric 
48566122f3e6SDimitry Andric   unsigned align = 0;
48576122f3e6SDimitry Andric   unsigned index = 0;
48586122f3e6SDimitry Andric   unsigned inc = 1;
48596122f3e6SDimitry Andric   switch (size) {
48606122f3e6SDimitry Andric     default:
48616122f3e6SDimitry Andric       return MCDisassembler::Fail;
48626122f3e6SDimitry Andric     case 0:
48637ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
48646122f3e6SDimitry Andric         align = 4;
48657ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 5, 3);
48666122f3e6SDimitry Andric       break;
48676122f3e6SDimitry Andric     case 1:
48687ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 4, 1))
48696122f3e6SDimitry Andric         align = 8;
48707ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 6, 2);
48717ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 5, 1))
48726122f3e6SDimitry Andric         inc = 2;
48736122f3e6SDimitry Andric       break;
48746122f3e6SDimitry Andric     case 2:
48753861d79fSDimitry Andric       switch (fieldFromInstruction(Insn, 4, 2)) {
48763861d79fSDimitry Andric         case 0:
48773861d79fSDimitry Andric           align = 0; break;
48783861d79fSDimitry Andric         case 3:
48793861d79fSDimitry Andric           return MCDisassembler::Fail;
48803861d79fSDimitry Andric         default:
48813861d79fSDimitry Andric           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
48823861d79fSDimitry Andric       }
48833861d79fSDimitry Andric 
48847ae0e2c9SDimitry Andric       index = fieldFromInstruction(Insn, 7, 1);
48857ae0e2c9SDimitry Andric       if (fieldFromInstruction(Insn, 6, 1))
48866122f3e6SDimitry Andric         inc = 2;
48876122f3e6SDimitry Andric       break;
48886122f3e6SDimitry Andric   }
48896122f3e6SDimitry Andric 
48906122f3e6SDimitry Andric   if (Rm != 0xF) { // Writeback
48916122f3e6SDimitry Andric     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48926122f3e6SDimitry Andric     return MCDisassembler::Fail;
48936122f3e6SDimitry Andric   }
48946122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
48956122f3e6SDimitry Andric     return MCDisassembler::Fail;
4896ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(align));
48976122f3e6SDimitry Andric   if (Rm != 0xF) {
48986122f3e6SDimitry Andric     if (Rm != 0xD) {
48996122f3e6SDimitry Andric       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
49006122f3e6SDimitry Andric     return MCDisassembler::Fail;
49016122f3e6SDimitry Andric     } else
4902ff0cc061SDimitry Andric       Inst.addOperand(MCOperand::createReg(0));
49036122f3e6SDimitry Andric   }
49046122f3e6SDimitry Andric 
49056122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
49066122f3e6SDimitry Andric     return MCDisassembler::Fail;
49076122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
49086122f3e6SDimitry Andric     return MCDisassembler::Fail;
49096122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
49106122f3e6SDimitry Andric     return MCDisassembler::Fail;
49116122f3e6SDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
49126122f3e6SDimitry Andric     return MCDisassembler::Fail;
4913ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(index));
49146122f3e6SDimitry Andric 
49156122f3e6SDimitry Andric   return S;
49166122f3e6SDimitry Andric }
49176122f3e6SDimitry Andric 
DecodeVMOVSRR(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4918dff0c46cSDimitry Andric static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
49196122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
49206122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
49217ae0e2c9SDimitry Andric   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
49227ae0e2c9SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
49237ae0e2c9SDimitry Andric   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
49247ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
49257ae0e2c9SDimitry Andric   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
49266122f3e6SDimitry Andric 
49276122f3e6SDimitry Andric   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
49286122f3e6SDimitry Andric     S = MCDisassembler::SoftFail;
49296122f3e6SDimitry Andric 
49306122f3e6SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
49316122f3e6SDimitry Andric     return MCDisassembler::Fail;
49326122f3e6SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
49336122f3e6SDimitry Andric     return MCDisassembler::Fail;
49346122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
49356122f3e6SDimitry Andric     return MCDisassembler::Fail;
49366122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
49376122f3e6SDimitry Andric     return MCDisassembler::Fail;
49386122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
49396122f3e6SDimitry Andric     return MCDisassembler::Fail;
49406122f3e6SDimitry Andric 
49416122f3e6SDimitry Andric   return S;
49426122f3e6SDimitry Andric }
49436122f3e6SDimitry Andric 
DecodeVMOVRRS(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4944dff0c46cSDimitry Andric static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
49456122f3e6SDimitry Andric                                   uint64_t Address, const void *Decoder) {
49466122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
49477ae0e2c9SDimitry Andric   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
49487ae0e2c9SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
49497ae0e2c9SDimitry Andric   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
49507ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
49517ae0e2c9SDimitry Andric   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
49526122f3e6SDimitry Andric 
49536122f3e6SDimitry Andric   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
49546122f3e6SDimitry Andric     S = MCDisassembler::SoftFail;
49556122f3e6SDimitry Andric 
49566122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
49576122f3e6SDimitry Andric     return MCDisassembler::Fail;
49586122f3e6SDimitry Andric   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
49596122f3e6SDimitry Andric     return MCDisassembler::Fail;
49606122f3e6SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
49616122f3e6SDimitry Andric     return MCDisassembler::Fail;
49626122f3e6SDimitry Andric   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
49636122f3e6SDimitry Andric     return MCDisassembler::Fail;
49646122f3e6SDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
49656122f3e6SDimitry Andric     return MCDisassembler::Fail;
49666122f3e6SDimitry Andric 
49676122f3e6SDimitry Andric   return S;
49686122f3e6SDimitry Andric }
49696122f3e6SDimitry Andric 
DecodeIT(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4970dff0c46cSDimitry Andric static DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn,
49716122f3e6SDimitry Andric                              uint64_t Address, const void *Decoder) {
49726122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
49737ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 4, 4);
49747ae0e2c9SDimitry Andric   unsigned mask = fieldFromInstruction(Insn, 0, 4);
49756122f3e6SDimitry Andric 
49766122f3e6SDimitry Andric   if (pred == 0xF) {
49776122f3e6SDimitry Andric     pred = 0xE;
49786122f3e6SDimitry Andric     S = MCDisassembler::SoftFail;
49796122f3e6SDimitry Andric   }
49806122f3e6SDimitry Andric 
4981f785676fSDimitry Andric   if (mask == 0x0)
4982f785676fSDimitry Andric     return MCDisassembler::Fail;
49836122f3e6SDimitry Andric 
4984ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(pred));
4985ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(mask));
49866122f3e6SDimitry Andric   return S;
49876122f3e6SDimitry Andric }
49886122f3e6SDimitry Andric 
49896122f3e6SDimitry Andric static DecodeStatus
DecodeT2LDRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4990dff0c46cSDimitry Andric DecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
49916122f3e6SDimitry Andric                            uint64_t Address, const void *Decoder) {
49926122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
49936122f3e6SDimitry Andric 
49947ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
49957ae0e2c9SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
49967ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
49977ae0e2c9SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
49987ae0e2c9SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
49997ae0e2c9SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
50007ae0e2c9SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
50016122f3e6SDimitry Andric   bool writeback = (W == 1) | (P == 0);
50026122f3e6SDimitry Andric 
50036122f3e6SDimitry Andric   addr |= (U << 8) | (Rn << 9);
50046122f3e6SDimitry Andric 
50056122f3e6SDimitry Andric   if (writeback && (Rn == Rt || Rn == Rt2))
50066122f3e6SDimitry Andric     Check(S, MCDisassembler::SoftFail);
50076122f3e6SDimitry Andric   if (Rt == Rt2)
50086122f3e6SDimitry Andric     Check(S, MCDisassembler::SoftFail);
50096122f3e6SDimitry Andric 
50106122f3e6SDimitry Andric   // Rt
50116122f3e6SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
50126122f3e6SDimitry Andric     return MCDisassembler::Fail;
50136122f3e6SDimitry Andric   // Rt2
50146122f3e6SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
50156122f3e6SDimitry Andric     return MCDisassembler::Fail;
50166122f3e6SDimitry Andric   // Writeback operand
50176122f3e6SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
50186122f3e6SDimitry Andric     return MCDisassembler::Fail;
50196122f3e6SDimitry Andric   // addr
50206122f3e6SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
50216122f3e6SDimitry Andric     return MCDisassembler::Fail;
50226122f3e6SDimitry Andric 
50236122f3e6SDimitry Andric   return S;
50246122f3e6SDimitry Andric }
50256122f3e6SDimitry Andric 
50266122f3e6SDimitry Andric static DecodeStatus
DecodeT2STRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)5027dff0c46cSDimitry Andric DecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
50286122f3e6SDimitry Andric                            uint64_t Address, const void *Decoder) {
50296122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
50306122f3e6SDimitry Andric 
50317ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
50327ae0e2c9SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
50337ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
50347ae0e2c9SDimitry Andric   unsigned addr = fieldFromInstruction(Insn, 0, 8);
50357ae0e2c9SDimitry Andric   unsigned W = fieldFromInstruction(Insn, 21, 1);
50367ae0e2c9SDimitry Andric   unsigned U = fieldFromInstruction(Insn, 23, 1);
50377ae0e2c9SDimitry Andric   unsigned P = fieldFromInstruction(Insn, 24, 1);
50386122f3e6SDimitry Andric   bool writeback = (W == 1) | (P == 0);
50396122f3e6SDimitry Andric 
50406122f3e6SDimitry Andric   addr |= (U << 8) | (Rn << 9);
50416122f3e6SDimitry Andric 
50426122f3e6SDimitry Andric   if (writeback && (Rn == Rt || Rn == Rt2))
50436122f3e6SDimitry Andric     Check(S, MCDisassembler::SoftFail);
50446122f3e6SDimitry Andric 
50456122f3e6SDimitry Andric   // Writeback operand
50466122f3e6SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
50476122f3e6SDimitry Andric     return MCDisassembler::Fail;
50486122f3e6SDimitry Andric   // Rt
50496122f3e6SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
50506122f3e6SDimitry Andric     return MCDisassembler::Fail;
50516122f3e6SDimitry Andric   // Rt2
50526122f3e6SDimitry Andric   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
50536122f3e6SDimitry Andric     return MCDisassembler::Fail;
50546122f3e6SDimitry Andric   // addr
50556122f3e6SDimitry Andric   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
50566122f3e6SDimitry Andric     return MCDisassembler::Fail;
50576122f3e6SDimitry Andric 
50586122f3e6SDimitry Andric   return S;
50596122f3e6SDimitry Andric }
50606122f3e6SDimitry Andric 
DecodeT2Adr(MCInst & Inst,uint32_t Insn,uint64_t Address,const void * Decoder)5061dff0c46cSDimitry Andric static DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn,
50626122f3e6SDimitry Andric                                 uint64_t Address, const void *Decoder) {
50637ae0e2c9SDimitry Andric   unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
50647ae0e2c9SDimitry Andric   unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
50656122f3e6SDimitry Andric   if (sign1 != sign2) return MCDisassembler::Fail;
50666122f3e6SDimitry Andric 
50677ae0e2c9SDimitry Andric   unsigned Val = fieldFromInstruction(Insn, 0, 8);
50687ae0e2c9SDimitry Andric   Val |= fieldFromInstruction(Insn, 12, 3) << 8;
50697ae0e2c9SDimitry Andric   Val |= fieldFromInstruction(Insn, 26, 1) << 11;
50706122f3e6SDimitry Andric   Val |= sign1 << 12;
5071ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<13>(Val)));
50726122f3e6SDimitry Andric 
50736122f3e6SDimitry Andric   return MCDisassembler::Success;
50746122f3e6SDimitry Andric }
50756122f3e6SDimitry Andric 
DecodeT2ShifterImmOperand(MCInst & Inst,uint32_t Val,uint64_t Address,const void * Decoder)5076dff0c46cSDimitry Andric static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
50776122f3e6SDimitry Andric                                               uint64_t Address,
50786122f3e6SDimitry Andric                                               const void *Decoder) {
50796122f3e6SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
50806122f3e6SDimitry Andric 
50816122f3e6SDimitry Andric   // Shift of "asr #32" is not allowed in Thumb2 mode.
5082ff0cc061SDimitry Andric   if (Val == 0x20) S = MCDisassembler::Fail;
5083ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
50846122f3e6SDimitry Andric   return S;
50856122f3e6SDimitry Andric }
50866122f3e6SDimitry Andric 
DecodeSwap(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)5087dff0c46cSDimitry Andric static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
5088dff0c46cSDimitry Andric                                uint64_t Address, const void *Decoder) {
50897ae0e2c9SDimitry Andric   unsigned Rt   = fieldFromInstruction(Insn, 12, 4);
50907ae0e2c9SDimitry Andric   unsigned Rt2  = fieldFromInstruction(Insn, 0,  4);
50917ae0e2c9SDimitry Andric   unsigned Rn   = fieldFromInstruction(Insn, 16, 4);
50927ae0e2c9SDimitry Andric   unsigned pred = fieldFromInstruction(Insn, 28, 4);
5093dff0c46cSDimitry Andric 
5094dff0c46cSDimitry Andric   if (pred == 0xF)
5095dff0c46cSDimitry Andric     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
5096dff0c46cSDimitry Andric 
5097dff0c46cSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
5098cb4dff85SDimitry Andric 
5099cb4dff85SDimitry Andric   if (Rt == Rn || Rn == Rt2)
5100cb4dff85SDimitry Andric     S = MCDisassembler::SoftFail;
5101cb4dff85SDimitry Andric 
5102dff0c46cSDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5103dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5104dff0c46cSDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5105dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5106dff0c46cSDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
5107dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5108dff0c46cSDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5109dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5110dff0c46cSDimitry Andric 
5111dff0c46cSDimitry Andric   return S;
5112dff0c46cSDimitry Andric }
5113dff0c46cSDimitry Andric 
DecodeVCVTD(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)5114dff0c46cSDimitry Andric static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
5115dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder) {
51167d523365SDimitry Andric   const FeatureBitset &featureBits =
51177d523365SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
51187d523365SDimitry Andric   bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
51197d523365SDimitry Andric 
51207ae0e2c9SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
51217ae0e2c9SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
51227ae0e2c9SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
51237ae0e2c9SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
51247ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 16, 6);
51257ae0e2c9SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
5126f785676fSDimitry Andric   unsigned op = fieldFromInstruction(Insn, 5, 1);
5127dff0c46cSDimitry Andric 
5128dff0c46cSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
5129dff0c46cSDimitry Andric 
51307d523365SDimitry Andric   // If the top 3 bits of imm are clear, this is a VMOV (immediate)
51317d523365SDimitry Andric   if (!(imm & 0x38)) {
51327d523365SDimitry Andric     if (cmode == 0xF) {
5133f785676fSDimitry Andric       if (op == 1) return MCDisassembler::Fail;
5134dff0c46cSDimitry Andric       Inst.setOpcode(ARM::VMOVv2f32);
51357d523365SDimitry Andric     }
51367d523365SDimitry Andric     if (hasFullFP16) {
51377d523365SDimitry Andric       if (cmode == 0xE) {
51387d523365SDimitry Andric         if (op == 1) {
51397d523365SDimitry Andric           Inst.setOpcode(ARM::VMOVv1i64);
51407d523365SDimitry Andric         } else {
51417d523365SDimitry Andric           Inst.setOpcode(ARM::VMOVv8i8);
51427d523365SDimitry Andric         }
51437d523365SDimitry Andric       }
51447d523365SDimitry Andric       if (cmode == 0xD) {
51457d523365SDimitry Andric         if (op == 1) {
51467d523365SDimitry Andric           Inst.setOpcode(ARM::VMVNv2i32);
51477d523365SDimitry Andric         } else {
51487d523365SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i32);
51497d523365SDimitry Andric         }
51507d523365SDimitry Andric       }
51517d523365SDimitry Andric       if (cmode == 0xC) {
51527d523365SDimitry Andric         if (op == 1) {
51537d523365SDimitry Andric           Inst.setOpcode(ARM::VMVNv2i32);
51547d523365SDimitry Andric         } else {
51557d523365SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i32);
51567d523365SDimitry Andric         }
51577d523365SDimitry Andric       }
51587d523365SDimitry Andric     }
5159dff0c46cSDimitry Andric     return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
5160dff0c46cSDimitry Andric   }
5161dff0c46cSDimitry Andric 
5162f785676fSDimitry Andric   if (!(imm & 0x20)) return MCDisassembler::Fail;
5163dff0c46cSDimitry Andric 
5164dff0c46cSDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
5165dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5166dff0c46cSDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
5167dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5168ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - imm));
5169dff0c46cSDimitry Andric 
5170dff0c46cSDimitry Andric   return S;
5171dff0c46cSDimitry Andric }
5172dff0c46cSDimitry Andric 
DecodeVCVTQ(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)5173dff0c46cSDimitry Andric static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
5174dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder) {
51757d523365SDimitry Andric   const FeatureBitset &featureBits =
51767d523365SDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
51777d523365SDimitry Andric   bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
51787d523365SDimitry Andric 
51797ae0e2c9SDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
51807ae0e2c9SDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
51817ae0e2c9SDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
51827ae0e2c9SDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
51837ae0e2c9SDimitry Andric   unsigned imm = fieldFromInstruction(Insn, 16, 6);
51847ae0e2c9SDimitry Andric   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
5185f785676fSDimitry Andric   unsigned op = fieldFromInstruction(Insn, 5, 1);
5186dff0c46cSDimitry Andric 
5187dff0c46cSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
5188dff0c46cSDimitry Andric 
51897d523365SDimitry Andric   // If the top 3 bits of imm are clear, this is a VMOV (immediate)
51907d523365SDimitry Andric   if (!(imm & 0x38)) {
51917d523365SDimitry Andric     if (cmode == 0xF) {
5192f785676fSDimitry Andric       if (op == 1) return MCDisassembler::Fail;
5193dff0c46cSDimitry Andric       Inst.setOpcode(ARM::VMOVv4f32);
51947d523365SDimitry Andric     }
51957d523365SDimitry Andric     if (hasFullFP16) {
51967d523365SDimitry Andric       if (cmode == 0xE) {
51977d523365SDimitry Andric         if (op == 1) {
51987d523365SDimitry Andric           Inst.setOpcode(ARM::VMOVv2i64);
51997d523365SDimitry Andric         } else {
52007d523365SDimitry Andric           Inst.setOpcode(ARM::VMOVv16i8);
52017d523365SDimitry Andric         }
52027d523365SDimitry Andric       }
52037d523365SDimitry Andric       if (cmode == 0xD) {
52047d523365SDimitry Andric         if (op == 1) {
52057d523365SDimitry Andric           Inst.setOpcode(ARM::VMVNv4i32);
52067d523365SDimitry Andric         } else {
52077d523365SDimitry Andric           Inst.setOpcode(ARM::VMOVv4i32);
52087d523365SDimitry Andric         }
52097d523365SDimitry Andric       }
52107d523365SDimitry Andric       if (cmode == 0xC) {
52117d523365SDimitry Andric         if (op == 1) {
52127d523365SDimitry Andric           Inst.setOpcode(ARM::VMVNv4i32);
52137d523365SDimitry Andric         } else {
52147d523365SDimitry Andric           Inst.setOpcode(ARM::VMOVv4i32);
52157d523365SDimitry Andric         }
52167d523365SDimitry Andric       }
52177d523365SDimitry Andric     }
5218dff0c46cSDimitry Andric     return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
5219dff0c46cSDimitry Andric   }
5220dff0c46cSDimitry Andric 
5221f785676fSDimitry Andric   if (!(imm & 0x20)) return MCDisassembler::Fail;
5222dff0c46cSDimitry Andric 
5223dff0c46cSDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
5224dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5225dff0c46cSDimitry Andric   if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
5226dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5227ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - imm));
5228dff0c46cSDimitry Andric 
5229dff0c46cSDimitry Andric   return S;
5230dff0c46cSDimitry Andric }
5231dff0c46cSDimitry Andric 
DecodeNEONComplexLane64Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)52322cab237bSDimitry Andric static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst,
52332cab237bSDimitry Andric                                                        unsigned Insn,
52342cab237bSDimitry Andric                                                        uint64_t Address,
52352cab237bSDimitry Andric                                                        const void *Decoder) {
52362cab237bSDimitry Andric   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
52372cab237bSDimitry Andric   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
52382cab237bSDimitry Andric   unsigned Vn = (fieldFromInstruction(Insn, 16, 4) << 0);
52392cab237bSDimitry Andric   Vn |= (fieldFromInstruction(Insn, 7, 1) << 4);
52402cab237bSDimitry Andric   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
52412cab237bSDimitry Andric   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
52422cab237bSDimitry Andric   unsigned q = (fieldFromInstruction(Insn, 6, 1) << 0);
52432cab237bSDimitry Andric   unsigned rotate = (fieldFromInstruction(Insn, 20, 2) << 0);
52442cab237bSDimitry Andric 
52452cab237bSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
52462cab237bSDimitry Andric 
52472cab237bSDimitry Andric   auto DestRegDecoder = q ? DecodeQPRRegisterClass : DecodeDPRRegisterClass;
52482cab237bSDimitry Andric 
52492cab237bSDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
52502cab237bSDimitry Andric     return MCDisassembler::Fail;
52512cab237bSDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
52522cab237bSDimitry Andric     return MCDisassembler::Fail;
52532cab237bSDimitry Andric   if (!Check(S, DestRegDecoder(Inst, Vn, Address, Decoder)))
52542cab237bSDimitry Andric     return MCDisassembler::Fail;
52552cab237bSDimitry Andric   if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
52562cab237bSDimitry Andric     return MCDisassembler::Fail;
52572cab237bSDimitry Andric   // The lane index does not have any bits in the encoding, because it can only
52582cab237bSDimitry Andric   // be 0.
52592cab237bSDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
52602cab237bSDimitry Andric   Inst.addOperand(MCOperand::createImm(rotate));
52612cab237bSDimitry Andric 
52622cab237bSDimitry Andric   return S;
52632cab237bSDimitry Andric }
52642cab237bSDimitry Andric 
DecodeLDR(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)5265dff0c46cSDimitry Andric static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
5266dff0c46cSDimitry Andric                                 uint64_t Address, const void *Decoder) {
5267dff0c46cSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
5268dff0c46cSDimitry Andric 
52697ae0e2c9SDimitry Andric   unsigned Rn = fieldFromInstruction(Val, 16, 4);
52707ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Val, 12, 4);
52717ae0e2c9SDimitry Andric   unsigned Rm = fieldFromInstruction(Val, 0, 4);
52727ae0e2c9SDimitry Andric   Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
52737ae0e2c9SDimitry Andric   unsigned Cond = fieldFromInstruction(Val, 28, 4);
5274dff0c46cSDimitry Andric 
52757ae0e2c9SDimitry Andric   if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
5276dff0c46cSDimitry Andric     S = MCDisassembler::SoftFail;
5277dff0c46cSDimitry Andric 
5278dff0c46cSDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5279dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5280dff0c46cSDimitry Andric   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
5281dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5282dff0c46cSDimitry Andric   if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
5283dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5284dff0c46cSDimitry Andric   if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
5285dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5286dff0c46cSDimitry Andric   if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
5287dff0c46cSDimitry Andric     return MCDisassembler::Fail;
5288dff0c46cSDimitry Andric 
5289dff0c46cSDimitry Andric   return S;
5290dff0c46cSDimitry Andric }
5291dff0c46cSDimitry Andric 
DecoderForMRRC2AndMCRR2(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)52927a7e6055SDimitry Andric static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
5293cb4dff85SDimitry Andric                                             uint64_t Address, const void *Decoder) {
5294cb4dff85SDimitry Andric   DecodeStatus S = MCDisassembler::Success;
5295cb4dff85SDimitry Andric 
52967ae0e2c9SDimitry Andric   unsigned CRm = fieldFromInstruction(Val, 0, 4);
52977ae0e2c9SDimitry Andric   unsigned opc1 = fieldFromInstruction(Val, 4, 4);
52987ae0e2c9SDimitry Andric   unsigned cop = fieldFromInstruction(Val, 8, 4);
52997ae0e2c9SDimitry Andric   unsigned Rt = fieldFromInstruction(Val, 12, 4);
53007ae0e2c9SDimitry Andric   unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
5301cb4dff85SDimitry Andric 
5302cb4dff85SDimitry Andric   if ((cop & ~0x1) == 0xa)
5303cb4dff85SDimitry Andric     return MCDisassembler::Fail;
5304cb4dff85SDimitry Andric 
5305cb4dff85SDimitry Andric   if (Rt == Rt2)
5306cb4dff85SDimitry Andric     S = MCDisassembler::SoftFail;
5307cb4dff85SDimitry Andric 
53083ca95b02SDimitry Andric   // We have to check if the instruction is MRRC2
53093ca95b02SDimitry Andric   // or MCRR2 when constructing the operands for
53103ca95b02SDimitry Andric   // Inst. Reason is because MRRC2 stores to two
53113ca95b02SDimitry Andric   // registers so it's tablegen desc has has two
53123ca95b02SDimitry Andric   // outputs whereas MCRR doesn't store to any
53133ca95b02SDimitry Andric   // registers so all of it's operands are listed
53143ca95b02SDimitry Andric   // as inputs, therefore the operand order for
53153ca95b02SDimitry Andric   // MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm]
53163ca95b02SDimitry Andric   // and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm]
53173ca95b02SDimitry Andric 
53183ca95b02SDimitry Andric   if (Inst.getOpcode() == ARM::MRRC2) {
5319cb4dff85SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5320cb4dff85SDimitry Andric       return MCDisassembler::Fail;
5321cb4dff85SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5322cb4dff85SDimitry Andric       return MCDisassembler::Fail;
53233ca95b02SDimitry Andric   }
53243ca95b02SDimitry Andric   Inst.addOperand(MCOperand::createImm(cop));
53253ca95b02SDimitry Andric   Inst.addOperand(MCOperand::createImm(opc1));
53263ca95b02SDimitry Andric   if (Inst.getOpcode() == ARM::MCRR2) {
53273ca95b02SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
53283ca95b02SDimitry Andric       return MCDisassembler::Fail;
53293ca95b02SDimitry Andric     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
53303ca95b02SDimitry Andric       return MCDisassembler::Fail;
53313ca95b02SDimitry Andric   }
5332ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(CRm));
5333cb4dff85SDimitry Andric 
5334cb4dff85SDimitry Andric   return S;
5335cb4dff85SDimitry Andric }
53362cab237bSDimitry Andric 
DecodeForVMRSandVMSR(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)53372cab237bSDimitry Andric static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
53382cab237bSDimitry Andric                                          uint64_t Address,
53392cab237bSDimitry Andric                                          const void *Decoder) {
53402cab237bSDimitry Andric   const FeatureBitset &featureBits =
53412cab237bSDimitry Andric       ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
53422cab237bSDimitry Andric   DecodeStatus S = MCDisassembler::Success;
53432cab237bSDimitry Andric 
53442cab237bSDimitry Andric   unsigned Rt = fieldFromInstruction(Val, 12, 4);
53452cab237bSDimitry Andric 
53462cab237bSDimitry Andric   if (featureBits[ARM::ModeThumb] && !featureBits[ARM::HasV8Ops]) {
53472cab237bSDimitry Andric     if (Rt == 13 || Rt == 15)
53482cab237bSDimitry Andric       S = MCDisassembler::SoftFail;
53492cab237bSDimitry Andric     Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder));
53502cab237bSDimitry Andric   } else
53512cab237bSDimitry Andric     Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder));
53522cab237bSDimitry Andric 
53532cab237bSDimitry Andric   if (featureBits[ARM::ModeThumb]) {
53542cab237bSDimitry Andric     Inst.addOperand(MCOperand::createImm(ARMCC::AL));
53552cab237bSDimitry Andric     Inst.addOperand(MCOperand::createReg(0));
53562cab237bSDimitry Andric   } else {
53572cab237bSDimitry Andric     unsigned pred = fieldFromInstruction(Val, 28, 4);
53582cab237bSDimitry Andric     if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
53592cab237bSDimitry Andric       return MCDisassembler::Fail;
53602cab237bSDimitry Andric   }
53612cab237bSDimitry Andric 
53622cab237bSDimitry Andric   return S;
53632cab237bSDimitry Andric }
5364