xref: /minix3/external/bsd/llvm/dist/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc #include "llvm/MC/MCDisassembler.h"
11f4a2713aSLionel Sambuc #include "MCTargetDesc/ARMAddressingModes.h"
12f4a2713aSLionel Sambuc #include "MCTargetDesc/ARMBaseInfo.h"
13f4a2713aSLionel Sambuc #include "MCTargetDesc/ARMMCExpr.h"
14f4a2713aSLionel Sambuc #include "llvm/MC/MCContext.h"
15f4a2713aSLionel Sambuc #include "llvm/MC/MCExpr.h"
16f4a2713aSLionel Sambuc #include "llvm/MC/MCFixedLenDisassembler.h"
17f4a2713aSLionel Sambuc #include "llvm/MC/MCInst.h"
18f4a2713aSLionel Sambuc #include "llvm/MC/MCInstrDesc.h"
19f4a2713aSLionel Sambuc #include "llvm/MC/MCSubtargetInfo.h"
20f4a2713aSLionel Sambuc #include "llvm/Support/Debug.h"
21f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/LEB128.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/TargetRegistry.h"
24f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
25f4a2713aSLionel Sambuc #include <vector>
26f4a2713aSLionel Sambuc 
27f4a2713aSLionel Sambuc using namespace llvm;
28f4a2713aSLionel Sambuc 
29*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "arm-disassembler"
30*0a6a1f1dSLionel Sambuc 
31f4a2713aSLionel Sambuc typedef MCDisassembler::DecodeStatus DecodeStatus;
32f4a2713aSLionel Sambuc 
33f4a2713aSLionel Sambuc namespace {
34f4a2713aSLionel Sambuc   // Handles the condition code status of instructions in IT blocks
35f4a2713aSLionel Sambuc   class ITStatus
36f4a2713aSLionel Sambuc   {
37f4a2713aSLionel Sambuc     public:
38f4a2713aSLionel Sambuc       // Returns the condition code for instruction in IT block
getITCC()39f4a2713aSLionel Sambuc       unsigned getITCC() {
40f4a2713aSLionel Sambuc         unsigned CC = ARMCC::AL;
41f4a2713aSLionel Sambuc         if (instrInITBlock())
42f4a2713aSLionel Sambuc           CC = ITStates.back();
43f4a2713aSLionel Sambuc         return CC;
44f4a2713aSLionel Sambuc       }
45f4a2713aSLionel Sambuc 
46f4a2713aSLionel Sambuc       // Advances the IT block state to the next T or E
advanceITState()47f4a2713aSLionel Sambuc       void advanceITState() {
48f4a2713aSLionel Sambuc         ITStates.pop_back();
49f4a2713aSLionel Sambuc       }
50f4a2713aSLionel Sambuc 
51f4a2713aSLionel Sambuc       // Returns true if the current instruction is in an IT block
instrInITBlock()52f4a2713aSLionel Sambuc       bool instrInITBlock() {
53f4a2713aSLionel Sambuc         return !ITStates.empty();
54f4a2713aSLionel Sambuc       }
55f4a2713aSLionel Sambuc 
56f4a2713aSLionel Sambuc       // Returns true if current instruction is the last instruction in an IT block
instrLastInITBlock()57f4a2713aSLionel Sambuc       bool instrLastInITBlock() {
58f4a2713aSLionel Sambuc         return ITStates.size() == 1;
59f4a2713aSLionel Sambuc       }
60f4a2713aSLionel Sambuc 
61f4a2713aSLionel Sambuc       // Called when decoding an IT instruction. Sets the IT state for the following
62f4a2713aSLionel Sambuc       // instructions that for the IT block. Firstcond and Mask correspond to the
63f4a2713aSLionel Sambuc       // fields in the IT instruction encoding.
setITState(char Firstcond,char Mask)64f4a2713aSLionel Sambuc       void setITState(char Firstcond, char Mask) {
65f4a2713aSLionel Sambuc         // (3 - the number of trailing zeros) is the number of then / else.
66f4a2713aSLionel Sambuc         unsigned CondBit0 = Firstcond & 1;
67f4a2713aSLionel Sambuc         unsigned NumTZ = countTrailingZeros<uint8_t>(Mask);
68f4a2713aSLionel Sambuc         unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
69f4a2713aSLionel Sambuc         assert(NumTZ <= 3 && "Invalid IT mask!");
70f4a2713aSLionel Sambuc         // push condition codes onto the stack the correct order for the pops
71f4a2713aSLionel Sambuc         for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
72f4a2713aSLionel Sambuc           bool T = ((Mask >> Pos) & 1) == CondBit0;
73f4a2713aSLionel Sambuc           if (T)
74f4a2713aSLionel Sambuc             ITStates.push_back(CCBits);
75f4a2713aSLionel Sambuc           else
76f4a2713aSLionel Sambuc             ITStates.push_back(CCBits ^ 1);
77f4a2713aSLionel Sambuc         }
78f4a2713aSLionel Sambuc         ITStates.push_back(CCBits);
79f4a2713aSLionel Sambuc       }
80f4a2713aSLionel Sambuc 
81f4a2713aSLionel Sambuc     private:
82f4a2713aSLionel Sambuc       std::vector<unsigned char> ITStates;
83f4a2713aSLionel Sambuc   };
84f4a2713aSLionel Sambuc }
85f4a2713aSLionel Sambuc 
86f4a2713aSLionel Sambuc namespace {
87*0a6a1f1dSLionel Sambuc /// ARM disassembler for all ARM platforms.
88f4a2713aSLionel Sambuc class ARMDisassembler : public MCDisassembler {
89f4a2713aSLionel Sambuc public:
ARMDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)90*0a6a1f1dSLionel Sambuc   ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
91*0a6a1f1dSLionel Sambuc     MCDisassembler(STI, Ctx) {
92f4a2713aSLionel Sambuc   }
93f4a2713aSLionel Sambuc 
~ARMDisassembler()94*0a6a1f1dSLionel Sambuc   ~ARMDisassembler() {}
95f4a2713aSLionel Sambuc 
96*0a6a1f1dSLionel Sambuc   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
97*0a6a1f1dSLionel Sambuc                               ArrayRef<uint8_t> Bytes, uint64_t Address,
98*0a6a1f1dSLionel Sambuc                               raw_ostream &VStream,
99*0a6a1f1dSLionel Sambuc                               raw_ostream &CStream) const override;
100f4a2713aSLionel Sambuc };
101f4a2713aSLionel Sambuc 
102*0a6a1f1dSLionel Sambuc /// Thumb disassembler for all Thumb platforms.
103f4a2713aSLionel Sambuc class ThumbDisassembler : public MCDisassembler {
104f4a2713aSLionel Sambuc public:
ThumbDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)105*0a6a1f1dSLionel Sambuc   ThumbDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
106*0a6a1f1dSLionel Sambuc     MCDisassembler(STI, Ctx) {
107f4a2713aSLionel Sambuc   }
108f4a2713aSLionel Sambuc 
~ThumbDisassembler()109*0a6a1f1dSLionel Sambuc   ~ThumbDisassembler() {}
110f4a2713aSLionel Sambuc 
111*0a6a1f1dSLionel Sambuc   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
112*0a6a1f1dSLionel Sambuc                               ArrayRef<uint8_t> Bytes, uint64_t Address,
113*0a6a1f1dSLionel Sambuc                               raw_ostream &VStream,
114*0a6a1f1dSLionel Sambuc                               raw_ostream &CStream) const override;
115f4a2713aSLionel Sambuc 
116f4a2713aSLionel Sambuc private:
117f4a2713aSLionel Sambuc   mutable ITStatus ITBlock;
118f4a2713aSLionel Sambuc   DecodeStatus AddThumbPredicate(MCInst&) const;
119f4a2713aSLionel Sambuc   void UpdateThumbVFPPredicate(MCInst&) const;
120f4a2713aSLionel Sambuc };
121f4a2713aSLionel Sambuc }
122f4a2713aSLionel Sambuc 
Check(DecodeStatus & Out,DecodeStatus In)123f4a2713aSLionel Sambuc static bool Check(DecodeStatus &Out, DecodeStatus In) {
124f4a2713aSLionel Sambuc   switch (In) {
125f4a2713aSLionel Sambuc     case MCDisassembler::Success:
126f4a2713aSLionel Sambuc       // Out stays the same.
127f4a2713aSLionel Sambuc       return true;
128f4a2713aSLionel Sambuc     case MCDisassembler::SoftFail:
129f4a2713aSLionel Sambuc       Out = In;
130f4a2713aSLionel Sambuc       return true;
131f4a2713aSLionel Sambuc     case MCDisassembler::Fail:
132f4a2713aSLionel Sambuc       Out = In;
133f4a2713aSLionel Sambuc       return false;
134f4a2713aSLionel Sambuc   }
135f4a2713aSLionel Sambuc   llvm_unreachable("Invalid DecodeStatus!");
136f4a2713aSLionel Sambuc }
137f4a2713aSLionel Sambuc 
138f4a2713aSLionel Sambuc 
139f4a2713aSLionel Sambuc // Forward declare these because the autogenerated code will reference them.
140f4a2713aSLionel Sambuc // Definitions are further down.
141f4a2713aSLionel Sambuc static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
142f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
143f4a2713aSLionel Sambuc static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst,
144f4a2713aSLionel Sambuc                                                unsigned RegNo, uint64_t Address,
145f4a2713aSLionel Sambuc                                                const void *Decoder);
146f4a2713aSLionel Sambuc static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst,
147f4a2713aSLionel Sambuc                                                unsigned RegNo, uint64_t Address,
148f4a2713aSLionel Sambuc                                                const void *Decoder);
149f4a2713aSLionel Sambuc static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
150f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
151f4a2713aSLionel Sambuc static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
152f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
153f4a2713aSLionel Sambuc static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
154f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
155f4a2713aSLionel Sambuc static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
156f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
157f4a2713aSLionel Sambuc static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
158f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
159f4a2713aSLionel Sambuc static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
160f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
161f4a2713aSLionel Sambuc static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
162f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
163f4a2713aSLionel Sambuc static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
164f4a2713aSLionel Sambuc                                                 unsigned RegNo,
165f4a2713aSLionel Sambuc                                                 uint64_t Address,
166f4a2713aSLionel Sambuc                                                 const void *Decoder);
167f4a2713aSLionel Sambuc static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
168f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
169f4a2713aSLionel Sambuc static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
170f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder);
171f4a2713aSLionel Sambuc static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
172f4a2713aSLionel Sambuc                                unsigned RegNo, uint64_t Address,
173f4a2713aSLionel Sambuc                                const void *Decoder);
174f4a2713aSLionel Sambuc 
175f4a2713aSLionel Sambuc static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
176f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
177f4a2713aSLionel Sambuc static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
178f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
179f4a2713aSLionel Sambuc static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
180f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
181f4a2713aSLionel Sambuc static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
182f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
183f4a2713aSLionel Sambuc static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
184f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
185f4a2713aSLionel Sambuc 
186f4a2713aSLionel Sambuc static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
187f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
188f4a2713aSLionel Sambuc static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
189f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
190f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst,
191f4a2713aSLionel Sambuc                                                   unsigned Insn,
192f4a2713aSLionel Sambuc                                                   uint64_t Address,
193f4a2713aSLionel Sambuc                                                   const void *Decoder);
194f4a2713aSLionel Sambuc static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
195f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
196f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn,
197f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
198f4a2713aSLionel Sambuc static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
199f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
200f4a2713aSLionel Sambuc static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
201f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
202f4a2713aSLionel Sambuc 
203f4a2713aSLionel Sambuc static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst,
204f4a2713aSLionel Sambuc                                                   unsigned Insn,
205f4a2713aSLionel Sambuc                                                   uint64_t Adddress,
206f4a2713aSLionel Sambuc                                                   const void *Decoder);
207f4a2713aSLionel Sambuc static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
208f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
209f4a2713aSLionel Sambuc static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
210f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
211f4a2713aSLionel Sambuc static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
212f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
213f4a2713aSLionel Sambuc static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
214f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
215f4a2713aSLionel Sambuc static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
216f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
217f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
218f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
219f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
220f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
221f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
222f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
223f4a2713aSLionel Sambuc static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
224f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
225f4a2713aSLionel Sambuc static DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn,
226f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
227f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
228f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
229f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val,
230f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
231f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val,
232f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
233f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val,
234f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
235f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val,
236f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
237f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
238f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
239f4a2713aSLionel Sambuc static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
240f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
241f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
242f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
243f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
244f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
245f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
246f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
247f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
248f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
249f4a2713aSLionel Sambuc static DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val,
250f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
251f4a2713aSLionel Sambuc static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
252f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
253f4a2713aSLionel Sambuc static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
254f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
255f4a2713aSLionel Sambuc static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
256f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
257f4a2713aSLionel Sambuc static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
258f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
259f4a2713aSLionel Sambuc static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
260f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
261f4a2713aSLionel Sambuc static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
262f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
263f4a2713aSLionel Sambuc static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
264f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
265f4a2713aSLionel Sambuc static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
266f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
267f4a2713aSLionel Sambuc static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
268f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
269f4a2713aSLionel Sambuc static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
270f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
271f4a2713aSLionel Sambuc static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
272f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
273*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Insn,
274*0a6a1f1dSLionel Sambuc                                uint64_t Address, const void *Decoder);
275f4a2713aSLionel Sambuc static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
276f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
277f4a2713aSLionel Sambuc static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
278f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
279f4a2713aSLionel Sambuc static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
280f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
281f4a2713aSLionel Sambuc static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
282f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
283f4a2713aSLionel Sambuc static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
284f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
285f4a2713aSLionel Sambuc static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
286f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
287f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
288f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
289f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
290f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
291f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
292f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
293f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
294f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
295f4a2713aSLionel Sambuc static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
296f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
297f4a2713aSLionel Sambuc static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
298f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
299f4a2713aSLionel Sambuc static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
300f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
301f4a2713aSLionel Sambuc static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
302f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
303f4a2713aSLionel Sambuc static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
304f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
305f4a2713aSLionel Sambuc static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
306f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
307f4a2713aSLionel Sambuc static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
308f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
309f4a2713aSLionel Sambuc static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
310f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
311f4a2713aSLionel Sambuc static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
312f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
313f4a2713aSLionel Sambuc 
314f4a2713aSLionel Sambuc 
315f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
316f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
317f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
318f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
319f4a2713aSLionel Sambuc static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
320f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
321f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
322f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
323f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
324f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
325f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
326f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
327f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
328f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
329f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
330f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
331f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
332f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
333f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
334f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
335f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
336f4a2713aSLionel Sambuc                                uint64_t Address, const void* Decoder);
337f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
338f4a2713aSLionel Sambuc                                uint64_t Address, const void* Decoder);
339f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
340f4a2713aSLionel Sambuc                                uint64_t Address, const void* Decoder);
341f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
342f4a2713aSLionel Sambuc                                uint64_t Address, const void* Decoder);
343f4a2713aSLionel Sambuc static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
344f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
345f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
346f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
347f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
348f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
349f4a2713aSLionel Sambuc static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
350f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
351f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
352f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
353f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
354f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
355f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
356f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
357f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
358f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
359f4a2713aSLionel Sambuc static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
360f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
361f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
362f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
363f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
364f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
365f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
366f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
367f4a2713aSLionel Sambuc static DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
368f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
369f4a2713aSLionel Sambuc static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
370f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
371f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val,
372f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
373f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
374f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
375f4a2713aSLionel Sambuc static DecodeStatus DecodeIT(MCInst &Inst, unsigned Val,
376f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
377f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn,
378f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
379f4a2713aSLionel Sambuc static DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn,
380f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder);
381f4a2713aSLionel Sambuc static DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val,
382f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
383f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
384f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
385f4a2713aSLionel Sambuc static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
386f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
387f4a2713aSLionel Sambuc 
388f4a2713aSLionel Sambuc static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
389f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
390f4a2713aSLionel Sambuc static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
391f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder);
392f4a2713aSLionel Sambuc #include "ARMGenDisassemblerTables.inc"
393f4a2713aSLionel Sambuc 
createARMDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)394*0a6a1f1dSLionel Sambuc static MCDisassembler *createARMDisassembler(const Target &T,
395*0a6a1f1dSLionel Sambuc                                              const MCSubtargetInfo &STI,
396*0a6a1f1dSLionel Sambuc                                              MCContext &Ctx) {
397*0a6a1f1dSLionel Sambuc   return new ARMDisassembler(STI, Ctx);
398f4a2713aSLionel Sambuc }
399f4a2713aSLionel Sambuc 
createThumbDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)400*0a6a1f1dSLionel Sambuc static MCDisassembler *createThumbDisassembler(const Target &T,
401*0a6a1f1dSLionel Sambuc                                                const MCSubtargetInfo &STI,
402*0a6a1f1dSLionel Sambuc                                                MCContext &Ctx) {
403*0a6a1f1dSLionel Sambuc   return new ThumbDisassembler(STI, Ctx);
404*0a6a1f1dSLionel Sambuc }
405*0a6a1f1dSLionel Sambuc 
406*0a6a1f1dSLionel Sambuc // Post-decoding checks
checkDecodedInstruction(MCInst & MI,uint64_t & Size,uint64_t Address,raw_ostream & OS,raw_ostream & CS,uint32_t Insn,DecodeStatus Result)407*0a6a1f1dSLionel Sambuc static DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,
408*0a6a1f1dSLionel Sambuc                                             uint64_t Address, raw_ostream &OS,
409*0a6a1f1dSLionel Sambuc                                             raw_ostream &CS,
410*0a6a1f1dSLionel Sambuc                                             uint32_t Insn,
411*0a6a1f1dSLionel Sambuc                                             DecodeStatus Result)
412*0a6a1f1dSLionel Sambuc {
413*0a6a1f1dSLionel Sambuc   switch (MI.getOpcode()) {
414*0a6a1f1dSLionel Sambuc     case ARM::HVC: {
415*0a6a1f1dSLionel Sambuc       // HVC is undefined if condition = 0xf otherwise upredictable
416*0a6a1f1dSLionel Sambuc       // if condition != 0xe
417*0a6a1f1dSLionel Sambuc       uint32_t Cond = (Insn >> 28) & 0xF;
418*0a6a1f1dSLionel Sambuc       if (Cond == 0xF)
419*0a6a1f1dSLionel Sambuc         return MCDisassembler::Fail;
420*0a6a1f1dSLionel Sambuc       if (Cond != 0xE)
421*0a6a1f1dSLionel Sambuc         return MCDisassembler::SoftFail;
422*0a6a1f1dSLionel Sambuc       return Result;
423*0a6a1f1dSLionel Sambuc     }
424*0a6a1f1dSLionel Sambuc     default: return Result;
425*0a6a1f1dSLionel Sambuc   }
426f4a2713aSLionel Sambuc }
427f4a2713aSLionel Sambuc 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const428f4a2713aSLionel Sambuc DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
429*0a6a1f1dSLionel Sambuc                                              ArrayRef<uint8_t> Bytes,
430*0a6a1f1dSLionel Sambuc                                              uint64_t Address, raw_ostream &OS,
431*0a6a1f1dSLionel Sambuc                                              raw_ostream &CS) const {
432*0a6a1f1dSLionel Sambuc   CommentStream = &CS;
433f4a2713aSLionel Sambuc 
434f4a2713aSLionel Sambuc   assert(!(STI.getFeatureBits() & ARM::ModeThumb) &&
435*0a6a1f1dSLionel Sambuc          "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
436*0a6a1f1dSLionel Sambuc          "mode!");
437f4a2713aSLionel Sambuc 
438f4a2713aSLionel Sambuc   // We want to read exactly 4 bytes of data.
439*0a6a1f1dSLionel Sambuc   if (Bytes.size() < 4) {
440f4a2713aSLionel Sambuc     Size = 0;
441f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
442f4a2713aSLionel Sambuc   }
443f4a2713aSLionel Sambuc 
444f4a2713aSLionel Sambuc   // Encoded as a small-endian 32-bit word in the stream.
445*0a6a1f1dSLionel Sambuc   uint32_t Insn =
446*0a6a1f1dSLionel Sambuc       (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
447f4a2713aSLionel Sambuc 
448f4a2713aSLionel Sambuc   // Calling the auto-generated decoder function.
449*0a6a1f1dSLionel Sambuc   DecodeStatus Result =
450*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI);
451*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
452f4a2713aSLionel Sambuc     Size = 4;
453*0a6a1f1dSLionel Sambuc     return checkDecodedInstruction(MI, Size, Address, OS, CS, Insn, Result);
454f4a2713aSLionel Sambuc   }
455f4a2713aSLionel Sambuc 
456f4a2713aSLionel Sambuc   // VFP and NEON instructions, similarly, are shared between ARM
457f4a2713aSLionel Sambuc   // and Thumb modes.
458f4a2713aSLionel Sambuc   MI.clear();
459*0a6a1f1dSLionel Sambuc   Result = decodeInstruction(DecoderTableVFP32, MI, Insn, Address, this, STI);
460*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
461f4a2713aSLionel Sambuc     Size = 4;
462*0a6a1f1dSLionel Sambuc     return Result;
463f4a2713aSLionel Sambuc   }
464f4a2713aSLionel Sambuc 
465f4a2713aSLionel Sambuc   MI.clear();
466*0a6a1f1dSLionel Sambuc   Result = decodeInstruction(DecoderTableVFPV832, MI, Insn, Address, this, STI);
467*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
468f4a2713aSLionel Sambuc     Size = 4;
469*0a6a1f1dSLionel Sambuc     return Result;
470f4a2713aSLionel Sambuc   }
471f4a2713aSLionel Sambuc 
472f4a2713aSLionel Sambuc   MI.clear();
473*0a6a1f1dSLionel Sambuc   Result =
474*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableNEONData32, MI, Insn, Address, this, STI);
475*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
476f4a2713aSLionel Sambuc     Size = 4;
477f4a2713aSLionel Sambuc     // Add a fake predicate operand, because we share these instruction
478f4a2713aSLionel Sambuc     // definitions with Thumb2 where these instructions are predicable.
479f4a2713aSLionel Sambuc     if (!DecodePredicateOperand(MI, 0xE, Address, this))
480f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
481*0a6a1f1dSLionel Sambuc     return Result;
482f4a2713aSLionel Sambuc   }
483f4a2713aSLionel Sambuc 
484f4a2713aSLionel Sambuc   MI.clear();
485*0a6a1f1dSLionel Sambuc   Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, Insn, Address,
486f4a2713aSLionel Sambuc                              this, STI);
487*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
488f4a2713aSLionel Sambuc     Size = 4;
489f4a2713aSLionel Sambuc     // Add a fake predicate operand, because we share these instruction
490f4a2713aSLionel Sambuc     // definitions with Thumb2 where these instructions are predicable.
491f4a2713aSLionel Sambuc     if (!DecodePredicateOperand(MI, 0xE, Address, this))
492f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
493*0a6a1f1dSLionel Sambuc     return Result;
494f4a2713aSLionel Sambuc   }
495f4a2713aSLionel Sambuc 
496f4a2713aSLionel Sambuc   MI.clear();
497*0a6a1f1dSLionel Sambuc   Result =
498*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableNEONDup32, MI, Insn, Address, this, STI);
499*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
500f4a2713aSLionel Sambuc     Size = 4;
501f4a2713aSLionel Sambuc     // Add a fake predicate operand, because we share these instruction
502f4a2713aSLionel Sambuc     // definitions with Thumb2 where these instructions are predicable.
503f4a2713aSLionel Sambuc     if (!DecodePredicateOperand(MI, 0xE, Address, this))
504f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
505*0a6a1f1dSLionel Sambuc     return Result;
506f4a2713aSLionel Sambuc   }
507f4a2713aSLionel Sambuc 
508f4a2713aSLionel Sambuc   MI.clear();
509*0a6a1f1dSLionel Sambuc   Result =
510*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTablev8NEON32, MI, Insn, Address, this, STI);
511*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
512f4a2713aSLionel Sambuc     Size = 4;
513*0a6a1f1dSLionel Sambuc     return Result;
514f4a2713aSLionel Sambuc   }
515f4a2713aSLionel Sambuc 
516f4a2713aSLionel Sambuc   MI.clear();
517*0a6a1f1dSLionel Sambuc   Result =
518*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTablev8Crypto32, MI, Insn, Address, this, STI);
519*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
520f4a2713aSLionel Sambuc     Size = 4;
521*0a6a1f1dSLionel Sambuc     return Result;
522f4a2713aSLionel Sambuc   }
523f4a2713aSLionel Sambuc 
524f4a2713aSLionel Sambuc   MI.clear();
525f4a2713aSLionel Sambuc   Size = 0;
526f4a2713aSLionel Sambuc   return MCDisassembler::Fail;
527f4a2713aSLionel Sambuc }
528f4a2713aSLionel Sambuc 
529f4a2713aSLionel Sambuc namespace llvm {
530f4a2713aSLionel Sambuc extern const MCInstrDesc ARMInsts[];
531f4a2713aSLionel Sambuc }
532f4a2713aSLionel Sambuc 
533f4a2713aSLionel Sambuc /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
534f4a2713aSLionel Sambuc /// immediate Value in the MCInst.  The immediate Value has had any PC
535f4a2713aSLionel Sambuc /// adjustment made by the caller.  If the instruction is a branch instruction
536f4a2713aSLionel Sambuc /// then isBranch is true, else false.  If the getOpInfo() function was set as
537f4a2713aSLionel Sambuc /// part of the setupForSymbolicDisassembly() call then that function is called
538f4a2713aSLionel Sambuc /// to get any symbolic information at the Address for this instruction.  If
539f4a2713aSLionel Sambuc /// that returns non-zero then the symbolic information it returns is used to
540f4a2713aSLionel Sambuc /// create an MCExpr and that is added as an operand to the MCInst.  If
541f4a2713aSLionel Sambuc /// getOpInfo() returns zero and isBranch is true then a symbol look up for
542f4a2713aSLionel Sambuc /// Value is done and if a symbol is found an MCExpr is created with that, else
543f4a2713aSLionel Sambuc /// an MCExpr with Value is created.  This function returns true if it adds an
544f4a2713aSLionel Sambuc /// operand to the MCInst and false otherwise.
tryAddingSymbolicOperand(uint64_t Address,int32_t Value,bool isBranch,uint64_t InstSize,MCInst & MI,const void * Decoder)545f4a2713aSLionel Sambuc static bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
546f4a2713aSLionel Sambuc                                      bool isBranch, uint64_t InstSize,
547f4a2713aSLionel Sambuc                                      MCInst &MI, const void *Decoder) {
548f4a2713aSLionel Sambuc   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
549f4a2713aSLionel Sambuc   // FIXME: Does it make sense for value to be negative?
550f4a2713aSLionel Sambuc   return Dis->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address, isBranch,
551f4a2713aSLionel Sambuc                                        /* Offset */ 0, InstSize);
552f4a2713aSLionel Sambuc }
553f4a2713aSLionel Sambuc 
554f4a2713aSLionel Sambuc /// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
555f4a2713aSLionel Sambuc /// referenced by a load instruction with the base register that is the Pc.
556f4a2713aSLionel Sambuc /// These can often be values in a literal pool near the Address of the
557f4a2713aSLionel Sambuc /// instruction.  The Address of the instruction and its immediate Value are
558f4a2713aSLionel Sambuc /// used as a possible literal pool entry.  The SymbolLookUp call back will
559f4a2713aSLionel Sambuc /// return the name of a symbol referenced by the literal pool's entry if
560f4a2713aSLionel Sambuc /// the referenced address is that of a symbol.  Or it will return a pointer to
561f4a2713aSLionel Sambuc /// a literal 'C' string if the referenced address of the literal pool's entry
562f4a2713aSLionel Sambuc /// is an address into a section with 'C' string literals.
tryAddingPcLoadReferenceComment(uint64_t Address,int Value,const void * Decoder)563f4a2713aSLionel Sambuc static void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
564f4a2713aSLionel Sambuc                                             const void *Decoder) {
565f4a2713aSLionel Sambuc   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
566f4a2713aSLionel Sambuc   Dis->tryAddingPcLoadReferenceComment(Value, Address);
567f4a2713aSLionel Sambuc }
568f4a2713aSLionel Sambuc 
569f4a2713aSLionel Sambuc // Thumb1 instructions don't have explicit S bits.  Rather, they
570f4a2713aSLionel Sambuc // implicitly set CPSR.  Since it's not represented in the encoding, the
571f4a2713aSLionel Sambuc // auto-generated decoder won't inject the CPSR operand.  We need to fix
572f4a2713aSLionel Sambuc // that as a post-pass.
AddThumb1SBit(MCInst & MI,bool InITBlock)573f4a2713aSLionel Sambuc static void AddThumb1SBit(MCInst &MI, bool InITBlock) {
574f4a2713aSLionel Sambuc   const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
575f4a2713aSLionel Sambuc   unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
576f4a2713aSLionel Sambuc   MCInst::iterator I = MI.begin();
577f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumOps; ++i, ++I) {
578f4a2713aSLionel Sambuc     if (I == MI.end()) break;
579f4a2713aSLionel Sambuc     if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
580f4a2713aSLionel Sambuc       if (i > 0 && OpInfo[i-1].isPredicate()) continue;
581f4a2713aSLionel Sambuc       MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
582f4a2713aSLionel Sambuc       return;
583f4a2713aSLionel Sambuc     }
584f4a2713aSLionel Sambuc   }
585f4a2713aSLionel Sambuc 
586f4a2713aSLionel Sambuc   MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
587f4a2713aSLionel Sambuc }
588f4a2713aSLionel Sambuc 
589f4a2713aSLionel Sambuc // Most Thumb instructions don't have explicit predicates in the
590f4a2713aSLionel Sambuc // encoding, but rather get their predicates from IT context.  We need
591f4a2713aSLionel Sambuc // to fix up the predicate operands using this context information as a
592f4a2713aSLionel Sambuc // post-pass.
593f4a2713aSLionel Sambuc MCDisassembler::DecodeStatus
AddThumbPredicate(MCInst & MI) const594f4a2713aSLionel Sambuc ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
595f4a2713aSLionel Sambuc   MCDisassembler::DecodeStatus S = Success;
596f4a2713aSLionel Sambuc 
597f4a2713aSLionel Sambuc   // A few instructions actually have predicates encoded in them.  Don't
598f4a2713aSLionel Sambuc   // try to overwrite it if we're seeing one of those.
599f4a2713aSLionel Sambuc   switch (MI.getOpcode()) {
600f4a2713aSLionel Sambuc     case ARM::tBcc:
601f4a2713aSLionel Sambuc     case ARM::t2Bcc:
602f4a2713aSLionel Sambuc     case ARM::tCBZ:
603f4a2713aSLionel Sambuc     case ARM::tCBNZ:
604f4a2713aSLionel Sambuc     case ARM::tCPS:
605f4a2713aSLionel Sambuc     case ARM::t2CPS3p:
606f4a2713aSLionel Sambuc     case ARM::t2CPS2p:
607f4a2713aSLionel Sambuc     case ARM::t2CPS1p:
608f4a2713aSLionel Sambuc     case ARM::tMOVSr:
609f4a2713aSLionel Sambuc     case ARM::tSETEND:
610f4a2713aSLionel Sambuc       // Some instructions (mostly conditional branches) are not
611f4a2713aSLionel Sambuc       // allowed in IT blocks.
612f4a2713aSLionel Sambuc       if (ITBlock.instrInITBlock())
613f4a2713aSLionel Sambuc         S = SoftFail;
614f4a2713aSLionel Sambuc       else
615f4a2713aSLionel Sambuc         return Success;
616f4a2713aSLionel Sambuc       break;
617f4a2713aSLionel Sambuc     case ARM::tB:
618f4a2713aSLionel Sambuc     case ARM::t2B:
619f4a2713aSLionel Sambuc     case ARM::t2TBB:
620f4a2713aSLionel Sambuc     case ARM::t2TBH:
621f4a2713aSLionel Sambuc       // Some instructions (mostly unconditional branches) can
622f4a2713aSLionel Sambuc       // only appears at the end of, or outside of, an IT.
623f4a2713aSLionel Sambuc       if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
624f4a2713aSLionel Sambuc         S = SoftFail;
625f4a2713aSLionel Sambuc       break;
626f4a2713aSLionel Sambuc     default:
627f4a2713aSLionel Sambuc       break;
628f4a2713aSLionel Sambuc   }
629f4a2713aSLionel Sambuc 
630f4a2713aSLionel Sambuc   // If we're in an IT block, base the predicate on that.  Otherwise,
631f4a2713aSLionel Sambuc   // assume a predicate of AL.
632f4a2713aSLionel Sambuc   unsigned CC;
633f4a2713aSLionel Sambuc   CC = ITBlock.getITCC();
634f4a2713aSLionel Sambuc   if (CC == 0xF)
635f4a2713aSLionel Sambuc     CC = ARMCC::AL;
636f4a2713aSLionel Sambuc   if (ITBlock.instrInITBlock())
637f4a2713aSLionel Sambuc     ITBlock.advanceITState();
638f4a2713aSLionel Sambuc 
639f4a2713aSLionel Sambuc   const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
640f4a2713aSLionel Sambuc   unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
641f4a2713aSLionel Sambuc   MCInst::iterator I = MI.begin();
642f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumOps; ++i, ++I) {
643f4a2713aSLionel Sambuc     if (I == MI.end()) break;
644f4a2713aSLionel Sambuc     if (OpInfo[i].isPredicate()) {
645f4a2713aSLionel Sambuc       I = MI.insert(I, MCOperand::CreateImm(CC));
646f4a2713aSLionel Sambuc       ++I;
647f4a2713aSLionel Sambuc       if (CC == ARMCC::AL)
648f4a2713aSLionel Sambuc         MI.insert(I, MCOperand::CreateReg(0));
649f4a2713aSLionel Sambuc       else
650f4a2713aSLionel Sambuc         MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
651f4a2713aSLionel Sambuc       return S;
652f4a2713aSLionel Sambuc     }
653f4a2713aSLionel Sambuc   }
654f4a2713aSLionel Sambuc 
655f4a2713aSLionel Sambuc   I = MI.insert(I, MCOperand::CreateImm(CC));
656f4a2713aSLionel Sambuc   ++I;
657f4a2713aSLionel Sambuc   if (CC == ARMCC::AL)
658f4a2713aSLionel Sambuc     MI.insert(I, MCOperand::CreateReg(0));
659f4a2713aSLionel Sambuc   else
660f4a2713aSLionel Sambuc     MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
661f4a2713aSLionel Sambuc 
662f4a2713aSLionel Sambuc   return S;
663f4a2713aSLionel Sambuc }
664f4a2713aSLionel Sambuc 
665f4a2713aSLionel Sambuc // Thumb VFP instructions are a special case.  Because we share their
666f4a2713aSLionel Sambuc // encodings between ARM and Thumb modes, and they are predicable in ARM
667f4a2713aSLionel Sambuc // mode, the auto-generated decoder will give them an (incorrect)
668f4a2713aSLionel Sambuc // predicate operand.  We need to rewrite these operands based on the IT
669f4a2713aSLionel Sambuc // context as a post-pass.
UpdateThumbVFPPredicate(MCInst & MI) const670f4a2713aSLionel Sambuc void ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const {
671f4a2713aSLionel Sambuc   unsigned CC;
672f4a2713aSLionel Sambuc   CC = ITBlock.getITCC();
673f4a2713aSLionel Sambuc   if (ITBlock.instrInITBlock())
674f4a2713aSLionel Sambuc     ITBlock.advanceITState();
675f4a2713aSLionel Sambuc 
676f4a2713aSLionel Sambuc   const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
677f4a2713aSLionel Sambuc   MCInst::iterator I = MI.begin();
678f4a2713aSLionel Sambuc   unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
679f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumOps; ++i, ++I) {
680f4a2713aSLionel Sambuc     if (OpInfo[i].isPredicate() ) {
681f4a2713aSLionel Sambuc       I->setImm(CC);
682f4a2713aSLionel Sambuc       ++I;
683f4a2713aSLionel Sambuc       if (CC == ARMCC::AL)
684f4a2713aSLionel Sambuc         I->setReg(0);
685f4a2713aSLionel Sambuc       else
686f4a2713aSLionel Sambuc         I->setReg(ARM::CPSR);
687f4a2713aSLionel Sambuc       return;
688f4a2713aSLionel Sambuc     }
689f4a2713aSLionel Sambuc   }
690f4a2713aSLionel Sambuc }
691f4a2713aSLionel Sambuc 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const692f4a2713aSLionel Sambuc DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
693*0a6a1f1dSLionel Sambuc                                                ArrayRef<uint8_t> Bytes,
694f4a2713aSLionel Sambuc                                                uint64_t Address,
695*0a6a1f1dSLionel Sambuc                                                raw_ostream &OS,
696*0a6a1f1dSLionel Sambuc                                                raw_ostream &CS) const {
697*0a6a1f1dSLionel Sambuc   CommentStream = &CS;
698f4a2713aSLionel Sambuc 
699f4a2713aSLionel Sambuc   assert((STI.getFeatureBits() & ARM::ModeThumb) &&
700f4a2713aSLionel Sambuc          "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
701f4a2713aSLionel Sambuc 
702f4a2713aSLionel Sambuc   // We want to read exactly 2 bytes of data.
703*0a6a1f1dSLionel Sambuc   if (Bytes.size() < 2) {
704f4a2713aSLionel Sambuc     Size = 0;
705f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
706f4a2713aSLionel Sambuc   }
707f4a2713aSLionel Sambuc 
708*0a6a1f1dSLionel Sambuc   uint16_t Insn16 = (Bytes[1] << 8) | Bytes[0];
709*0a6a1f1dSLionel Sambuc   DecodeStatus Result =
710*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableThumb16, MI, Insn16, Address, this, STI);
711*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
712f4a2713aSLionel Sambuc     Size = 2;
713*0a6a1f1dSLionel Sambuc     Check(Result, AddThumbPredicate(MI));
714*0a6a1f1dSLionel Sambuc     return Result;
715f4a2713aSLionel Sambuc   }
716f4a2713aSLionel Sambuc 
717f4a2713aSLionel Sambuc   MI.clear();
718*0a6a1f1dSLionel Sambuc   Result = decodeInstruction(DecoderTableThumbSBit16, MI, Insn16, Address, this,
719*0a6a1f1dSLionel Sambuc                              STI);
720*0a6a1f1dSLionel Sambuc   if (Result) {
721f4a2713aSLionel Sambuc     Size = 2;
722f4a2713aSLionel Sambuc     bool InITBlock = ITBlock.instrInITBlock();
723*0a6a1f1dSLionel Sambuc     Check(Result, AddThumbPredicate(MI));
724f4a2713aSLionel Sambuc     AddThumb1SBit(MI, InITBlock);
725*0a6a1f1dSLionel Sambuc     return Result;
726f4a2713aSLionel Sambuc   }
727f4a2713aSLionel Sambuc 
728f4a2713aSLionel Sambuc   MI.clear();
729*0a6a1f1dSLionel Sambuc   Result =
730*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableThumb216, MI, Insn16, Address, this, STI);
731*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
732f4a2713aSLionel Sambuc     Size = 2;
733f4a2713aSLionel Sambuc 
734f4a2713aSLionel Sambuc     // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
735f4a2713aSLionel Sambuc     // the Thumb predicate.
736f4a2713aSLionel Sambuc     if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
737*0a6a1f1dSLionel Sambuc       Result = MCDisassembler::SoftFail;
738f4a2713aSLionel Sambuc 
739*0a6a1f1dSLionel Sambuc     Check(Result, AddThumbPredicate(MI));
740f4a2713aSLionel Sambuc 
741f4a2713aSLionel Sambuc     // If we find an IT instruction, we need to parse its condition
742f4a2713aSLionel Sambuc     // code and mask operands so that we can apply them correctly
743f4a2713aSLionel Sambuc     // to the subsequent instructions.
744f4a2713aSLionel Sambuc     if (MI.getOpcode() == ARM::t2IT) {
745f4a2713aSLionel Sambuc 
746f4a2713aSLionel Sambuc       unsigned Firstcond = MI.getOperand(0).getImm();
747f4a2713aSLionel Sambuc       unsigned Mask = MI.getOperand(1).getImm();
748f4a2713aSLionel Sambuc       ITBlock.setITState(Firstcond, Mask);
749f4a2713aSLionel Sambuc     }
750f4a2713aSLionel Sambuc 
751*0a6a1f1dSLionel Sambuc     return Result;
752f4a2713aSLionel Sambuc   }
753f4a2713aSLionel Sambuc 
754f4a2713aSLionel Sambuc   // We want to read exactly 4 bytes of data.
755*0a6a1f1dSLionel Sambuc   if (Bytes.size() < 4) {
756f4a2713aSLionel Sambuc     Size = 0;
757f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
758f4a2713aSLionel Sambuc   }
759f4a2713aSLionel Sambuc 
760*0a6a1f1dSLionel Sambuc   uint32_t Insn32 =
761*0a6a1f1dSLionel Sambuc       (Bytes[3] << 8) | (Bytes[2] << 0) | (Bytes[1] << 24) | (Bytes[0] << 16);
762f4a2713aSLionel Sambuc   MI.clear();
763*0a6a1f1dSLionel Sambuc   Result =
764*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
765*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
766f4a2713aSLionel Sambuc     Size = 4;
767f4a2713aSLionel Sambuc     bool InITBlock = ITBlock.instrInITBlock();
768*0a6a1f1dSLionel Sambuc     Check(Result, AddThumbPredicate(MI));
769f4a2713aSLionel Sambuc     AddThumb1SBit(MI, InITBlock);
770*0a6a1f1dSLionel Sambuc     return Result;
771f4a2713aSLionel Sambuc   }
772f4a2713aSLionel Sambuc 
773f4a2713aSLionel Sambuc   MI.clear();
774*0a6a1f1dSLionel Sambuc   Result =
775*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableThumb232, MI, Insn32, Address, this, STI);
776*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
777f4a2713aSLionel Sambuc     Size = 4;
778*0a6a1f1dSLionel Sambuc     Check(Result, AddThumbPredicate(MI));
779*0a6a1f1dSLionel Sambuc     return Result;
780f4a2713aSLionel Sambuc   }
781f4a2713aSLionel Sambuc 
782*0a6a1f1dSLionel Sambuc   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
783f4a2713aSLionel Sambuc     MI.clear();
784*0a6a1f1dSLionel Sambuc     Result =
785*0a6a1f1dSLionel Sambuc         decodeInstruction(DecoderTableVFP32, MI, Insn32, Address, this, STI);
786*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
787f4a2713aSLionel Sambuc       Size = 4;
788f4a2713aSLionel Sambuc       UpdateThumbVFPPredicate(MI);
789*0a6a1f1dSLionel Sambuc       return Result;
790f4a2713aSLionel Sambuc     }
791f4a2713aSLionel Sambuc   }
792f4a2713aSLionel Sambuc 
793f4a2713aSLionel Sambuc   MI.clear();
794*0a6a1f1dSLionel Sambuc   Result =
795*0a6a1f1dSLionel Sambuc       decodeInstruction(DecoderTableVFPV832, MI, Insn32, Address, this, STI);
796*0a6a1f1dSLionel Sambuc   if (Result != MCDisassembler::Fail) {
797f4a2713aSLionel Sambuc     Size = 4;
798*0a6a1f1dSLionel Sambuc     return Result;
799f4a2713aSLionel Sambuc   }
800f4a2713aSLionel Sambuc 
801*0a6a1f1dSLionel Sambuc   if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
802f4a2713aSLionel Sambuc     MI.clear();
803*0a6a1f1dSLionel Sambuc     Result = decodeInstruction(DecoderTableNEONDup32, MI, Insn32, Address, this,
804*0a6a1f1dSLionel Sambuc                                STI);
805*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
806f4a2713aSLionel Sambuc       Size = 4;
807*0a6a1f1dSLionel Sambuc       Check(Result, AddThumbPredicate(MI));
808*0a6a1f1dSLionel Sambuc       return Result;
809f4a2713aSLionel Sambuc     }
810f4a2713aSLionel Sambuc   }
811f4a2713aSLionel Sambuc 
812*0a6a1f1dSLionel Sambuc   if (fieldFromInstruction(Insn32, 24, 8) == 0xF9) {
813f4a2713aSLionel Sambuc     MI.clear();
814*0a6a1f1dSLionel Sambuc     uint32_t NEONLdStInsn = Insn32;
815f4a2713aSLionel Sambuc     NEONLdStInsn &= 0xF0FFFFFF;
816f4a2713aSLionel Sambuc     NEONLdStInsn |= 0x04000000;
817*0a6a1f1dSLionel Sambuc     Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
818f4a2713aSLionel Sambuc                                Address, this, STI);
819*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
820f4a2713aSLionel Sambuc       Size = 4;
821*0a6a1f1dSLionel Sambuc       Check(Result, AddThumbPredicate(MI));
822*0a6a1f1dSLionel Sambuc       return Result;
823f4a2713aSLionel Sambuc     }
824f4a2713aSLionel Sambuc   }
825f4a2713aSLionel Sambuc 
826*0a6a1f1dSLionel Sambuc   if (fieldFromInstruction(Insn32, 24, 4) == 0xF) {
827f4a2713aSLionel Sambuc     MI.clear();
828*0a6a1f1dSLionel Sambuc     uint32_t NEONDataInsn = Insn32;
829f4a2713aSLionel Sambuc     NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
830f4a2713aSLionel Sambuc     NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
831f4a2713aSLionel Sambuc     NEONDataInsn |= 0x12000000; // Set bits 28 and 25
832*0a6a1f1dSLionel Sambuc     Result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
833f4a2713aSLionel Sambuc                                Address, this, STI);
834*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
835f4a2713aSLionel Sambuc       Size = 4;
836*0a6a1f1dSLionel Sambuc       Check(Result, AddThumbPredicate(MI));
837*0a6a1f1dSLionel Sambuc       return Result;
838f4a2713aSLionel Sambuc     }
839f4a2713aSLionel Sambuc 
840f4a2713aSLionel Sambuc     MI.clear();
841*0a6a1f1dSLionel Sambuc     uint32_t NEONCryptoInsn = Insn32;
842f4a2713aSLionel Sambuc     NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
843f4a2713aSLionel Sambuc     NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
844f4a2713aSLionel Sambuc     NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
845*0a6a1f1dSLionel Sambuc     Result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
846f4a2713aSLionel Sambuc                                Address, this, STI);
847*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
848f4a2713aSLionel Sambuc       Size = 4;
849*0a6a1f1dSLionel Sambuc       return Result;
850f4a2713aSLionel Sambuc     }
851f4a2713aSLionel Sambuc 
852f4a2713aSLionel Sambuc     MI.clear();
853*0a6a1f1dSLionel Sambuc     uint32_t NEONv8Insn = Insn32;
854f4a2713aSLionel Sambuc     NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
855*0a6a1f1dSLionel Sambuc     Result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
856f4a2713aSLionel Sambuc                                this, STI);
857*0a6a1f1dSLionel Sambuc     if (Result != MCDisassembler::Fail) {
858f4a2713aSLionel Sambuc       Size = 4;
859*0a6a1f1dSLionel Sambuc       return Result;
860f4a2713aSLionel Sambuc     }
861f4a2713aSLionel Sambuc   }
862f4a2713aSLionel Sambuc 
863f4a2713aSLionel Sambuc   MI.clear();
864f4a2713aSLionel Sambuc   Size = 0;
865f4a2713aSLionel Sambuc   return MCDisassembler::Fail;
866f4a2713aSLionel Sambuc }
867f4a2713aSLionel Sambuc 
868f4a2713aSLionel Sambuc 
LLVMInitializeARMDisassembler()869f4a2713aSLionel Sambuc extern "C" void LLVMInitializeARMDisassembler() {
870*0a6a1f1dSLionel Sambuc   TargetRegistry::RegisterMCDisassembler(TheARMLETarget,
871f4a2713aSLionel Sambuc                                          createARMDisassembler);
872*0a6a1f1dSLionel Sambuc   TargetRegistry::RegisterMCDisassembler(TheARMBETarget,
873*0a6a1f1dSLionel Sambuc                                          createARMDisassembler);
874*0a6a1f1dSLionel Sambuc   TargetRegistry::RegisterMCDisassembler(TheThumbLETarget,
875*0a6a1f1dSLionel Sambuc                                          createThumbDisassembler);
876*0a6a1f1dSLionel Sambuc   TargetRegistry::RegisterMCDisassembler(TheThumbBETarget,
877f4a2713aSLionel Sambuc                                          createThumbDisassembler);
878f4a2713aSLionel Sambuc }
879f4a2713aSLionel Sambuc 
880f4a2713aSLionel Sambuc static const uint16_t GPRDecoderTable[] = {
881f4a2713aSLionel Sambuc   ARM::R0, ARM::R1, ARM::R2, ARM::R3,
882f4a2713aSLionel Sambuc   ARM::R4, ARM::R5, ARM::R6, ARM::R7,
883f4a2713aSLionel Sambuc   ARM::R8, ARM::R9, ARM::R10, ARM::R11,
884f4a2713aSLionel Sambuc   ARM::R12, ARM::SP, ARM::LR, ARM::PC
885f4a2713aSLionel Sambuc };
886f4a2713aSLionel Sambuc 
DecodeGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)887f4a2713aSLionel Sambuc static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
888f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
889f4a2713aSLionel Sambuc   if (RegNo > 15)
890f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
891f4a2713aSLionel Sambuc 
892f4a2713aSLionel Sambuc   unsigned Register = GPRDecoderTable[RegNo];
893f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Register));
894f4a2713aSLionel Sambuc   return MCDisassembler::Success;
895f4a2713aSLionel Sambuc }
896f4a2713aSLionel Sambuc 
897f4a2713aSLionel Sambuc static DecodeStatus
DecodeGPRnopcRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)898f4a2713aSLionel Sambuc DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
899f4a2713aSLionel Sambuc                            uint64_t Address, const void *Decoder) {
900f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
901f4a2713aSLionel Sambuc 
902f4a2713aSLionel Sambuc   if (RegNo == 15)
903f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
904f4a2713aSLionel Sambuc 
905f4a2713aSLionel Sambuc   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
906f4a2713aSLionel Sambuc 
907f4a2713aSLionel Sambuc   return S;
908f4a2713aSLionel Sambuc }
909f4a2713aSLionel Sambuc 
910f4a2713aSLionel Sambuc static DecodeStatus
DecodeGPRwithAPSRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)911f4a2713aSLionel Sambuc DecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo,
912f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
913f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
914f4a2713aSLionel Sambuc 
915f4a2713aSLionel Sambuc   if (RegNo == 15)
916f4a2713aSLionel Sambuc   {
917f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(ARM::APSR_NZCV));
918f4a2713aSLionel Sambuc     return MCDisassembler::Success;
919f4a2713aSLionel Sambuc   }
920f4a2713aSLionel Sambuc 
921f4a2713aSLionel Sambuc   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
922f4a2713aSLionel Sambuc   return S;
923f4a2713aSLionel Sambuc }
924f4a2713aSLionel Sambuc 
DecodetGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)925f4a2713aSLionel Sambuc static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
926f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
927f4a2713aSLionel Sambuc   if (RegNo > 7)
928f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
929f4a2713aSLionel Sambuc   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
930f4a2713aSLionel Sambuc }
931f4a2713aSLionel Sambuc 
932f4a2713aSLionel Sambuc static const uint16_t GPRPairDecoderTable[] = {
933f4a2713aSLionel Sambuc   ARM::R0_R1, ARM::R2_R3,   ARM::R4_R5,  ARM::R6_R7,
934f4a2713aSLionel Sambuc   ARM::R8_R9, ARM::R10_R11, ARM::R12_SP
935f4a2713aSLionel Sambuc };
936f4a2713aSLionel Sambuc 
DecodeGPRPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)937f4a2713aSLionel Sambuc static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
938f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
939f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
940f4a2713aSLionel Sambuc 
941f4a2713aSLionel Sambuc   if (RegNo > 13)
942f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
943f4a2713aSLionel Sambuc 
944f4a2713aSLionel Sambuc   if ((RegNo & 1) || RegNo == 0xe)
945f4a2713aSLionel Sambuc      S = MCDisassembler::SoftFail;
946f4a2713aSLionel Sambuc 
947f4a2713aSLionel Sambuc   unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
948f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(RegisterPair));
949f4a2713aSLionel Sambuc   return S;
950f4a2713aSLionel Sambuc }
951f4a2713aSLionel Sambuc 
DecodetcGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)952f4a2713aSLionel Sambuc static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
953f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
954f4a2713aSLionel Sambuc   unsigned Register = 0;
955f4a2713aSLionel Sambuc   switch (RegNo) {
956f4a2713aSLionel Sambuc     case 0:
957f4a2713aSLionel Sambuc       Register = ARM::R0;
958f4a2713aSLionel Sambuc       break;
959f4a2713aSLionel Sambuc     case 1:
960f4a2713aSLionel Sambuc       Register = ARM::R1;
961f4a2713aSLionel Sambuc       break;
962f4a2713aSLionel Sambuc     case 2:
963f4a2713aSLionel Sambuc       Register = ARM::R2;
964f4a2713aSLionel Sambuc       break;
965f4a2713aSLionel Sambuc     case 3:
966f4a2713aSLionel Sambuc       Register = ARM::R3;
967f4a2713aSLionel Sambuc       break;
968f4a2713aSLionel Sambuc     case 9:
969f4a2713aSLionel Sambuc       Register = ARM::R9;
970f4a2713aSLionel Sambuc       break;
971f4a2713aSLionel Sambuc     case 12:
972f4a2713aSLionel Sambuc       Register = ARM::R12;
973f4a2713aSLionel Sambuc       break;
974f4a2713aSLionel Sambuc     default:
975f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
976f4a2713aSLionel Sambuc     }
977f4a2713aSLionel Sambuc 
978f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Register));
979f4a2713aSLionel Sambuc   return MCDisassembler::Success;
980f4a2713aSLionel Sambuc }
981f4a2713aSLionel Sambuc 
DecoderGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)982f4a2713aSLionel Sambuc static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
983f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
984f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
985f4a2713aSLionel Sambuc   if (RegNo == 13 || RegNo == 15)
986f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
987f4a2713aSLionel Sambuc   Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
988f4a2713aSLionel Sambuc   return S;
989f4a2713aSLionel Sambuc }
990f4a2713aSLionel Sambuc 
991f4a2713aSLionel Sambuc static const uint16_t SPRDecoderTable[] = {
992f4a2713aSLionel Sambuc      ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
993f4a2713aSLionel Sambuc      ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
994f4a2713aSLionel Sambuc      ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
995f4a2713aSLionel Sambuc     ARM::S12, ARM::S13, ARM::S14, ARM::S15,
996f4a2713aSLionel Sambuc     ARM::S16, ARM::S17, ARM::S18, ARM::S19,
997f4a2713aSLionel Sambuc     ARM::S20, ARM::S21, ARM::S22, ARM::S23,
998f4a2713aSLionel Sambuc     ARM::S24, ARM::S25, ARM::S26, ARM::S27,
999f4a2713aSLionel Sambuc     ARM::S28, ARM::S29, ARM::S30, ARM::S31
1000f4a2713aSLionel Sambuc };
1001f4a2713aSLionel Sambuc 
DecodeSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1002f4a2713aSLionel Sambuc static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
1003f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
1004f4a2713aSLionel Sambuc   if (RegNo > 31)
1005f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1006f4a2713aSLionel Sambuc 
1007f4a2713aSLionel Sambuc   unsigned Register = SPRDecoderTable[RegNo];
1008f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Register));
1009f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1010f4a2713aSLionel Sambuc }
1011f4a2713aSLionel Sambuc 
1012f4a2713aSLionel Sambuc static const uint16_t DPRDecoderTable[] = {
1013f4a2713aSLionel Sambuc      ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
1014f4a2713aSLionel Sambuc      ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
1015f4a2713aSLionel Sambuc      ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
1016f4a2713aSLionel Sambuc     ARM::D12, ARM::D13, ARM::D14, ARM::D15,
1017f4a2713aSLionel Sambuc     ARM::D16, ARM::D17, ARM::D18, ARM::D19,
1018f4a2713aSLionel Sambuc     ARM::D20, ARM::D21, ARM::D22, ARM::D23,
1019f4a2713aSLionel Sambuc     ARM::D24, ARM::D25, ARM::D26, ARM::D27,
1020f4a2713aSLionel Sambuc     ARM::D28, ARM::D29, ARM::D30, ARM::D31
1021f4a2713aSLionel Sambuc };
1022f4a2713aSLionel Sambuc 
DecodeDPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1023f4a2713aSLionel Sambuc static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
1024f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
1025*0a6a1f1dSLionel Sambuc   uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
1026*0a6a1f1dSLionel Sambuc                                                           .getFeatureBits();
1027*0a6a1f1dSLionel Sambuc   bool hasD16 = featureBits & ARM::FeatureD16;
1028*0a6a1f1dSLionel Sambuc 
1029*0a6a1f1dSLionel Sambuc   if (RegNo > 31 || (hasD16 && RegNo > 15))
1030f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1031f4a2713aSLionel Sambuc 
1032f4a2713aSLionel Sambuc   unsigned Register = DPRDecoderTable[RegNo];
1033f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Register));
1034f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1035f4a2713aSLionel Sambuc }
1036f4a2713aSLionel Sambuc 
DecodeDPR_8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1037f4a2713aSLionel Sambuc static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1038f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
1039f4a2713aSLionel Sambuc   if (RegNo > 7)
1040f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1041f4a2713aSLionel Sambuc   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
1042f4a2713aSLionel Sambuc }
1043f4a2713aSLionel Sambuc 
1044f4a2713aSLionel Sambuc static DecodeStatus
DecodeDPR_VFP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1045f4a2713aSLionel Sambuc DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
1046f4a2713aSLionel Sambuc                             uint64_t Address, const void *Decoder) {
1047f4a2713aSLionel Sambuc   if (RegNo > 15)
1048f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1049f4a2713aSLionel Sambuc   return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
1050f4a2713aSLionel Sambuc }
1051f4a2713aSLionel Sambuc 
1052f4a2713aSLionel Sambuc static const uint16_t QPRDecoderTable[] = {
1053f4a2713aSLionel Sambuc      ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
1054f4a2713aSLionel Sambuc      ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
1055f4a2713aSLionel Sambuc      ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
1056f4a2713aSLionel Sambuc     ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
1057f4a2713aSLionel Sambuc };
1058f4a2713aSLionel Sambuc 
1059f4a2713aSLionel Sambuc 
DecodeQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1060f4a2713aSLionel Sambuc static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
1061f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
1062f4a2713aSLionel Sambuc   if (RegNo > 31 || (RegNo & 1) != 0)
1063f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1064f4a2713aSLionel Sambuc   RegNo >>= 1;
1065f4a2713aSLionel Sambuc 
1066f4a2713aSLionel Sambuc   unsigned Register = QPRDecoderTable[RegNo];
1067f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Register));
1068f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1069f4a2713aSLionel Sambuc }
1070f4a2713aSLionel Sambuc 
1071f4a2713aSLionel Sambuc static const uint16_t DPairDecoderTable[] = {
1072f4a2713aSLionel Sambuc   ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
1073f4a2713aSLionel Sambuc   ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
1074f4a2713aSLionel Sambuc   ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
1075f4a2713aSLionel Sambuc   ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
1076f4a2713aSLionel Sambuc   ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
1077f4a2713aSLionel Sambuc   ARM::Q15
1078f4a2713aSLionel Sambuc };
1079f4a2713aSLionel Sambuc 
DecodeDPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1080f4a2713aSLionel Sambuc static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
1081f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
1082f4a2713aSLionel Sambuc   if (RegNo > 30)
1083f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1084f4a2713aSLionel Sambuc 
1085f4a2713aSLionel Sambuc   unsigned Register = DPairDecoderTable[RegNo];
1086f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Register));
1087f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1088f4a2713aSLionel Sambuc }
1089f4a2713aSLionel Sambuc 
1090f4a2713aSLionel Sambuc static const uint16_t DPairSpacedDecoderTable[] = {
1091f4a2713aSLionel Sambuc   ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
1092f4a2713aSLionel Sambuc   ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
1093f4a2713aSLionel Sambuc   ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
1094f4a2713aSLionel Sambuc   ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
1095f4a2713aSLionel Sambuc   ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
1096f4a2713aSLionel Sambuc   ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
1097f4a2713aSLionel Sambuc   ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
1098f4a2713aSLionel Sambuc   ARM::D28_D30, ARM::D29_D31
1099f4a2713aSLionel Sambuc };
1100f4a2713aSLionel Sambuc 
DecodeDPairSpacedRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1101f4a2713aSLionel Sambuc static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
1102f4a2713aSLionel Sambuc                                                    unsigned RegNo,
1103f4a2713aSLionel Sambuc                                                    uint64_t Address,
1104f4a2713aSLionel Sambuc                                                    const void *Decoder) {
1105f4a2713aSLionel Sambuc   if (RegNo > 29)
1106f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1107f4a2713aSLionel Sambuc 
1108f4a2713aSLionel Sambuc   unsigned Register = DPairSpacedDecoderTable[RegNo];
1109f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(Register));
1110f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1111f4a2713aSLionel Sambuc }
1112f4a2713aSLionel Sambuc 
DecodePredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1113f4a2713aSLionel Sambuc static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
1114f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
1115f4a2713aSLionel Sambuc   if (Val == 0xF) return MCDisassembler::Fail;
1116f4a2713aSLionel Sambuc   // AL predicate is not allowed on Thumb1 branches.
1117f4a2713aSLionel Sambuc   if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
1118f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1119f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Val));
1120f4a2713aSLionel Sambuc   if (Val == ARMCC::AL) {
1121f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(0));
1122f4a2713aSLionel Sambuc   } else
1123f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1124f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1125f4a2713aSLionel Sambuc }
1126f4a2713aSLionel Sambuc 
DecodeCCOutOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1127f4a2713aSLionel Sambuc static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
1128f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
1129f4a2713aSLionel Sambuc   if (Val)
1130f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1131f4a2713aSLionel Sambuc   else
1132f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(0));
1133f4a2713aSLionel Sambuc   return MCDisassembler::Success;
1134f4a2713aSLionel Sambuc }
1135f4a2713aSLionel Sambuc 
DecodeSORegImmOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1136f4a2713aSLionel Sambuc static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
1137f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
1138f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1139f4a2713aSLionel Sambuc 
1140f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Val, 0, 4);
1141f4a2713aSLionel Sambuc   unsigned type = fieldFromInstruction(Val, 5, 2);
1142f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 7, 5);
1143f4a2713aSLionel Sambuc 
1144f4a2713aSLionel Sambuc   // Register-immediate
1145f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1146f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1147f4a2713aSLionel Sambuc 
1148f4a2713aSLionel Sambuc   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1149f4a2713aSLionel Sambuc   switch (type) {
1150f4a2713aSLionel Sambuc     case 0:
1151f4a2713aSLionel Sambuc       Shift = ARM_AM::lsl;
1152f4a2713aSLionel Sambuc       break;
1153f4a2713aSLionel Sambuc     case 1:
1154f4a2713aSLionel Sambuc       Shift = ARM_AM::lsr;
1155f4a2713aSLionel Sambuc       break;
1156f4a2713aSLionel Sambuc     case 2:
1157f4a2713aSLionel Sambuc       Shift = ARM_AM::asr;
1158f4a2713aSLionel Sambuc       break;
1159f4a2713aSLionel Sambuc     case 3:
1160f4a2713aSLionel Sambuc       Shift = ARM_AM::ror;
1161f4a2713aSLionel Sambuc       break;
1162f4a2713aSLionel Sambuc   }
1163f4a2713aSLionel Sambuc 
1164f4a2713aSLionel Sambuc   if (Shift == ARM_AM::ror && imm == 0)
1165f4a2713aSLionel Sambuc     Shift = ARM_AM::rrx;
1166f4a2713aSLionel Sambuc 
1167f4a2713aSLionel Sambuc   unsigned Op = Shift | (imm << 3);
1168f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Op));
1169f4a2713aSLionel Sambuc 
1170f4a2713aSLionel Sambuc   return S;
1171f4a2713aSLionel Sambuc }
1172f4a2713aSLionel Sambuc 
DecodeSORegRegOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1173f4a2713aSLionel Sambuc static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
1174f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
1175f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1176f4a2713aSLionel Sambuc 
1177f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Val, 0, 4);
1178f4a2713aSLionel Sambuc   unsigned type = fieldFromInstruction(Val, 5, 2);
1179f4a2713aSLionel Sambuc   unsigned Rs = fieldFromInstruction(Val, 8, 4);
1180f4a2713aSLionel Sambuc 
1181f4a2713aSLionel Sambuc   // Register-register
1182f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1183f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1184f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
1185f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1186f4a2713aSLionel Sambuc 
1187f4a2713aSLionel Sambuc   ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1188f4a2713aSLionel Sambuc   switch (type) {
1189f4a2713aSLionel Sambuc     case 0:
1190f4a2713aSLionel Sambuc       Shift = ARM_AM::lsl;
1191f4a2713aSLionel Sambuc       break;
1192f4a2713aSLionel Sambuc     case 1:
1193f4a2713aSLionel Sambuc       Shift = ARM_AM::lsr;
1194f4a2713aSLionel Sambuc       break;
1195f4a2713aSLionel Sambuc     case 2:
1196f4a2713aSLionel Sambuc       Shift = ARM_AM::asr;
1197f4a2713aSLionel Sambuc       break;
1198f4a2713aSLionel Sambuc     case 3:
1199f4a2713aSLionel Sambuc       Shift = ARM_AM::ror;
1200f4a2713aSLionel Sambuc       break;
1201f4a2713aSLionel Sambuc   }
1202f4a2713aSLionel Sambuc 
1203f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Shift));
1204f4a2713aSLionel Sambuc 
1205f4a2713aSLionel Sambuc   return S;
1206f4a2713aSLionel Sambuc }
1207f4a2713aSLionel Sambuc 
DecodeRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1208f4a2713aSLionel Sambuc static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
1209f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
1210f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1211f4a2713aSLionel Sambuc 
1212f4a2713aSLionel Sambuc   bool NeedDisjointWriteback = false;
1213f4a2713aSLionel Sambuc   unsigned WritebackReg = 0;
1214f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
1215f4a2713aSLionel Sambuc   default:
1216f4a2713aSLionel Sambuc     break;
1217f4a2713aSLionel Sambuc   case ARM::LDMIA_UPD:
1218f4a2713aSLionel Sambuc   case ARM::LDMDB_UPD:
1219f4a2713aSLionel Sambuc   case ARM::LDMIB_UPD:
1220f4a2713aSLionel Sambuc   case ARM::LDMDA_UPD:
1221f4a2713aSLionel Sambuc   case ARM::t2LDMIA_UPD:
1222f4a2713aSLionel Sambuc   case ARM::t2LDMDB_UPD:
1223f4a2713aSLionel Sambuc   case ARM::t2STMIA_UPD:
1224f4a2713aSLionel Sambuc   case ARM::t2STMDB_UPD:
1225f4a2713aSLionel Sambuc     NeedDisjointWriteback = true;
1226f4a2713aSLionel Sambuc     WritebackReg = Inst.getOperand(0).getReg();
1227f4a2713aSLionel Sambuc     break;
1228f4a2713aSLionel Sambuc   }
1229f4a2713aSLionel Sambuc 
1230f4a2713aSLionel Sambuc   // Empty register lists are not allowed.
1231f4a2713aSLionel Sambuc   if (Val == 0) return MCDisassembler::Fail;
1232f4a2713aSLionel Sambuc   for (unsigned i = 0; i < 16; ++i) {
1233f4a2713aSLionel Sambuc     if (Val & (1 << i)) {
1234f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
1235f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1236f4a2713aSLionel Sambuc       // Writeback not allowed if Rn is in the target list.
1237f4a2713aSLionel Sambuc       if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg())
1238f4a2713aSLionel Sambuc         Check(S, MCDisassembler::SoftFail);
1239f4a2713aSLionel Sambuc     }
1240f4a2713aSLionel Sambuc   }
1241f4a2713aSLionel Sambuc 
1242f4a2713aSLionel Sambuc   return S;
1243f4a2713aSLionel Sambuc }
1244f4a2713aSLionel Sambuc 
DecodeSPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1245f4a2713aSLionel Sambuc static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
1246f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
1247f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1248f4a2713aSLionel Sambuc 
1249f4a2713aSLionel Sambuc   unsigned Vd = fieldFromInstruction(Val, 8, 5);
1250f4a2713aSLionel Sambuc   unsigned regs = fieldFromInstruction(Val, 0, 8);
1251f4a2713aSLionel Sambuc 
1252f4a2713aSLionel Sambuc   // In case of unpredictable encoding, tweak the operands.
1253f4a2713aSLionel Sambuc   if (regs == 0 || (Vd + regs) > 32) {
1254f4a2713aSLionel Sambuc     regs = Vd + regs > 32 ? 32 - Vd : regs;
1255f4a2713aSLionel Sambuc     regs = std::max( 1u, regs);
1256f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
1257f4a2713aSLionel Sambuc   }
1258f4a2713aSLionel Sambuc 
1259f4a2713aSLionel Sambuc   if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
1260f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1261f4a2713aSLionel Sambuc   for (unsigned i = 0; i < (regs - 1); ++i) {
1262f4a2713aSLionel Sambuc     if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1263f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
1264f4a2713aSLionel Sambuc   }
1265f4a2713aSLionel Sambuc 
1266f4a2713aSLionel Sambuc   return S;
1267f4a2713aSLionel Sambuc }
1268f4a2713aSLionel Sambuc 
DecodeDPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1269f4a2713aSLionel Sambuc static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
1270f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
1271f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1272f4a2713aSLionel Sambuc 
1273f4a2713aSLionel Sambuc   unsigned Vd = fieldFromInstruction(Val, 8, 5);
1274f4a2713aSLionel Sambuc   unsigned regs = fieldFromInstruction(Val, 1, 7);
1275f4a2713aSLionel Sambuc 
1276f4a2713aSLionel Sambuc   // In case of unpredictable encoding, tweak the operands.
1277f4a2713aSLionel Sambuc   if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
1278f4a2713aSLionel Sambuc     regs = Vd + regs > 32 ? 32 - Vd : regs;
1279f4a2713aSLionel Sambuc     regs = std::max( 1u, regs);
1280f4a2713aSLionel Sambuc     regs = std::min(16u, regs);
1281f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
1282f4a2713aSLionel Sambuc   }
1283f4a2713aSLionel Sambuc 
1284f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
1285f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
1286f4a2713aSLionel Sambuc   for (unsigned i = 0; i < (regs - 1); ++i) {
1287f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1288f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
1289f4a2713aSLionel Sambuc   }
1290f4a2713aSLionel Sambuc 
1291f4a2713aSLionel Sambuc   return S;
1292f4a2713aSLionel Sambuc }
1293f4a2713aSLionel Sambuc 
DecodeBitfieldMaskOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1294f4a2713aSLionel Sambuc static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
1295f4a2713aSLionel Sambuc                                       uint64_t Address, const void *Decoder) {
1296f4a2713aSLionel Sambuc   // This operand encodes a mask of contiguous zeros between a specified MSB
1297f4a2713aSLionel Sambuc   // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
1298f4a2713aSLionel Sambuc   // the mask of all bits LSB-and-lower, and then xor them to create
1299f4a2713aSLionel Sambuc   // the mask of that's all ones on [msb, lsb].  Finally we not it to
1300f4a2713aSLionel Sambuc   // create the final mask.
1301f4a2713aSLionel Sambuc   unsigned msb = fieldFromInstruction(Val, 5, 5);
1302f4a2713aSLionel Sambuc   unsigned lsb = fieldFromInstruction(Val, 0, 5);
1303f4a2713aSLionel Sambuc 
1304f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1305f4a2713aSLionel Sambuc   if (lsb > msb) {
1306f4a2713aSLionel Sambuc     Check(S, MCDisassembler::SoftFail);
1307f4a2713aSLionel Sambuc     // The check above will cause the warning for the "potentially undefined
1308f4a2713aSLionel Sambuc     // instruction encoding" but we can't build a bad MCOperand value here
1309f4a2713aSLionel Sambuc     // with a lsb > msb or else printing the MCInst will cause a crash.
1310f4a2713aSLionel Sambuc     lsb = msb;
1311f4a2713aSLionel Sambuc   }
1312f4a2713aSLionel Sambuc 
1313f4a2713aSLionel Sambuc   uint32_t msb_mask = 0xFFFFFFFF;
1314f4a2713aSLionel Sambuc   if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
1315f4a2713aSLionel Sambuc   uint32_t lsb_mask = (1U << lsb) - 1;
1316f4a2713aSLionel Sambuc 
1317f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask)));
1318f4a2713aSLionel Sambuc   return S;
1319f4a2713aSLionel Sambuc }
1320f4a2713aSLionel Sambuc 
DecodeCopMemInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1321f4a2713aSLionel Sambuc static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
1322f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
1323f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1324f4a2713aSLionel Sambuc 
1325f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
1326f4a2713aSLionel Sambuc   unsigned CRd = fieldFromInstruction(Insn, 12, 4);
1327f4a2713aSLionel Sambuc   unsigned coproc = fieldFromInstruction(Insn, 8, 4);
1328f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 8);
1329f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1330f4a2713aSLionel Sambuc   unsigned U = fieldFromInstruction(Insn, 23, 1);
1331f4a2713aSLionel Sambuc 
1332f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
1333f4a2713aSLionel Sambuc     case ARM::LDC_OFFSET:
1334f4a2713aSLionel Sambuc     case ARM::LDC_PRE:
1335f4a2713aSLionel Sambuc     case ARM::LDC_POST:
1336f4a2713aSLionel Sambuc     case ARM::LDC_OPTION:
1337f4a2713aSLionel Sambuc     case ARM::LDCL_OFFSET:
1338f4a2713aSLionel Sambuc     case ARM::LDCL_PRE:
1339f4a2713aSLionel Sambuc     case ARM::LDCL_POST:
1340f4a2713aSLionel Sambuc     case ARM::LDCL_OPTION:
1341f4a2713aSLionel Sambuc     case ARM::STC_OFFSET:
1342f4a2713aSLionel Sambuc     case ARM::STC_PRE:
1343f4a2713aSLionel Sambuc     case ARM::STC_POST:
1344f4a2713aSLionel Sambuc     case ARM::STC_OPTION:
1345f4a2713aSLionel Sambuc     case ARM::STCL_OFFSET:
1346f4a2713aSLionel Sambuc     case ARM::STCL_PRE:
1347f4a2713aSLionel Sambuc     case ARM::STCL_POST:
1348f4a2713aSLionel Sambuc     case ARM::STCL_OPTION:
1349f4a2713aSLionel Sambuc     case ARM::t2LDC_OFFSET:
1350f4a2713aSLionel Sambuc     case ARM::t2LDC_PRE:
1351f4a2713aSLionel Sambuc     case ARM::t2LDC_POST:
1352f4a2713aSLionel Sambuc     case ARM::t2LDC_OPTION:
1353f4a2713aSLionel Sambuc     case ARM::t2LDCL_OFFSET:
1354f4a2713aSLionel Sambuc     case ARM::t2LDCL_PRE:
1355f4a2713aSLionel Sambuc     case ARM::t2LDCL_POST:
1356f4a2713aSLionel Sambuc     case ARM::t2LDCL_OPTION:
1357f4a2713aSLionel Sambuc     case ARM::t2STC_OFFSET:
1358f4a2713aSLionel Sambuc     case ARM::t2STC_PRE:
1359f4a2713aSLionel Sambuc     case ARM::t2STC_POST:
1360f4a2713aSLionel Sambuc     case ARM::t2STC_OPTION:
1361f4a2713aSLionel Sambuc     case ARM::t2STCL_OFFSET:
1362f4a2713aSLionel Sambuc     case ARM::t2STCL_PRE:
1363f4a2713aSLionel Sambuc     case ARM::t2STCL_POST:
1364f4a2713aSLionel Sambuc     case ARM::t2STCL_OPTION:
1365f4a2713aSLionel Sambuc       if (coproc == 0xA || coproc == 0xB)
1366f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1367f4a2713aSLionel Sambuc       break;
1368f4a2713aSLionel Sambuc     default:
1369f4a2713aSLionel Sambuc       break;
1370f4a2713aSLionel Sambuc   }
1371f4a2713aSLionel Sambuc 
1372f4a2713aSLionel Sambuc   uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
1373f4a2713aSLionel Sambuc                                                           .getFeatureBits();
1374f4a2713aSLionel Sambuc   if ((featureBits & ARM::HasV8Ops) && (coproc != 14))
1375f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1376f4a2713aSLionel Sambuc 
1377f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(coproc));
1378f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(CRd));
1379f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1380f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1381f4a2713aSLionel Sambuc 
1382f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
1383f4a2713aSLionel Sambuc     case ARM::t2LDC2_OFFSET:
1384f4a2713aSLionel Sambuc     case ARM::t2LDC2L_OFFSET:
1385f4a2713aSLionel Sambuc     case ARM::t2LDC2_PRE:
1386f4a2713aSLionel Sambuc     case ARM::t2LDC2L_PRE:
1387f4a2713aSLionel Sambuc     case ARM::t2STC2_OFFSET:
1388f4a2713aSLionel Sambuc     case ARM::t2STC2L_OFFSET:
1389f4a2713aSLionel Sambuc     case ARM::t2STC2_PRE:
1390f4a2713aSLionel Sambuc     case ARM::t2STC2L_PRE:
1391f4a2713aSLionel Sambuc     case ARM::LDC2_OFFSET:
1392f4a2713aSLionel Sambuc     case ARM::LDC2L_OFFSET:
1393f4a2713aSLionel Sambuc     case ARM::LDC2_PRE:
1394f4a2713aSLionel Sambuc     case ARM::LDC2L_PRE:
1395f4a2713aSLionel Sambuc     case ARM::STC2_OFFSET:
1396f4a2713aSLionel Sambuc     case ARM::STC2L_OFFSET:
1397f4a2713aSLionel Sambuc     case ARM::STC2_PRE:
1398f4a2713aSLionel Sambuc     case ARM::STC2L_PRE:
1399f4a2713aSLionel Sambuc     case ARM::t2LDC_OFFSET:
1400f4a2713aSLionel Sambuc     case ARM::t2LDCL_OFFSET:
1401f4a2713aSLionel Sambuc     case ARM::t2LDC_PRE:
1402f4a2713aSLionel Sambuc     case ARM::t2LDCL_PRE:
1403f4a2713aSLionel Sambuc     case ARM::t2STC_OFFSET:
1404f4a2713aSLionel Sambuc     case ARM::t2STCL_OFFSET:
1405f4a2713aSLionel Sambuc     case ARM::t2STC_PRE:
1406f4a2713aSLionel Sambuc     case ARM::t2STCL_PRE:
1407f4a2713aSLionel Sambuc     case ARM::LDC_OFFSET:
1408f4a2713aSLionel Sambuc     case ARM::LDCL_OFFSET:
1409f4a2713aSLionel Sambuc     case ARM::LDC_PRE:
1410f4a2713aSLionel Sambuc     case ARM::LDCL_PRE:
1411f4a2713aSLionel Sambuc     case ARM::STC_OFFSET:
1412f4a2713aSLionel Sambuc     case ARM::STCL_OFFSET:
1413f4a2713aSLionel Sambuc     case ARM::STC_PRE:
1414f4a2713aSLionel Sambuc     case ARM::STCL_PRE:
1415f4a2713aSLionel Sambuc       imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
1416f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateImm(imm));
1417f4a2713aSLionel Sambuc       break;
1418f4a2713aSLionel Sambuc     case ARM::t2LDC2_POST:
1419f4a2713aSLionel Sambuc     case ARM::t2LDC2L_POST:
1420f4a2713aSLionel Sambuc     case ARM::t2STC2_POST:
1421f4a2713aSLionel Sambuc     case ARM::t2STC2L_POST:
1422f4a2713aSLionel Sambuc     case ARM::LDC2_POST:
1423f4a2713aSLionel Sambuc     case ARM::LDC2L_POST:
1424f4a2713aSLionel Sambuc     case ARM::STC2_POST:
1425f4a2713aSLionel Sambuc     case ARM::STC2L_POST:
1426f4a2713aSLionel Sambuc     case ARM::t2LDC_POST:
1427f4a2713aSLionel Sambuc     case ARM::t2LDCL_POST:
1428f4a2713aSLionel Sambuc     case ARM::t2STC_POST:
1429f4a2713aSLionel Sambuc     case ARM::t2STCL_POST:
1430f4a2713aSLionel Sambuc     case ARM::LDC_POST:
1431f4a2713aSLionel Sambuc     case ARM::LDCL_POST:
1432f4a2713aSLionel Sambuc     case ARM::STC_POST:
1433f4a2713aSLionel Sambuc     case ARM::STCL_POST:
1434f4a2713aSLionel Sambuc       imm |= U << 8;
1435f4a2713aSLionel Sambuc       // fall through.
1436f4a2713aSLionel Sambuc     default:
1437f4a2713aSLionel Sambuc       // The 'option' variant doesn't encode 'U' in the immediate since
1438f4a2713aSLionel Sambuc       // the immediate is unsigned [0,255].
1439f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateImm(imm));
1440f4a2713aSLionel Sambuc       break;
1441f4a2713aSLionel Sambuc   }
1442f4a2713aSLionel Sambuc 
1443f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
1444f4a2713aSLionel Sambuc     case ARM::LDC_OFFSET:
1445f4a2713aSLionel Sambuc     case ARM::LDC_PRE:
1446f4a2713aSLionel Sambuc     case ARM::LDC_POST:
1447f4a2713aSLionel Sambuc     case ARM::LDC_OPTION:
1448f4a2713aSLionel Sambuc     case ARM::LDCL_OFFSET:
1449f4a2713aSLionel Sambuc     case ARM::LDCL_PRE:
1450f4a2713aSLionel Sambuc     case ARM::LDCL_POST:
1451f4a2713aSLionel Sambuc     case ARM::LDCL_OPTION:
1452f4a2713aSLionel Sambuc     case ARM::STC_OFFSET:
1453f4a2713aSLionel Sambuc     case ARM::STC_PRE:
1454f4a2713aSLionel Sambuc     case ARM::STC_POST:
1455f4a2713aSLionel Sambuc     case ARM::STC_OPTION:
1456f4a2713aSLionel Sambuc     case ARM::STCL_OFFSET:
1457f4a2713aSLionel Sambuc     case ARM::STCL_PRE:
1458f4a2713aSLionel Sambuc     case ARM::STCL_POST:
1459f4a2713aSLionel Sambuc     case ARM::STCL_OPTION:
1460f4a2713aSLionel Sambuc       if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1461f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1462f4a2713aSLionel Sambuc       break;
1463f4a2713aSLionel Sambuc     default:
1464f4a2713aSLionel Sambuc       break;
1465f4a2713aSLionel Sambuc   }
1466f4a2713aSLionel Sambuc 
1467f4a2713aSLionel Sambuc   return S;
1468f4a2713aSLionel Sambuc }
1469f4a2713aSLionel Sambuc 
1470f4a2713aSLionel Sambuc static DecodeStatus
DecodeAddrMode2IdxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1471f4a2713aSLionel Sambuc DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn,
1472f4a2713aSLionel Sambuc                               uint64_t Address, const void *Decoder) {
1473f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1474f4a2713aSLionel Sambuc 
1475f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1476f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1477f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1478f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 12);
1479f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
1480f4a2713aSLionel Sambuc   unsigned reg = fieldFromInstruction(Insn, 25, 1);
1481f4a2713aSLionel Sambuc   unsigned P = fieldFromInstruction(Insn, 24, 1);
1482f4a2713aSLionel Sambuc   unsigned W = fieldFromInstruction(Insn, 21, 1);
1483f4a2713aSLionel Sambuc 
1484f4a2713aSLionel Sambuc   // On stores, the writeback operand precedes Rt.
1485f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
1486f4a2713aSLionel Sambuc     case ARM::STR_POST_IMM:
1487f4a2713aSLionel Sambuc     case ARM::STR_POST_REG:
1488f4a2713aSLionel Sambuc     case ARM::STRB_POST_IMM:
1489f4a2713aSLionel Sambuc     case ARM::STRB_POST_REG:
1490f4a2713aSLionel Sambuc     case ARM::STRT_POST_REG:
1491f4a2713aSLionel Sambuc     case ARM::STRT_POST_IMM:
1492f4a2713aSLionel Sambuc     case ARM::STRBT_POST_REG:
1493f4a2713aSLionel Sambuc     case ARM::STRBT_POST_IMM:
1494f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1495f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1496f4a2713aSLionel Sambuc       break;
1497f4a2713aSLionel Sambuc     default:
1498f4a2713aSLionel Sambuc       break;
1499f4a2713aSLionel Sambuc   }
1500f4a2713aSLionel Sambuc 
1501f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1502f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1503f4a2713aSLionel Sambuc 
1504f4a2713aSLionel Sambuc   // On loads, the writeback operand comes after Rt.
1505f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
1506f4a2713aSLionel Sambuc     case ARM::LDR_POST_IMM:
1507f4a2713aSLionel Sambuc     case ARM::LDR_POST_REG:
1508f4a2713aSLionel Sambuc     case ARM::LDRB_POST_IMM:
1509f4a2713aSLionel Sambuc     case ARM::LDRB_POST_REG:
1510f4a2713aSLionel Sambuc     case ARM::LDRBT_POST_REG:
1511f4a2713aSLionel Sambuc     case ARM::LDRBT_POST_IMM:
1512f4a2713aSLionel Sambuc     case ARM::LDRT_POST_REG:
1513f4a2713aSLionel Sambuc     case ARM::LDRT_POST_IMM:
1514f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1515f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1516f4a2713aSLionel Sambuc       break;
1517f4a2713aSLionel Sambuc     default:
1518f4a2713aSLionel Sambuc       break;
1519f4a2713aSLionel Sambuc   }
1520f4a2713aSLionel Sambuc 
1521f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1522f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1523f4a2713aSLionel Sambuc 
1524f4a2713aSLionel Sambuc   ARM_AM::AddrOpc Op = ARM_AM::add;
1525f4a2713aSLionel Sambuc   if (!fieldFromInstruction(Insn, 23, 1))
1526f4a2713aSLionel Sambuc     Op = ARM_AM::sub;
1527f4a2713aSLionel Sambuc 
1528f4a2713aSLionel Sambuc   bool writeback = (P == 0) || (W == 1);
1529f4a2713aSLionel Sambuc   unsigned idx_mode = 0;
1530f4a2713aSLionel Sambuc   if (P && writeback)
1531f4a2713aSLionel Sambuc     idx_mode = ARMII::IndexModePre;
1532f4a2713aSLionel Sambuc   else if (!P && writeback)
1533f4a2713aSLionel Sambuc     idx_mode = ARMII::IndexModePost;
1534f4a2713aSLionel Sambuc 
1535f4a2713aSLionel Sambuc   if (writeback && (Rn == 15 || Rn == Rt))
1536f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail; // UNPREDICTABLE
1537f4a2713aSLionel Sambuc 
1538f4a2713aSLionel Sambuc   if (reg) {
1539f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1540f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
1541f4a2713aSLionel Sambuc     ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
1542f4a2713aSLionel Sambuc     switch( fieldFromInstruction(Insn, 5, 2)) {
1543f4a2713aSLionel Sambuc       case 0:
1544f4a2713aSLionel Sambuc         Opc = ARM_AM::lsl;
1545f4a2713aSLionel Sambuc         break;
1546f4a2713aSLionel Sambuc       case 1:
1547f4a2713aSLionel Sambuc         Opc = ARM_AM::lsr;
1548f4a2713aSLionel Sambuc         break;
1549f4a2713aSLionel Sambuc       case 2:
1550f4a2713aSLionel Sambuc         Opc = ARM_AM::asr;
1551f4a2713aSLionel Sambuc         break;
1552f4a2713aSLionel Sambuc       case 3:
1553f4a2713aSLionel Sambuc         Opc = ARM_AM::ror;
1554f4a2713aSLionel Sambuc         break;
1555f4a2713aSLionel Sambuc       default:
1556f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1557f4a2713aSLionel Sambuc     }
1558f4a2713aSLionel Sambuc     unsigned amt = fieldFromInstruction(Insn, 7, 5);
1559f4a2713aSLionel Sambuc     if (Opc == ARM_AM::ror && amt == 0)
1560f4a2713aSLionel Sambuc       Opc = ARM_AM::rrx;
1561f4a2713aSLionel Sambuc     unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
1562f4a2713aSLionel Sambuc 
1563f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imm));
1564f4a2713aSLionel Sambuc   } else {
1565f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(0));
1566f4a2713aSLionel Sambuc     unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
1567f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(tmp));
1568f4a2713aSLionel Sambuc   }
1569f4a2713aSLionel Sambuc 
1570f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1571f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1572f4a2713aSLionel Sambuc 
1573f4a2713aSLionel Sambuc   return S;
1574f4a2713aSLionel Sambuc }
1575f4a2713aSLionel Sambuc 
DecodeSORegMemOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)1576f4a2713aSLionel Sambuc static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
1577f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
1578f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1579f4a2713aSLionel Sambuc 
1580f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 13, 4);
1581f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Val,  0, 4);
1582f4a2713aSLionel Sambuc   unsigned type = fieldFromInstruction(Val, 5, 2);
1583f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 7, 5);
1584f4a2713aSLionel Sambuc   unsigned U = fieldFromInstruction(Val, 12, 1);
1585f4a2713aSLionel Sambuc 
1586f4a2713aSLionel Sambuc   ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
1587f4a2713aSLionel Sambuc   switch (type) {
1588f4a2713aSLionel Sambuc     case 0:
1589f4a2713aSLionel Sambuc       ShOp = ARM_AM::lsl;
1590f4a2713aSLionel Sambuc       break;
1591f4a2713aSLionel Sambuc     case 1:
1592f4a2713aSLionel Sambuc       ShOp = ARM_AM::lsr;
1593f4a2713aSLionel Sambuc       break;
1594f4a2713aSLionel Sambuc     case 2:
1595f4a2713aSLionel Sambuc       ShOp = ARM_AM::asr;
1596f4a2713aSLionel Sambuc       break;
1597f4a2713aSLionel Sambuc     case 3:
1598f4a2713aSLionel Sambuc       ShOp = ARM_AM::ror;
1599f4a2713aSLionel Sambuc       break;
1600f4a2713aSLionel Sambuc   }
1601f4a2713aSLionel Sambuc 
1602f4a2713aSLionel Sambuc   if (ShOp == ARM_AM::ror && imm == 0)
1603f4a2713aSLionel Sambuc     ShOp = ARM_AM::rrx;
1604f4a2713aSLionel Sambuc 
1605f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1606f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1607f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1608f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1609f4a2713aSLionel Sambuc   unsigned shift;
1610f4a2713aSLionel Sambuc   if (U)
1611f4a2713aSLionel Sambuc     shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
1612f4a2713aSLionel Sambuc   else
1613f4a2713aSLionel Sambuc     shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
1614f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(shift));
1615f4a2713aSLionel Sambuc 
1616f4a2713aSLionel Sambuc   return S;
1617f4a2713aSLionel Sambuc }
1618f4a2713aSLionel Sambuc 
1619f4a2713aSLionel Sambuc static DecodeStatus
DecodeAddrMode3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1620f4a2713aSLionel Sambuc DecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
1621f4a2713aSLionel Sambuc                            uint64_t Address, const void *Decoder) {
1622f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1623f4a2713aSLionel Sambuc 
1624f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1625f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1626f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1627f4a2713aSLionel Sambuc   unsigned type = fieldFromInstruction(Insn, 22, 1);
1628f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 8, 4);
1629f4a2713aSLionel Sambuc   unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
1630f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
1631f4a2713aSLionel Sambuc   unsigned W = fieldFromInstruction(Insn, 21, 1);
1632f4a2713aSLionel Sambuc   unsigned P = fieldFromInstruction(Insn, 24, 1);
1633f4a2713aSLionel Sambuc   unsigned Rt2 = Rt + 1;
1634f4a2713aSLionel Sambuc 
1635f4a2713aSLionel Sambuc   bool writeback = (W == 1) | (P == 0);
1636f4a2713aSLionel Sambuc 
1637f4a2713aSLionel Sambuc   // For {LD,ST}RD, Rt must be even, else undefined.
1638f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
1639f4a2713aSLionel Sambuc     case ARM::STRD:
1640f4a2713aSLionel Sambuc     case ARM::STRD_PRE:
1641f4a2713aSLionel Sambuc     case ARM::STRD_POST:
1642f4a2713aSLionel Sambuc     case ARM::LDRD:
1643f4a2713aSLionel Sambuc     case ARM::LDRD_PRE:
1644f4a2713aSLionel Sambuc     case ARM::LDRD_POST:
1645f4a2713aSLionel Sambuc       if (Rt & 0x1) S = MCDisassembler::SoftFail;
1646f4a2713aSLionel Sambuc       break;
1647f4a2713aSLionel Sambuc     default:
1648f4a2713aSLionel Sambuc       break;
1649f4a2713aSLionel Sambuc   }
1650f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
1651f4a2713aSLionel Sambuc     case ARM::STRD:
1652f4a2713aSLionel Sambuc     case ARM::STRD_PRE:
1653f4a2713aSLionel Sambuc     case ARM::STRD_POST:
1654f4a2713aSLionel Sambuc       if (P == 0 && W == 1)
1655f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1656f4a2713aSLionel Sambuc 
1657f4a2713aSLionel Sambuc       if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
1658f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1659f4a2713aSLionel Sambuc       if (type && Rm == 15)
1660f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1661f4a2713aSLionel Sambuc       if (Rt2 == 15)
1662f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1663f4a2713aSLionel Sambuc       if (!type && fieldFromInstruction(Insn, 8, 4))
1664f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1665f4a2713aSLionel Sambuc       break;
1666f4a2713aSLionel Sambuc     case ARM::STRH:
1667f4a2713aSLionel Sambuc     case ARM::STRH_PRE:
1668f4a2713aSLionel Sambuc     case ARM::STRH_POST:
1669f4a2713aSLionel Sambuc       if (Rt == 15)
1670f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1671f4a2713aSLionel Sambuc       if (writeback && (Rn == 15 || Rn == Rt))
1672f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1673f4a2713aSLionel Sambuc       if (!type && Rm == 15)
1674f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1675f4a2713aSLionel Sambuc       break;
1676f4a2713aSLionel Sambuc     case ARM::LDRD:
1677f4a2713aSLionel Sambuc     case ARM::LDRD_PRE:
1678f4a2713aSLionel Sambuc     case ARM::LDRD_POST:
1679f4a2713aSLionel Sambuc       if (type && Rn == 15){
1680f4a2713aSLionel Sambuc         if (Rt2 == 15)
1681f4a2713aSLionel Sambuc           S = MCDisassembler::SoftFail;
1682f4a2713aSLionel Sambuc         break;
1683f4a2713aSLionel Sambuc       }
1684f4a2713aSLionel Sambuc       if (P == 0 && W == 1)
1685f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1686f4a2713aSLionel Sambuc       if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
1687f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1688f4a2713aSLionel Sambuc       if (!type && writeback && Rn == 15)
1689f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1690f4a2713aSLionel Sambuc       if (writeback && (Rn == Rt || Rn == Rt2))
1691f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1692f4a2713aSLionel Sambuc       break;
1693f4a2713aSLionel Sambuc     case ARM::LDRH:
1694f4a2713aSLionel Sambuc     case ARM::LDRH_PRE:
1695f4a2713aSLionel Sambuc     case ARM::LDRH_POST:
1696f4a2713aSLionel Sambuc       if (type && Rn == 15){
1697f4a2713aSLionel Sambuc         if (Rt == 15)
1698f4a2713aSLionel Sambuc           S = MCDisassembler::SoftFail;
1699f4a2713aSLionel Sambuc         break;
1700f4a2713aSLionel Sambuc       }
1701f4a2713aSLionel Sambuc       if (Rt == 15)
1702f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1703f4a2713aSLionel Sambuc       if (!type && Rm == 15)
1704f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1705f4a2713aSLionel Sambuc       if (!type && writeback && (Rn == 15 || Rn == Rt))
1706f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1707f4a2713aSLionel Sambuc       break;
1708f4a2713aSLionel Sambuc     case ARM::LDRSH:
1709f4a2713aSLionel Sambuc     case ARM::LDRSH_PRE:
1710f4a2713aSLionel Sambuc     case ARM::LDRSH_POST:
1711f4a2713aSLionel Sambuc     case ARM::LDRSB:
1712f4a2713aSLionel Sambuc     case ARM::LDRSB_PRE:
1713f4a2713aSLionel Sambuc     case ARM::LDRSB_POST:
1714f4a2713aSLionel Sambuc       if (type && Rn == 15){
1715f4a2713aSLionel Sambuc         if (Rt == 15)
1716f4a2713aSLionel Sambuc           S = MCDisassembler::SoftFail;
1717f4a2713aSLionel Sambuc         break;
1718f4a2713aSLionel Sambuc       }
1719f4a2713aSLionel Sambuc       if (type && (Rt == 15 || (writeback && Rn == Rt)))
1720f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1721f4a2713aSLionel Sambuc       if (!type && (Rt == 15 || Rm == 15))
1722f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1723f4a2713aSLionel Sambuc       if (!type && writeback && (Rn == 15 || Rn == Rt))
1724f4a2713aSLionel Sambuc         S = MCDisassembler::SoftFail;
1725f4a2713aSLionel Sambuc       break;
1726f4a2713aSLionel Sambuc     default:
1727f4a2713aSLionel Sambuc       break;
1728f4a2713aSLionel Sambuc   }
1729f4a2713aSLionel Sambuc 
1730f4a2713aSLionel Sambuc   if (writeback) { // Writeback
1731f4a2713aSLionel Sambuc     if (P)
1732f4a2713aSLionel Sambuc       U |= ARMII::IndexModePre << 9;
1733f4a2713aSLionel Sambuc     else
1734f4a2713aSLionel Sambuc       U |= ARMII::IndexModePost << 9;
1735f4a2713aSLionel Sambuc 
1736f4a2713aSLionel Sambuc     // On stores, the writeback operand precedes Rt.
1737f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
1738f4a2713aSLionel Sambuc     case ARM::STRD:
1739f4a2713aSLionel Sambuc     case ARM::STRD_PRE:
1740f4a2713aSLionel Sambuc     case ARM::STRD_POST:
1741f4a2713aSLionel Sambuc     case ARM::STRH:
1742f4a2713aSLionel Sambuc     case ARM::STRH_PRE:
1743f4a2713aSLionel Sambuc     case ARM::STRH_POST:
1744f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1745f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1746f4a2713aSLionel Sambuc       break;
1747f4a2713aSLionel Sambuc     default:
1748f4a2713aSLionel Sambuc       break;
1749f4a2713aSLionel Sambuc     }
1750f4a2713aSLionel Sambuc   }
1751f4a2713aSLionel Sambuc 
1752f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1753f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1754f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
1755f4a2713aSLionel Sambuc     case ARM::STRD:
1756f4a2713aSLionel Sambuc     case ARM::STRD_PRE:
1757f4a2713aSLionel Sambuc     case ARM::STRD_POST:
1758f4a2713aSLionel Sambuc     case ARM::LDRD:
1759f4a2713aSLionel Sambuc     case ARM::LDRD_PRE:
1760f4a2713aSLionel Sambuc     case ARM::LDRD_POST:
1761f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
1762f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1763f4a2713aSLionel Sambuc       break;
1764f4a2713aSLionel Sambuc     default:
1765f4a2713aSLionel Sambuc       break;
1766f4a2713aSLionel Sambuc   }
1767f4a2713aSLionel Sambuc 
1768f4a2713aSLionel Sambuc   if (writeback) {
1769f4a2713aSLionel Sambuc     // On loads, the writeback operand comes after Rt.
1770f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
1771f4a2713aSLionel Sambuc     case ARM::LDRD:
1772f4a2713aSLionel Sambuc     case ARM::LDRD_PRE:
1773f4a2713aSLionel Sambuc     case ARM::LDRD_POST:
1774f4a2713aSLionel Sambuc     case ARM::LDRH:
1775f4a2713aSLionel Sambuc     case ARM::LDRH_PRE:
1776f4a2713aSLionel Sambuc     case ARM::LDRH_POST:
1777f4a2713aSLionel Sambuc     case ARM::LDRSH:
1778f4a2713aSLionel Sambuc     case ARM::LDRSH_PRE:
1779f4a2713aSLionel Sambuc     case ARM::LDRSH_POST:
1780f4a2713aSLionel Sambuc     case ARM::LDRSB:
1781f4a2713aSLionel Sambuc     case ARM::LDRSB_PRE:
1782f4a2713aSLionel Sambuc     case ARM::LDRSB_POST:
1783f4a2713aSLionel Sambuc     case ARM::LDRHTr:
1784f4a2713aSLionel Sambuc     case ARM::LDRSBTr:
1785f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1786f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1787f4a2713aSLionel Sambuc       break;
1788f4a2713aSLionel Sambuc     default:
1789f4a2713aSLionel Sambuc       break;
1790f4a2713aSLionel Sambuc     }
1791f4a2713aSLionel Sambuc   }
1792f4a2713aSLionel Sambuc 
1793f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1794f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1795f4a2713aSLionel Sambuc 
1796f4a2713aSLionel Sambuc   if (type) {
1797f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(0));
1798f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm));
1799f4a2713aSLionel Sambuc   } else {
1800f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1801f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1802f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(U));
1803f4a2713aSLionel Sambuc   }
1804f4a2713aSLionel Sambuc 
1805f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1806f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1807f4a2713aSLionel Sambuc 
1808f4a2713aSLionel Sambuc   return S;
1809f4a2713aSLionel Sambuc }
1810f4a2713aSLionel Sambuc 
DecodeRFEInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1811f4a2713aSLionel Sambuc static DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
1812f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
1813f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1814f4a2713aSLionel Sambuc 
1815f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1816f4a2713aSLionel Sambuc   unsigned mode = fieldFromInstruction(Insn, 23, 2);
1817f4a2713aSLionel Sambuc 
1818f4a2713aSLionel Sambuc   switch (mode) {
1819f4a2713aSLionel Sambuc     case 0:
1820f4a2713aSLionel Sambuc       mode = ARM_AM::da;
1821f4a2713aSLionel Sambuc       break;
1822f4a2713aSLionel Sambuc     case 1:
1823f4a2713aSLionel Sambuc       mode = ARM_AM::ia;
1824f4a2713aSLionel Sambuc       break;
1825f4a2713aSLionel Sambuc     case 2:
1826f4a2713aSLionel Sambuc       mode = ARM_AM::db;
1827f4a2713aSLionel Sambuc       break;
1828f4a2713aSLionel Sambuc     case 3:
1829f4a2713aSLionel Sambuc       mode = ARM_AM::ib;
1830f4a2713aSLionel Sambuc       break;
1831f4a2713aSLionel Sambuc   }
1832f4a2713aSLionel Sambuc 
1833f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(mode));
1834f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1835f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1836f4a2713aSLionel Sambuc 
1837f4a2713aSLionel Sambuc   return S;
1838f4a2713aSLionel Sambuc }
1839f4a2713aSLionel Sambuc 
DecodeQADDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1840f4a2713aSLionel Sambuc static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
1841f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
1842f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1843f4a2713aSLionel Sambuc 
1844f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
1845f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1846f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1847f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
1848f4a2713aSLionel Sambuc 
1849f4a2713aSLionel Sambuc   if (pred == 0xF)
1850f4a2713aSLionel Sambuc     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
1851f4a2713aSLionel Sambuc 
1852f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
1853f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1854f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1855f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1856f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
1857f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1858f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1859f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1860f4a2713aSLionel Sambuc   return S;
1861f4a2713aSLionel Sambuc }
1862f4a2713aSLionel Sambuc 
DecodeMemMultipleWritebackInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1863f4a2713aSLionel Sambuc static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst,
1864f4a2713aSLionel Sambuc                                   unsigned Insn,
1865f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
1866f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1867f4a2713aSLionel Sambuc 
1868f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1869f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
1870f4a2713aSLionel Sambuc   unsigned reglist = fieldFromInstruction(Insn, 0, 16);
1871f4a2713aSLionel Sambuc 
1872f4a2713aSLionel Sambuc   if (pred == 0xF) {
1873f4a2713aSLionel Sambuc     // Ambiguous with RFE and SRS
1874f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
1875f4a2713aSLionel Sambuc       case ARM::LDMDA:
1876f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::RFEDA);
1877f4a2713aSLionel Sambuc         break;
1878f4a2713aSLionel Sambuc       case ARM::LDMDA_UPD:
1879f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::RFEDA_UPD);
1880f4a2713aSLionel Sambuc         break;
1881f4a2713aSLionel Sambuc       case ARM::LDMDB:
1882f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::RFEDB);
1883f4a2713aSLionel Sambuc         break;
1884f4a2713aSLionel Sambuc       case ARM::LDMDB_UPD:
1885f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::RFEDB_UPD);
1886f4a2713aSLionel Sambuc         break;
1887f4a2713aSLionel Sambuc       case ARM::LDMIA:
1888f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::RFEIA);
1889f4a2713aSLionel Sambuc         break;
1890f4a2713aSLionel Sambuc       case ARM::LDMIA_UPD:
1891f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::RFEIA_UPD);
1892f4a2713aSLionel Sambuc         break;
1893f4a2713aSLionel Sambuc       case ARM::LDMIB:
1894f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::RFEIB);
1895f4a2713aSLionel Sambuc         break;
1896f4a2713aSLionel Sambuc       case ARM::LDMIB_UPD:
1897f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::RFEIB_UPD);
1898f4a2713aSLionel Sambuc         break;
1899f4a2713aSLionel Sambuc       case ARM::STMDA:
1900f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::SRSDA);
1901f4a2713aSLionel Sambuc         break;
1902f4a2713aSLionel Sambuc       case ARM::STMDA_UPD:
1903f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::SRSDA_UPD);
1904f4a2713aSLionel Sambuc         break;
1905f4a2713aSLionel Sambuc       case ARM::STMDB:
1906f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::SRSDB);
1907f4a2713aSLionel Sambuc         break;
1908f4a2713aSLionel Sambuc       case ARM::STMDB_UPD:
1909f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::SRSDB_UPD);
1910f4a2713aSLionel Sambuc         break;
1911f4a2713aSLionel Sambuc       case ARM::STMIA:
1912f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::SRSIA);
1913f4a2713aSLionel Sambuc         break;
1914f4a2713aSLionel Sambuc       case ARM::STMIA_UPD:
1915f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::SRSIA_UPD);
1916f4a2713aSLionel Sambuc         break;
1917f4a2713aSLionel Sambuc       case ARM::STMIB:
1918f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::SRSIB);
1919f4a2713aSLionel Sambuc         break;
1920f4a2713aSLionel Sambuc       case ARM::STMIB_UPD:
1921f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::SRSIB_UPD);
1922f4a2713aSLionel Sambuc         break;
1923f4a2713aSLionel Sambuc       default:
1924f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1925f4a2713aSLionel Sambuc     }
1926f4a2713aSLionel Sambuc 
1927f4a2713aSLionel Sambuc     // For stores (which become SRS's, the only operand is the mode.
1928f4a2713aSLionel Sambuc     if (fieldFromInstruction(Insn, 20, 1) == 0) {
1929f4a2713aSLionel Sambuc       // Check SRS encoding constraints
1930f4a2713aSLionel Sambuc       if (!(fieldFromInstruction(Insn, 22, 1) == 1 &&
1931f4a2713aSLionel Sambuc             fieldFromInstruction(Insn, 20, 1) == 0))
1932f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
1933f4a2713aSLionel Sambuc 
1934f4a2713aSLionel Sambuc       Inst.addOperand(
1935f4a2713aSLionel Sambuc           MCOperand::CreateImm(fieldFromInstruction(Insn, 0, 4)));
1936f4a2713aSLionel Sambuc       return S;
1937f4a2713aSLionel Sambuc     }
1938f4a2713aSLionel Sambuc 
1939f4a2713aSLionel Sambuc     return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
1940f4a2713aSLionel Sambuc   }
1941f4a2713aSLionel Sambuc 
1942f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1943f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1944f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1945f4a2713aSLionel Sambuc     return MCDisassembler::Fail; // Tied
1946f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1947f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1948f4a2713aSLionel Sambuc   if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
1949f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1950f4a2713aSLionel Sambuc 
1951f4a2713aSLionel Sambuc   return S;
1952f4a2713aSLionel Sambuc }
1953f4a2713aSLionel Sambuc 
DecodeCPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)1954f4a2713aSLionel Sambuc static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
1955f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
1956f4a2713aSLionel Sambuc   unsigned imod = fieldFromInstruction(Insn, 18, 2);
1957f4a2713aSLionel Sambuc   unsigned M = fieldFromInstruction(Insn, 17, 1);
1958f4a2713aSLionel Sambuc   unsigned iflags = fieldFromInstruction(Insn, 6, 3);
1959f4a2713aSLionel Sambuc   unsigned mode = fieldFromInstruction(Insn, 0, 5);
1960f4a2713aSLionel Sambuc 
1961f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
1962f4a2713aSLionel Sambuc 
1963f4a2713aSLionel Sambuc   // This decoder is called from multiple location that do not check
1964f4a2713aSLionel Sambuc   // the full encoding is valid before they do.
1965f4a2713aSLionel Sambuc   if (fieldFromInstruction(Insn, 5, 1) != 0 ||
1966f4a2713aSLionel Sambuc       fieldFromInstruction(Insn, 16, 1) != 0 ||
1967f4a2713aSLionel Sambuc       fieldFromInstruction(Insn, 20, 8) != 0x10)
1968f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
1969f4a2713aSLionel Sambuc 
1970f4a2713aSLionel Sambuc   // imod == '01' --> UNPREDICTABLE
1971f4a2713aSLionel Sambuc   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
1972f4a2713aSLionel Sambuc   // return failure here.  The '01' imod value is unprintable, so there's
1973f4a2713aSLionel Sambuc   // nothing useful we could do even if we returned UNPREDICTABLE.
1974f4a2713aSLionel Sambuc 
1975f4a2713aSLionel Sambuc   if (imod == 1) return MCDisassembler::Fail;
1976f4a2713aSLionel Sambuc 
1977f4a2713aSLionel Sambuc   if (imod && M) {
1978f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::CPS3p);
1979f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imod));
1980f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(iflags));
1981f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(mode));
1982f4a2713aSLionel Sambuc   } else if (imod && !M) {
1983f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::CPS2p);
1984f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imod));
1985f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(iflags));
1986f4a2713aSLionel Sambuc     if (mode) S = MCDisassembler::SoftFail;
1987f4a2713aSLionel Sambuc   } else if (!imod && M) {
1988f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::CPS1p);
1989f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(mode));
1990f4a2713aSLionel Sambuc     if (iflags) S = MCDisassembler::SoftFail;
1991f4a2713aSLionel Sambuc   } else {
1992f4a2713aSLionel Sambuc     // imod == '00' && M == '0' --> UNPREDICTABLE
1993f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::CPS1p);
1994f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(mode));
1995f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
1996f4a2713aSLionel Sambuc   }
1997f4a2713aSLionel Sambuc 
1998f4a2713aSLionel Sambuc   return S;
1999f4a2713aSLionel Sambuc }
2000f4a2713aSLionel Sambuc 
DecodeT2CPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2001f4a2713aSLionel Sambuc static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
2002f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
2003f4a2713aSLionel Sambuc   unsigned imod = fieldFromInstruction(Insn, 9, 2);
2004f4a2713aSLionel Sambuc   unsigned M = fieldFromInstruction(Insn, 8, 1);
2005f4a2713aSLionel Sambuc   unsigned iflags = fieldFromInstruction(Insn, 5, 3);
2006f4a2713aSLionel Sambuc   unsigned mode = fieldFromInstruction(Insn, 0, 5);
2007f4a2713aSLionel Sambuc 
2008f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2009f4a2713aSLionel Sambuc 
2010f4a2713aSLionel Sambuc   // imod == '01' --> UNPREDICTABLE
2011f4a2713aSLionel Sambuc   // NOTE: Even though this is technically UNPREDICTABLE, we choose to
2012f4a2713aSLionel Sambuc   // return failure here.  The '01' imod value is unprintable, so there's
2013f4a2713aSLionel Sambuc   // nothing useful we could do even if we returned UNPREDICTABLE.
2014f4a2713aSLionel Sambuc 
2015f4a2713aSLionel Sambuc   if (imod == 1) return MCDisassembler::Fail;
2016f4a2713aSLionel Sambuc 
2017f4a2713aSLionel Sambuc   if (imod && M) {
2018f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::t2CPS3p);
2019f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imod));
2020f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(iflags));
2021f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(mode));
2022f4a2713aSLionel Sambuc   } else if (imod && !M) {
2023f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::t2CPS2p);
2024f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imod));
2025f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(iflags));
2026f4a2713aSLionel Sambuc     if (mode) S = MCDisassembler::SoftFail;
2027f4a2713aSLionel Sambuc   } else if (!imod && M) {
2028f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::t2CPS1p);
2029f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(mode));
2030f4a2713aSLionel Sambuc     if (iflags) S = MCDisassembler::SoftFail;
2031f4a2713aSLionel Sambuc   } else {
2032f4a2713aSLionel Sambuc     // imod == '00' && M == '0' --> this is a HINT instruction
2033f4a2713aSLionel Sambuc     int imm = fieldFromInstruction(Insn, 0, 8);
2034f4a2713aSLionel Sambuc     // HINT are defined only for immediate in [0..4]
2035f4a2713aSLionel Sambuc     if(imm > 4) return MCDisassembler::Fail;
2036f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::t2HINT);
2037f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imm));
2038f4a2713aSLionel Sambuc   }
2039f4a2713aSLionel Sambuc 
2040f4a2713aSLionel Sambuc   return S;
2041f4a2713aSLionel Sambuc }
2042f4a2713aSLionel Sambuc 
DecodeT2MOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2043f4a2713aSLionel Sambuc static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
2044f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
2045f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2046f4a2713aSLionel Sambuc 
2047f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 8, 4);
2048f4a2713aSLionel Sambuc   unsigned imm = 0;
2049f4a2713aSLionel Sambuc 
2050f4a2713aSLionel Sambuc   imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
2051f4a2713aSLionel Sambuc   imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
2052f4a2713aSLionel Sambuc   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
2053f4a2713aSLionel Sambuc   imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
2054f4a2713aSLionel Sambuc 
2055f4a2713aSLionel Sambuc   if (Inst.getOpcode() == ARM::t2MOVTi16)
2056f4a2713aSLionel Sambuc     if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
2057f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2058f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
2059f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2060f4a2713aSLionel Sambuc 
2061f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
2062f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imm));
2063f4a2713aSLionel Sambuc 
2064f4a2713aSLionel Sambuc   return S;
2065f4a2713aSLionel Sambuc }
2066f4a2713aSLionel Sambuc 
DecodeArmMOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2067f4a2713aSLionel Sambuc static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
2068f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
2069f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2070f4a2713aSLionel Sambuc 
2071f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2072f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
2073f4a2713aSLionel Sambuc   unsigned imm = 0;
2074f4a2713aSLionel Sambuc 
2075f4a2713aSLionel Sambuc   imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
2076f4a2713aSLionel Sambuc   imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
2077f4a2713aSLionel Sambuc 
2078f4a2713aSLionel Sambuc   if (Inst.getOpcode() == ARM::MOVTi16)
2079f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2080f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2081f4a2713aSLionel Sambuc 
2082f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2083f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2084f4a2713aSLionel Sambuc 
2085f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
2086f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imm));
2087f4a2713aSLionel Sambuc 
2088f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2089f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2090f4a2713aSLionel Sambuc 
2091f4a2713aSLionel Sambuc   return S;
2092f4a2713aSLionel Sambuc }
2093f4a2713aSLionel Sambuc 
DecodeSMLAInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2094f4a2713aSLionel Sambuc static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
2095f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
2096f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2097f4a2713aSLionel Sambuc 
2098f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 16, 4);
2099f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 0, 4);
2100f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 8, 4);
2101f4a2713aSLionel Sambuc   unsigned Ra = fieldFromInstruction(Insn, 12, 4);
2102f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
2103f4a2713aSLionel Sambuc 
2104f4a2713aSLionel Sambuc   if (pred == 0xF)
2105f4a2713aSLionel Sambuc     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
2106f4a2713aSLionel Sambuc 
2107f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2108f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2109f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2110f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2111f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
2112f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2113f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
2114f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2115f4a2713aSLionel Sambuc 
2116f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2117f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2118f4a2713aSLionel Sambuc 
2119f4a2713aSLionel Sambuc   return S;
2120f4a2713aSLionel Sambuc }
2121f4a2713aSLionel Sambuc 
DecodeAddrModeImm12Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)2122f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
2123f4a2713aSLionel Sambuc                            uint64_t Address, const void *Decoder) {
2124f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2125f4a2713aSLionel Sambuc 
2126f4a2713aSLionel Sambuc   unsigned add = fieldFromInstruction(Val, 12, 1);
2127f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 0, 12);
2128f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 13, 4);
2129f4a2713aSLionel Sambuc 
2130f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2131f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2132f4a2713aSLionel Sambuc 
2133f4a2713aSLionel Sambuc   if (!add) imm *= -1;
2134f4a2713aSLionel Sambuc   if (imm == 0 && !add) imm = INT32_MIN;
2135f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
2136f4a2713aSLionel Sambuc   if (Rn == 15)
2137f4a2713aSLionel Sambuc     tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
2138f4a2713aSLionel Sambuc 
2139f4a2713aSLionel Sambuc   return S;
2140f4a2713aSLionel Sambuc }
2141f4a2713aSLionel Sambuc 
DecodeAddrMode5Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)2142f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
2143f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
2144f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2145f4a2713aSLionel Sambuc 
2146f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 9, 4);
2147f4a2713aSLionel Sambuc   unsigned U = fieldFromInstruction(Val, 8, 1);
2148f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 0, 8);
2149f4a2713aSLionel Sambuc 
2150f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2151f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2152f4a2713aSLionel Sambuc 
2153f4a2713aSLionel Sambuc   if (U)
2154f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
2155f4a2713aSLionel Sambuc   else
2156f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
2157f4a2713aSLionel Sambuc 
2158f4a2713aSLionel Sambuc   return S;
2159f4a2713aSLionel Sambuc }
2160f4a2713aSLionel Sambuc 
DecodeAddrMode7Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)2161f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
2162f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
2163f4a2713aSLionel Sambuc   return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
2164f4a2713aSLionel Sambuc }
2165f4a2713aSLionel Sambuc 
2166f4a2713aSLionel Sambuc static DecodeStatus
DecodeT2BInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2167f4a2713aSLionel Sambuc DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2168f4a2713aSLionel Sambuc                      uint64_t Address, const void *Decoder) {
2169f4a2713aSLionel Sambuc   DecodeStatus Status = MCDisassembler::Success;
2170f4a2713aSLionel Sambuc 
2171f4a2713aSLionel Sambuc   // Note the J1 and J2 values are from the encoded instruction.  So here
2172f4a2713aSLionel Sambuc   // change them to I1 and I2 values via as documented:
2173f4a2713aSLionel Sambuc   // I1 = NOT(J1 EOR S);
2174f4a2713aSLionel Sambuc   // I2 = NOT(J2 EOR S);
2175f4a2713aSLionel Sambuc   // and build the imm32 with one trailing zero as documented:
2176f4a2713aSLionel Sambuc   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
2177f4a2713aSLionel Sambuc   unsigned S = fieldFromInstruction(Insn, 26, 1);
2178f4a2713aSLionel Sambuc   unsigned J1 = fieldFromInstruction(Insn, 13, 1);
2179f4a2713aSLionel Sambuc   unsigned J2 = fieldFromInstruction(Insn, 11, 1);
2180f4a2713aSLionel Sambuc   unsigned I1 = !(J1 ^ S);
2181f4a2713aSLionel Sambuc   unsigned I2 = !(J2 ^ S);
2182f4a2713aSLionel Sambuc   unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
2183f4a2713aSLionel Sambuc   unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
2184f4a2713aSLionel Sambuc   unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
2185f4a2713aSLionel Sambuc   int imm32 = SignExtend32<25>(tmp << 1);
2186f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
2187f4a2713aSLionel Sambuc                                 true, 4, Inst, Decoder))
2188f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imm32));
2189f4a2713aSLionel Sambuc 
2190f4a2713aSLionel Sambuc   return Status;
2191f4a2713aSLionel Sambuc }
2192f4a2713aSLionel Sambuc 
2193f4a2713aSLionel Sambuc static DecodeStatus
DecodeBranchImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2194f4a2713aSLionel Sambuc DecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
2195f4a2713aSLionel Sambuc                            uint64_t Address, const void *Decoder) {
2196f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2197f4a2713aSLionel Sambuc 
2198f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
2199f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
2200f4a2713aSLionel Sambuc 
2201f4a2713aSLionel Sambuc   if (pred == 0xF) {
2202f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::BLXi);
2203f4a2713aSLionel Sambuc     imm |= fieldFromInstruction(Insn, 24, 1) << 1;
2204f4a2713aSLionel Sambuc     if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2205f4a2713aSLionel Sambuc                                   true, 4, Inst, Decoder))
2206f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
2207f4a2713aSLionel Sambuc     return S;
2208f4a2713aSLionel Sambuc   }
2209f4a2713aSLionel Sambuc 
2210f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2211f4a2713aSLionel Sambuc                                 true, 4, Inst, Decoder))
2212f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
2213f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2214f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2215f4a2713aSLionel Sambuc 
2216f4a2713aSLionel Sambuc   return S;
2217f4a2713aSLionel Sambuc }
2218f4a2713aSLionel Sambuc 
2219f4a2713aSLionel Sambuc 
DecodeAddrMode6Operand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)2220f4a2713aSLionel Sambuc static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
2221f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
2222f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2223f4a2713aSLionel Sambuc 
2224f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Val, 0, 4);
2225f4a2713aSLionel Sambuc   unsigned align = fieldFromInstruction(Val, 4, 2);
2226f4a2713aSLionel Sambuc 
2227f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2228f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2229f4a2713aSLionel Sambuc   if (!align)
2230f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(0));
2231f4a2713aSLionel Sambuc   else
2232f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(4 << align));
2233f4a2713aSLionel Sambuc 
2234f4a2713aSLionel Sambuc   return S;
2235f4a2713aSLionel Sambuc }
2236f4a2713aSLionel Sambuc 
DecodeVLDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2237f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
2238f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
2239f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2240f4a2713aSLionel Sambuc 
2241f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2242f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2243f4a2713aSLionel Sambuc   unsigned wb = fieldFromInstruction(Insn, 16, 4);
2244f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2245f4a2713aSLionel Sambuc   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2246f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2247f4a2713aSLionel Sambuc 
2248f4a2713aSLionel Sambuc   // First output register
2249f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2250f4a2713aSLionel Sambuc   case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
2251f4a2713aSLionel Sambuc   case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
2252f4a2713aSLionel Sambuc   case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
2253f4a2713aSLionel Sambuc   case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
2254f4a2713aSLionel Sambuc   case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
2255f4a2713aSLionel Sambuc   case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
2256f4a2713aSLionel Sambuc   case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
2257f4a2713aSLionel Sambuc   case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
2258f4a2713aSLionel Sambuc   case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
2259f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2260f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2261f4a2713aSLionel Sambuc     break;
2262f4a2713aSLionel Sambuc   case ARM::VLD2b16:
2263f4a2713aSLionel Sambuc   case ARM::VLD2b32:
2264f4a2713aSLionel Sambuc   case ARM::VLD2b8:
2265f4a2713aSLionel Sambuc   case ARM::VLD2b16wb_fixed:
2266f4a2713aSLionel Sambuc   case ARM::VLD2b16wb_register:
2267f4a2713aSLionel Sambuc   case ARM::VLD2b32wb_fixed:
2268f4a2713aSLionel Sambuc   case ARM::VLD2b32wb_register:
2269f4a2713aSLionel Sambuc   case ARM::VLD2b8wb_fixed:
2270f4a2713aSLionel Sambuc   case ARM::VLD2b8wb_register:
2271f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2272f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2273f4a2713aSLionel Sambuc     break;
2274f4a2713aSLionel Sambuc   default:
2275f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2276f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2277f4a2713aSLionel Sambuc   }
2278f4a2713aSLionel Sambuc 
2279f4a2713aSLionel Sambuc   // Second output register
2280f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2281f4a2713aSLionel Sambuc     case ARM::VLD3d8:
2282f4a2713aSLionel Sambuc     case ARM::VLD3d16:
2283f4a2713aSLionel Sambuc     case ARM::VLD3d32:
2284f4a2713aSLionel Sambuc     case ARM::VLD3d8_UPD:
2285f4a2713aSLionel Sambuc     case ARM::VLD3d16_UPD:
2286f4a2713aSLionel Sambuc     case ARM::VLD3d32_UPD:
2287f4a2713aSLionel Sambuc     case ARM::VLD4d8:
2288f4a2713aSLionel Sambuc     case ARM::VLD4d16:
2289f4a2713aSLionel Sambuc     case ARM::VLD4d32:
2290f4a2713aSLionel Sambuc     case ARM::VLD4d8_UPD:
2291f4a2713aSLionel Sambuc     case ARM::VLD4d16_UPD:
2292f4a2713aSLionel Sambuc     case ARM::VLD4d32_UPD:
2293f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2294f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2295f4a2713aSLionel Sambuc       break;
2296f4a2713aSLionel Sambuc     case ARM::VLD3q8:
2297f4a2713aSLionel Sambuc     case ARM::VLD3q16:
2298f4a2713aSLionel Sambuc     case ARM::VLD3q32:
2299f4a2713aSLionel Sambuc     case ARM::VLD3q8_UPD:
2300f4a2713aSLionel Sambuc     case ARM::VLD3q16_UPD:
2301f4a2713aSLionel Sambuc     case ARM::VLD3q32_UPD:
2302f4a2713aSLionel Sambuc     case ARM::VLD4q8:
2303f4a2713aSLionel Sambuc     case ARM::VLD4q16:
2304f4a2713aSLionel Sambuc     case ARM::VLD4q32:
2305f4a2713aSLionel Sambuc     case ARM::VLD4q8_UPD:
2306f4a2713aSLionel Sambuc     case ARM::VLD4q16_UPD:
2307f4a2713aSLionel Sambuc     case ARM::VLD4q32_UPD:
2308f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2309f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2310f4a2713aSLionel Sambuc     default:
2311f4a2713aSLionel Sambuc       break;
2312f4a2713aSLionel Sambuc   }
2313f4a2713aSLionel Sambuc 
2314f4a2713aSLionel Sambuc   // Third output register
2315f4a2713aSLionel Sambuc   switch(Inst.getOpcode()) {
2316f4a2713aSLionel Sambuc     case ARM::VLD3d8:
2317f4a2713aSLionel Sambuc     case ARM::VLD3d16:
2318f4a2713aSLionel Sambuc     case ARM::VLD3d32:
2319f4a2713aSLionel Sambuc     case ARM::VLD3d8_UPD:
2320f4a2713aSLionel Sambuc     case ARM::VLD3d16_UPD:
2321f4a2713aSLionel Sambuc     case ARM::VLD3d32_UPD:
2322f4a2713aSLionel Sambuc     case ARM::VLD4d8:
2323f4a2713aSLionel Sambuc     case ARM::VLD4d16:
2324f4a2713aSLionel Sambuc     case ARM::VLD4d32:
2325f4a2713aSLionel Sambuc     case ARM::VLD4d8_UPD:
2326f4a2713aSLionel Sambuc     case ARM::VLD4d16_UPD:
2327f4a2713aSLionel Sambuc     case ARM::VLD4d32_UPD:
2328f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2329f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2330f4a2713aSLionel Sambuc       break;
2331f4a2713aSLionel Sambuc     case ARM::VLD3q8:
2332f4a2713aSLionel Sambuc     case ARM::VLD3q16:
2333f4a2713aSLionel Sambuc     case ARM::VLD3q32:
2334f4a2713aSLionel Sambuc     case ARM::VLD3q8_UPD:
2335f4a2713aSLionel Sambuc     case ARM::VLD3q16_UPD:
2336f4a2713aSLionel Sambuc     case ARM::VLD3q32_UPD:
2337f4a2713aSLionel Sambuc     case ARM::VLD4q8:
2338f4a2713aSLionel Sambuc     case ARM::VLD4q16:
2339f4a2713aSLionel Sambuc     case ARM::VLD4q32:
2340f4a2713aSLionel Sambuc     case ARM::VLD4q8_UPD:
2341f4a2713aSLionel Sambuc     case ARM::VLD4q16_UPD:
2342f4a2713aSLionel Sambuc     case ARM::VLD4q32_UPD:
2343f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2344f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2345f4a2713aSLionel Sambuc       break;
2346f4a2713aSLionel Sambuc     default:
2347f4a2713aSLionel Sambuc       break;
2348f4a2713aSLionel Sambuc   }
2349f4a2713aSLionel Sambuc 
2350f4a2713aSLionel Sambuc   // Fourth output register
2351f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2352f4a2713aSLionel Sambuc     case ARM::VLD4d8:
2353f4a2713aSLionel Sambuc     case ARM::VLD4d16:
2354f4a2713aSLionel Sambuc     case ARM::VLD4d32:
2355f4a2713aSLionel Sambuc     case ARM::VLD4d8_UPD:
2356f4a2713aSLionel Sambuc     case ARM::VLD4d16_UPD:
2357f4a2713aSLionel Sambuc     case ARM::VLD4d32_UPD:
2358f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2359f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2360f4a2713aSLionel Sambuc       break;
2361f4a2713aSLionel Sambuc     case ARM::VLD4q8:
2362f4a2713aSLionel Sambuc     case ARM::VLD4q16:
2363f4a2713aSLionel Sambuc     case ARM::VLD4q32:
2364f4a2713aSLionel Sambuc     case ARM::VLD4q8_UPD:
2365f4a2713aSLionel Sambuc     case ARM::VLD4q16_UPD:
2366f4a2713aSLionel Sambuc     case ARM::VLD4q32_UPD:
2367f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2368f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2369f4a2713aSLionel Sambuc       break;
2370f4a2713aSLionel Sambuc     default:
2371f4a2713aSLionel Sambuc       break;
2372f4a2713aSLionel Sambuc   }
2373f4a2713aSLionel Sambuc 
2374f4a2713aSLionel Sambuc   // Writeback operand
2375f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2376f4a2713aSLionel Sambuc     case ARM::VLD1d8wb_fixed:
2377f4a2713aSLionel Sambuc     case ARM::VLD1d16wb_fixed:
2378f4a2713aSLionel Sambuc     case ARM::VLD1d32wb_fixed:
2379f4a2713aSLionel Sambuc     case ARM::VLD1d64wb_fixed:
2380f4a2713aSLionel Sambuc     case ARM::VLD1d8wb_register:
2381f4a2713aSLionel Sambuc     case ARM::VLD1d16wb_register:
2382f4a2713aSLionel Sambuc     case ARM::VLD1d32wb_register:
2383f4a2713aSLionel Sambuc     case ARM::VLD1d64wb_register:
2384f4a2713aSLionel Sambuc     case ARM::VLD1q8wb_fixed:
2385f4a2713aSLionel Sambuc     case ARM::VLD1q16wb_fixed:
2386f4a2713aSLionel Sambuc     case ARM::VLD1q32wb_fixed:
2387f4a2713aSLionel Sambuc     case ARM::VLD1q64wb_fixed:
2388f4a2713aSLionel Sambuc     case ARM::VLD1q8wb_register:
2389f4a2713aSLionel Sambuc     case ARM::VLD1q16wb_register:
2390f4a2713aSLionel Sambuc     case ARM::VLD1q32wb_register:
2391f4a2713aSLionel Sambuc     case ARM::VLD1q64wb_register:
2392f4a2713aSLionel Sambuc     case ARM::VLD1d8Twb_fixed:
2393f4a2713aSLionel Sambuc     case ARM::VLD1d8Twb_register:
2394f4a2713aSLionel Sambuc     case ARM::VLD1d16Twb_fixed:
2395f4a2713aSLionel Sambuc     case ARM::VLD1d16Twb_register:
2396f4a2713aSLionel Sambuc     case ARM::VLD1d32Twb_fixed:
2397f4a2713aSLionel Sambuc     case ARM::VLD1d32Twb_register:
2398f4a2713aSLionel Sambuc     case ARM::VLD1d64Twb_fixed:
2399f4a2713aSLionel Sambuc     case ARM::VLD1d64Twb_register:
2400f4a2713aSLionel Sambuc     case ARM::VLD1d8Qwb_fixed:
2401f4a2713aSLionel Sambuc     case ARM::VLD1d8Qwb_register:
2402f4a2713aSLionel Sambuc     case ARM::VLD1d16Qwb_fixed:
2403f4a2713aSLionel Sambuc     case ARM::VLD1d16Qwb_register:
2404f4a2713aSLionel Sambuc     case ARM::VLD1d32Qwb_fixed:
2405f4a2713aSLionel Sambuc     case ARM::VLD1d32Qwb_register:
2406f4a2713aSLionel Sambuc     case ARM::VLD1d64Qwb_fixed:
2407f4a2713aSLionel Sambuc     case ARM::VLD1d64Qwb_register:
2408f4a2713aSLionel Sambuc     case ARM::VLD2d8wb_fixed:
2409f4a2713aSLionel Sambuc     case ARM::VLD2d16wb_fixed:
2410f4a2713aSLionel Sambuc     case ARM::VLD2d32wb_fixed:
2411f4a2713aSLionel Sambuc     case ARM::VLD2q8wb_fixed:
2412f4a2713aSLionel Sambuc     case ARM::VLD2q16wb_fixed:
2413f4a2713aSLionel Sambuc     case ARM::VLD2q32wb_fixed:
2414f4a2713aSLionel Sambuc     case ARM::VLD2d8wb_register:
2415f4a2713aSLionel Sambuc     case ARM::VLD2d16wb_register:
2416f4a2713aSLionel Sambuc     case ARM::VLD2d32wb_register:
2417f4a2713aSLionel Sambuc     case ARM::VLD2q8wb_register:
2418f4a2713aSLionel Sambuc     case ARM::VLD2q16wb_register:
2419f4a2713aSLionel Sambuc     case ARM::VLD2q32wb_register:
2420f4a2713aSLionel Sambuc     case ARM::VLD2b8wb_fixed:
2421f4a2713aSLionel Sambuc     case ARM::VLD2b16wb_fixed:
2422f4a2713aSLionel Sambuc     case ARM::VLD2b32wb_fixed:
2423f4a2713aSLionel Sambuc     case ARM::VLD2b8wb_register:
2424f4a2713aSLionel Sambuc     case ARM::VLD2b16wb_register:
2425f4a2713aSLionel Sambuc     case ARM::VLD2b32wb_register:
2426f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateImm(0));
2427f4a2713aSLionel Sambuc       break;
2428f4a2713aSLionel Sambuc     case ARM::VLD3d8_UPD:
2429f4a2713aSLionel Sambuc     case ARM::VLD3d16_UPD:
2430f4a2713aSLionel Sambuc     case ARM::VLD3d32_UPD:
2431f4a2713aSLionel Sambuc     case ARM::VLD3q8_UPD:
2432f4a2713aSLionel Sambuc     case ARM::VLD3q16_UPD:
2433f4a2713aSLionel Sambuc     case ARM::VLD3q32_UPD:
2434f4a2713aSLionel Sambuc     case ARM::VLD4d8_UPD:
2435f4a2713aSLionel Sambuc     case ARM::VLD4d16_UPD:
2436f4a2713aSLionel Sambuc     case ARM::VLD4d32_UPD:
2437f4a2713aSLionel Sambuc     case ARM::VLD4q8_UPD:
2438f4a2713aSLionel Sambuc     case ARM::VLD4q16_UPD:
2439f4a2713aSLionel Sambuc     case ARM::VLD4q32_UPD:
2440f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2441f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2442f4a2713aSLionel Sambuc       break;
2443f4a2713aSLionel Sambuc     default:
2444f4a2713aSLionel Sambuc       break;
2445f4a2713aSLionel Sambuc   }
2446f4a2713aSLionel Sambuc 
2447f4a2713aSLionel Sambuc   // AddrMode6 Base (register+alignment)
2448f4a2713aSLionel Sambuc   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2449f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2450f4a2713aSLionel Sambuc 
2451f4a2713aSLionel Sambuc   // AddrMode6 Offset (register)
2452f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2453f4a2713aSLionel Sambuc   default:
2454f4a2713aSLionel Sambuc     // The below have been updated to have explicit am6offset split
2455f4a2713aSLionel Sambuc     // between fixed and register offset. For those instructions not
2456f4a2713aSLionel Sambuc     // yet updated, we need to add an additional reg0 operand for the
2457f4a2713aSLionel Sambuc     // fixed variant.
2458f4a2713aSLionel Sambuc     //
2459f4a2713aSLionel Sambuc     // The fixed offset encodes as Rm == 0xd, so we check for that.
2460f4a2713aSLionel Sambuc     if (Rm == 0xd) {
2461f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(0));
2462f4a2713aSLionel Sambuc       break;
2463f4a2713aSLionel Sambuc     }
2464f4a2713aSLionel Sambuc     // Fall through to handle the register offset variant.
2465f4a2713aSLionel Sambuc   case ARM::VLD1d8wb_fixed:
2466f4a2713aSLionel Sambuc   case ARM::VLD1d16wb_fixed:
2467f4a2713aSLionel Sambuc   case ARM::VLD1d32wb_fixed:
2468f4a2713aSLionel Sambuc   case ARM::VLD1d64wb_fixed:
2469f4a2713aSLionel Sambuc   case ARM::VLD1d8Twb_fixed:
2470f4a2713aSLionel Sambuc   case ARM::VLD1d16Twb_fixed:
2471f4a2713aSLionel Sambuc   case ARM::VLD1d32Twb_fixed:
2472f4a2713aSLionel Sambuc   case ARM::VLD1d64Twb_fixed:
2473f4a2713aSLionel Sambuc   case ARM::VLD1d8Qwb_fixed:
2474f4a2713aSLionel Sambuc   case ARM::VLD1d16Qwb_fixed:
2475f4a2713aSLionel Sambuc   case ARM::VLD1d32Qwb_fixed:
2476f4a2713aSLionel Sambuc   case ARM::VLD1d64Qwb_fixed:
2477f4a2713aSLionel Sambuc   case ARM::VLD1d8wb_register:
2478f4a2713aSLionel Sambuc   case ARM::VLD1d16wb_register:
2479f4a2713aSLionel Sambuc   case ARM::VLD1d32wb_register:
2480f4a2713aSLionel Sambuc   case ARM::VLD1d64wb_register:
2481f4a2713aSLionel Sambuc   case ARM::VLD1q8wb_fixed:
2482f4a2713aSLionel Sambuc   case ARM::VLD1q16wb_fixed:
2483f4a2713aSLionel Sambuc   case ARM::VLD1q32wb_fixed:
2484f4a2713aSLionel Sambuc   case ARM::VLD1q64wb_fixed:
2485f4a2713aSLionel Sambuc   case ARM::VLD1q8wb_register:
2486f4a2713aSLionel Sambuc   case ARM::VLD1q16wb_register:
2487f4a2713aSLionel Sambuc   case ARM::VLD1q32wb_register:
2488f4a2713aSLionel Sambuc   case ARM::VLD1q64wb_register:
2489f4a2713aSLionel Sambuc     // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2490f4a2713aSLionel Sambuc     // variant encodes Rm == 0xf. Anything else is a register offset post-
2491f4a2713aSLionel Sambuc     // increment and we need to add the register operand to the instruction.
2492f4a2713aSLionel Sambuc     if (Rm != 0xD && Rm != 0xF &&
2493f4a2713aSLionel Sambuc         !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2494f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2495f4a2713aSLionel Sambuc     break;
2496f4a2713aSLionel Sambuc   case ARM::VLD2d8wb_fixed:
2497f4a2713aSLionel Sambuc   case ARM::VLD2d16wb_fixed:
2498f4a2713aSLionel Sambuc   case ARM::VLD2d32wb_fixed:
2499f4a2713aSLionel Sambuc   case ARM::VLD2b8wb_fixed:
2500f4a2713aSLionel Sambuc   case ARM::VLD2b16wb_fixed:
2501f4a2713aSLionel Sambuc   case ARM::VLD2b32wb_fixed:
2502f4a2713aSLionel Sambuc   case ARM::VLD2q8wb_fixed:
2503f4a2713aSLionel Sambuc   case ARM::VLD2q16wb_fixed:
2504f4a2713aSLionel Sambuc   case ARM::VLD2q32wb_fixed:
2505f4a2713aSLionel Sambuc     break;
2506f4a2713aSLionel Sambuc   }
2507f4a2713aSLionel Sambuc 
2508f4a2713aSLionel Sambuc   return S;
2509f4a2713aSLionel Sambuc }
2510f4a2713aSLionel Sambuc 
DecodeVLDST1Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2511f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
2512f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
2513f4a2713aSLionel Sambuc   unsigned type = fieldFromInstruction(Insn, 8, 4);
2514f4a2713aSLionel Sambuc   unsigned align = fieldFromInstruction(Insn, 4, 2);
2515f4a2713aSLionel Sambuc   if (type == 6 && (align & 2)) return MCDisassembler::Fail;
2516f4a2713aSLionel Sambuc   if (type == 7 && (align & 2)) return MCDisassembler::Fail;
2517f4a2713aSLionel Sambuc   if (type == 10 && align == 3) return MCDisassembler::Fail;
2518f4a2713aSLionel Sambuc 
2519f4a2713aSLionel Sambuc   unsigned load = fieldFromInstruction(Insn, 21, 1);
2520f4a2713aSLionel Sambuc   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2521f4a2713aSLionel Sambuc               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2522f4a2713aSLionel Sambuc }
2523f4a2713aSLionel Sambuc 
DecodeVLDST2Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2524f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
2525f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
2526f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 6, 2);
2527f4a2713aSLionel Sambuc   if (size == 3) return MCDisassembler::Fail;
2528f4a2713aSLionel Sambuc 
2529f4a2713aSLionel Sambuc   unsigned type = fieldFromInstruction(Insn, 8, 4);
2530f4a2713aSLionel Sambuc   unsigned align = fieldFromInstruction(Insn, 4, 2);
2531f4a2713aSLionel Sambuc   if (type == 8 && align == 3) return MCDisassembler::Fail;
2532f4a2713aSLionel Sambuc   if (type == 9 && align == 3) return MCDisassembler::Fail;
2533f4a2713aSLionel Sambuc 
2534f4a2713aSLionel Sambuc   unsigned load = fieldFromInstruction(Insn, 21, 1);
2535f4a2713aSLionel Sambuc   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2536f4a2713aSLionel Sambuc               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2537f4a2713aSLionel Sambuc }
2538f4a2713aSLionel Sambuc 
DecodeVLDST3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2539f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
2540f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
2541f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 6, 2);
2542f4a2713aSLionel Sambuc   if (size == 3) return MCDisassembler::Fail;
2543f4a2713aSLionel Sambuc 
2544f4a2713aSLionel Sambuc   unsigned align = fieldFromInstruction(Insn, 4, 2);
2545f4a2713aSLionel Sambuc   if (align & 2) return MCDisassembler::Fail;
2546f4a2713aSLionel Sambuc 
2547f4a2713aSLionel Sambuc   unsigned load = fieldFromInstruction(Insn, 21, 1);
2548f4a2713aSLionel Sambuc   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2549f4a2713aSLionel Sambuc               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2550f4a2713aSLionel Sambuc }
2551f4a2713aSLionel Sambuc 
DecodeVLDST4Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2552f4a2713aSLionel Sambuc static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
2553f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
2554f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 6, 2);
2555f4a2713aSLionel Sambuc   if (size == 3) return MCDisassembler::Fail;
2556f4a2713aSLionel Sambuc 
2557f4a2713aSLionel Sambuc   unsigned load = fieldFromInstruction(Insn, 21, 1);
2558f4a2713aSLionel Sambuc   return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2559f4a2713aSLionel Sambuc               : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2560f4a2713aSLionel Sambuc }
2561f4a2713aSLionel Sambuc 
DecodeVSTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2562f4a2713aSLionel Sambuc static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
2563f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
2564f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2565f4a2713aSLionel Sambuc 
2566f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2567f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2568f4a2713aSLionel Sambuc   unsigned wb = fieldFromInstruction(Insn, 16, 4);
2569f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2570f4a2713aSLionel Sambuc   Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2571f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2572f4a2713aSLionel Sambuc 
2573f4a2713aSLionel Sambuc   // Writeback Operand
2574f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2575f4a2713aSLionel Sambuc     case ARM::VST1d8wb_fixed:
2576f4a2713aSLionel Sambuc     case ARM::VST1d16wb_fixed:
2577f4a2713aSLionel Sambuc     case ARM::VST1d32wb_fixed:
2578f4a2713aSLionel Sambuc     case ARM::VST1d64wb_fixed:
2579f4a2713aSLionel Sambuc     case ARM::VST1d8wb_register:
2580f4a2713aSLionel Sambuc     case ARM::VST1d16wb_register:
2581f4a2713aSLionel Sambuc     case ARM::VST1d32wb_register:
2582f4a2713aSLionel Sambuc     case ARM::VST1d64wb_register:
2583f4a2713aSLionel Sambuc     case ARM::VST1q8wb_fixed:
2584f4a2713aSLionel Sambuc     case ARM::VST1q16wb_fixed:
2585f4a2713aSLionel Sambuc     case ARM::VST1q32wb_fixed:
2586f4a2713aSLionel Sambuc     case ARM::VST1q64wb_fixed:
2587f4a2713aSLionel Sambuc     case ARM::VST1q8wb_register:
2588f4a2713aSLionel Sambuc     case ARM::VST1q16wb_register:
2589f4a2713aSLionel Sambuc     case ARM::VST1q32wb_register:
2590f4a2713aSLionel Sambuc     case ARM::VST1q64wb_register:
2591f4a2713aSLionel Sambuc     case ARM::VST1d8Twb_fixed:
2592f4a2713aSLionel Sambuc     case ARM::VST1d16Twb_fixed:
2593f4a2713aSLionel Sambuc     case ARM::VST1d32Twb_fixed:
2594f4a2713aSLionel Sambuc     case ARM::VST1d64Twb_fixed:
2595f4a2713aSLionel Sambuc     case ARM::VST1d8Twb_register:
2596f4a2713aSLionel Sambuc     case ARM::VST1d16Twb_register:
2597f4a2713aSLionel Sambuc     case ARM::VST1d32Twb_register:
2598f4a2713aSLionel Sambuc     case ARM::VST1d64Twb_register:
2599f4a2713aSLionel Sambuc     case ARM::VST1d8Qwb_fixed:
2600f4a2713aSLionel Sambuc     case ARM::VST1d16Qwb_fixed:
2601f4a2713aSLionel Sambuc     case ARM::VST1d32Qwb_fixed:
2602f4a2713aSLionel Sambuc     case ARM::VST1d64Qwb_fixed:
2603f4a2713aSLionel Sambuc     case ARM::VST1d8Qwb_register:
2604f4a2713aSLionel Sambuc     case ARM::VST1d16Qwb_register:
2605f4a2713aSLionel Sambuc     case ARM::VST1d32Qwb_register:
2606f4a2713aSLionel Sambuc     case ARM::VST1d64Qwb_register:
2607f4a2713aSLionel Sambuc     case ARM::VST2d8wb_fixed:
2608f4a2713aSLionel Sambuc     case ARM::VST2d16wb_fixed:
2609f4a2713aSLionel Sambuc     case ARM::VST2d32wb_fixed:
2610f4a2713aSLionel Sambuc     case ARM::VST2d8wb_register:
2611f4a2713aSLionel Sambuc     case ARM::VST2d16wb_register:
2612f4a2713aSLionel Sambuc     case ARM::VST2d32wb_register:
2613f4a2713aSLionel Sambuc     case ARM::VST2q8wb_fixed:
2614f4a2713aSLionel Sambuc     case ARM::VST2q16wb_fixed:
2615f4a2713aSLionel Sambuc     case ARM::VST2q32wb_fixed:
2616f4a2713aSLionel Sambuc     case ARM::VST2q8wb_register:
2617f4a2713aSLionel Sambuc     case ARM::VST2q16wb_register:
2618f4a2713aSLionel Sambuc     case ARM::VST2q32wb_register:
2619f4a2713aSLionel Sambuc     case ARM::VST2b8wb_fixed:
2620f4a2713aSLionel Sambuc     case ARM::VST2b16wb_fixed:
2621f4a2713aSLionel Sambuc     case ARM::VST2b32wb_fixed:
2622f4a2713aSLionel Sambuc     case ARM::VST2b8wb_register:
2623f4a2713aSLionel Sambuc     case ARM::VST2b16wb_register:
2624f4a2713aSLionel Sambuc     case ARM::VST2b32wb_register:
2625f4a2713aSLionel Sambuc       if (Rm == 0xF)
2626f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2627f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateImm(0));
2628f4a2713aSLionel Sambuc       break;
2629f4a2713aSLionel Sambuc     case ARM::VST3d8_UPD:
2630f4a2713aSLionel Sambuc     case ARM::VST3d16_UPD:
2631f4a2713aSLionel Sambuc     case ARM::VST3d32_UPD:
2632f4a2713aSLionel Sambuc     case ARM::VST3q8_UPD:
2633f4a2713aSLionel Sambuc     case ARM::VST3q16_UPD:
2634f4a2713aSLionel Sambuc     case ARM::VST3q32_UPD:
2635f4a2713aSLionel Sambuc     case ARM::VST4d8_UPD:
2636f4a2713aSLionel Sambuc     case ARM::VST4d16_UPD:
2637f4a2713aSLionel Sambuc     case ARM::VST4d32_UPD:
2638f4a2713aSLionel Sambuc     case ARM::VST4q8_UPD:
2639f4a2713aSLionel Sambuc     case ARM::VST4q16_UPD:
2640f4a2713aSLionel Sambuc     case ARM::VST4q32_UPD:
2641f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2642f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2643f4a2713aSLionel Sambuc       break;
2644f4a2713aSLionel Sambuc     default:
2645f4a2713aSLionel Sambuc       break;
2646f4a2713aSLionel Sambuc   }
2647f4a2713aSLionel Sambuc 
2648f4a2713aSLionel Sambuc   // AddrMode6 Base (register+alignment)
2649f4a2713aSLionel Sambuc   if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2650f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2651f4a2713aSLionel Sambuc 
2652f4a2713aSLionel Sambuc   // AddrMode6 Offset (register)
2653f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2654f4a2713aSLionel Sambuc     default:
2655f4a2713aSLionel Sambuc       if (Rm == 0xD)
2656f4a2713aSLionel Sambuc         Inst.addOperand(MCOperand::CreateReg(0));
2657f4a2713aSLionel Sambuc       else if (Rm != 0xF) {
2658f4a2713aSLionel Sambuc         if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2659f4a2713aSLionel Sambuc           return MCDisassembler::Fail;
2660f4a2713aSLionel Sambuc       }
2661f4a2713aSLionel Sambuc       break;
2662f4a2713aSLionel Sambuc     case ARM::VST1d8wb_fixed:
2663f4a2713aSLionel Sambuc     case ARM::VST1d16wb_fixed:
2664f4a2713aSLionel Sambuc     case ARM::VST1d32wb_fixed:
2665f4a2713aSLionel Sambuc     case ARM::VST1d64wb_fixed:
2666f4a2713aSLionel Sambuc     case ARM::VST1q8wb_fixed:
2667f4a2713aSLionel Sambuc     case ARM::VST1q16wb_fixed:
2668f4a2713aSLionel Sambuc     case ARM::VST1q32wb_fixed:
2669f4a2713aSLionel Sambuc     case ARM::VST1q64wb_fixed:
2670f4a2713aSLionel Sambuc     case ARM::VST1d8Twb_fixed:
2671f4a2713aSLionel Sambuc     case ARM::VST1d16Twb_fixed:
2672f4a2713aSLionel Sambuc     case ARM::VST1d32Twb_fixed:
2673f4a2713aSLionel Sambuc     case ARM::VST1d64Twb_fixed:
2674f4a2713aSLionel Sambuc     case ARM::VST1d8Qwb_fixed:
2675f4a2713aSLionel Sambuc     case ARM::VST1d16Qwb_fixed:
2676f4a2713aSLionel Sambuc     case ARM::VST1d32Qwb_fixed:
2677f4a2713aSLionel Sambuc     case ARM::VST1d64Qwb_fixed:
2678f4a2713aSLionel Sambuc     case ARM::VST2d8wb_fixed:
2679f4a2713aSLionel Sambuc     case ARM::VST2d16wb_fixed:
2680f4a2713aSLionel Sambuc     case ARM::VST2d32wb_fixed:
2681f4a2713aSLionel Sambuc     case ARM::VST2q8wb_fixed:
2682f4a2713aSLionel Sambuc     case ARM::VST2q16wb_fixed:
2683f4a2713aSLionel Sambuc     case ARM::VST2q32wb_fixed:
2684f4a2713aSLionel Sambuc     case ARM::VST2b8wb_fixed:
2685f4a2713aSLionel Sambuc     case ARM::VST2b16wb_fixed:
2686f4a2713aSLionel Sambuc     case ARM::VST2b32wb_fixed:
2687f4a2713aSLionel Sambuc       break;
2688f4a2713aSLionel Sambuc   }
2689f4a2713aSLionel Sambuc 
2690f4a2713aSLionel Sambuc 
2691f4a2713aSLionel Sambuc   // First input register
2692f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2693f4a2713aSLionel Sambuc   case ARM::VST1q16:
2694f4a2713aSLionel Sambuc   case ARM::VST1q32:
2695f4a2713aSLionel Sambuc   case ARM::VST1q64:
2696f4a2713aSLionel Sambuc   case ARM::VST1q8:
2697f4a2713aSLionel Sambuc   case ARM::VST1q16wb_fixed:
2698f4a2713aSLionel Sambuc   case ARM::VST1q16wb_register:
2699f4a2713aSLionel Sambuc   case ARM::VST1q32wb_fixed:
2700f4a2713aSLionel Sambuc   case ARM::VST1q32wb_register:
2701f4a2713aSLionel Sambuc   case ARM::VST1q64wb_fixed:
2702f4a2713aSLionel Sambuc   case ARM::VST1q64wb_register:
2703f4a2713aSLionel Sambuc   case ARM::VST1q8wb_fixed:
2704f4a2713aSLionel Sambuc   case ARM::VST1q8wb_register:
2705f4a2713aSLionel Sambuc   case ARM::VST2d16:
2706f4a2713aSLionel Sambuc   case ARM::VST2d32:
2707f4a2713aSLionel Sambuc   case ARM::VST2d8:
2708f4a2713aSLionel Sambuc   case ARM::VST2d16wb_fixed:
2709f4a2713aSLionel Sambuc   case ARM::VST2d16wb_register:
2710f4a2713aSLionel Sambuc   case ARM::VST2d32wb_fixed:
2711f4a2713aSLionel Sambuc   case ARM::VST2d32wb_register:
2712f4a2713aSLionel Sambuc   case ARM::VST2d8wb_fixed:
2713f4a2713aSLionel Sambuc   case ARM::VST2d8wb_register:
2714f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2715f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2716f4a2713aSLionel Sambuc     break;
2717f4a2713aSLionel Sambuc   case ARM::VST2b16:
2718f4a2713aSLionel Sambuc   case ARM::VST2b32:
2719f4a2713aSLionel Sambuc   case ARM::VST2b8:
2720f4a2713aSLionel Sambuc   case ARM::VST2b16wb_fixed:
2721f4a2713aSLionel Sambuc   case ARM::VST2b16wb_register:
2722f4a2713aSLionel Sambuc   case ARM::VST2b32wb_fixed:
2723f4a2713aSLionel Sambuc   case ARM::VST2b32wb_register:
2724f4a2713aSLionel Sambuc   case ARM::VST2b8wb_fixed:
2725f4a2713aSLionel Sambuc   case ARM::VST2b8wb_register:
2726f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2727f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2728f4a2713aSLionel Sambuc     break;
2729f4a2713aSLionel Sambuc   default:
2730f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2731f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2732f4a2713aSLionel Sambuc   }
2733f4a2713aSLionel Sambuc 
2734f4a2713aSLionel Sambuc   // Second input register
2735f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2736f4a2713aSLionel Sambuc     case ARM::VST3d8:
2737f4a2713aSLionel Sambuc     case ARM::VST3d16:
2738f4a2713aSLionel Sambuc     case ARM::VST3d32:
2739f4a2713aSLionel Sambuc     case ARM::VST3d8_UPD:
2740f4a2713aSLionel Sambuc     case ARM::VST3d16_UPD:
2741f4a2713aSLionel Sambuc     case ARM::VST3d32_UPD:
2742f4a2713aSLionel Sambuc     case ARM::VST4d8:
2743f4a2713aSLionel Sambuc     case ARM::VST4d16:
2744f4a2713aSLionel Sambuc     case ARM::VST4d32:
2745f4a2713aSLionel Sambuc     case ARM::VST4d8_UPD:
2746f4a2713aSLionel Sambuc     case ARM::VST4d16_UPD:
2747f4a2713aSLionel Sambuc     case ARM::VST4d32_UPD:
2748f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2749f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2750f4a2713aSLionel Sambuc       break;
2751f4a2713aSLionel Sambuc     case ARM::VST3q8:
2752f4a2713aSLionel Sambuc     case ARM::VST3q16:
2753f4a2713aSLionel Sambuc     case ARM::VST3q32:
2754f4a2713aSLionel Sambuc     case ARM::VST3q8_UPD:
2755f4a2713aSLionel Sambuc     case ARM::VST3q16_UPD:
2756f4a2713aSLionel Sambuc     case ARM::VST3q32_UPD:
2757f4a2713aSLionel Sambuc     case ARM::VST4q8:
2758f4a2713aSLionel Sambuc     case ARM::VST4q16:
2759f4a2713aSLionel Sambuc     case ARM::VST4q32:
2760f4a2713aSLionel Sambuc     case ARM::VST4q8_UPD:
2761f4a2713aSLionel Sambuc     case ARM::VST4q16_UPD:
2762f4a2713aSLionel Sambuc     case ARM::VST4q32_UPD:
2763f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2764f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2765f4a2713aSLionel Sambuc       break;
2766f4a2713aSLionel Sambuc     default:
2767f4a2713aSLionel Sambuc       break;
2768f4a2713aSLionel Sambuc   }
2769f4a2713aSLionel Sambuc 
2770f4a2713aSLionel Sambuc   // Third input register
2771f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2772f4a2713aSLionel Sambuc     case ARM::VST3d8:
2773f4a2713aSLionel Sambuc     case ARM::VST3d16:
2774f4a2713aSLionel Sambuc     case ARM::VST3d32:
2775f4a2713aSLionel Sambuc     case ARM::VST3d8_UPD:
2776f4a2713aSLionel Sambuc     case ARM::VST3d16_UPD:
2777f4a2713aSLionel Sambuc     case ARM::VST3d32_UPD:
2778f4a2713aSLionel Sambuc     case ARM::VST4d8:
2779f4a2713aSLionel Sambuc     case ARM::VST4d16:
2780f4a2713aSLionel Sambuc     case ARM::VST4d32:
2781f4a2713aSLionel Sambuc     case ARM::VST4d8_UPD:
2782f4a2713aSLionel Sambuc     case ARM::VST4d16_UPD:
2783f4a2713aSLionel Sambuc     case ARM::VST4d32_UPD:
2784f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2785f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2786f4a2713aSLionel Sambuc       break;
2787f4a2713aSLionel Sambuc     case ARM::VST3q8:
2788f4a2713aSLionel Sambuc     case ARM::VST3q16:
2789f4a2713aSLionel Sambuc     case ARM::VST3q32:
2790f4a2713aSLionel Sambuc     case ARM::VST3q8_UPD:
2791f4a2713aSLionel Sambuc     case ARM::VST3q16_UPD:
2792f4a2713aSLionel Sambuc     case ARM::VST3q32_UPD:
2793f4a2713aSLionel Sambuc     case ARM::VST4q8:
2794f4a2713aSLionel Sambuc     case ARM::VST4q16:
2795f4a2713aSLionel Sambuc     case ARM::VST4q32:
2796f4a2713aSLionel Sambuc     case ARM::VST4q8_UPD:
2797f4a2713aSLionel Sambuc     case ARM::VST4q16_UPD:
2798f4a2713aSLionel Sambuc     case ARM::VST4q32_UPD:
2799f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2800f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2801f4a2713aSLionel Sambuc       break;
2802f4a2713aSLionel Sambuc     default:
2803f4a2713aSLionel Sambuc       break;
2804f4a2713aSLionel Sambuc   }
2805f4a2713aSLionel Sambuc 
2806f4a2713aSLionel Sambuc   // Fourth input register
2807f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2808f4a2713aSLionel Sambuc     case ARM::VST4d8:
2809f4a2713aSLionel Sambuc     case ARM::VST4d16:
2810f4a2713aSLionel Sambuc     case ARM::VST4d32:
2811f4a2713aSLionel Sambuc     case ARM::VST4d8_UPD:
2812f4a2713aSLionel Sambuc     case ARM::VST4d16_UPD:
2813f4a2713aSLionel Sambuc     case ARM::VST4d32_UPD:
2814f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2815f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2816f4a2713aSLionel Sambuc       break;
2817f4a2713aSLionel Sambuc     case ARM::VST4q8:
2818f4a2713aSLionel Sambuc     case ARM::VST4q16:
2819f4a2713aSLionel Sambuc     case ARM::VST4q32:
2820f4a2713aSLionel Sambuc     case ARM::VST4q8_UPD:
2821f4a2713aSLionel Sambuc     case ARM::VST4q16_UPD:
2822f4a2713aSLionel Sambuc     case ARM::VST4q32_UPD:
2823f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2824f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
2825f4a2713aSLionel Sambuc       break;
2826f4a2713aSLionel Sambuc     default:
2827f4a2713aSLionel Sambuc       break;
2828f4a2713aSLionel Sambuc   }
2829f4a2713aSLionel Sambuc 
2830f4a2713aSLionel Sambuc   return S;
2831f4a2713aSLionel Sambuc }
2832f4a2713aSLionel Sambuc 
DecodeVLD1DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2833f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
2834f4a2713aSLionel Sambuc                                     uint64_t Address, const void *Decoder) {
2835f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2836f4a2713aSLionel Sambuc 
2837f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2838f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2839f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2840f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2841f4a2713aSLionel Sambuc   unsigned align = fieldFromInstruction(Insn, 4, 1);
2842f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 6, 2);
2843f4a2713aSLionel Sambuc 
2844f4a2713aSLionel Sambuc   if (size == 0 && align == 1)
2845f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2846f4a2713aSLionel Sambuc   align *= (1 << size);
2847f4a2713aSLionel Sambuc 
2848f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2849f4a2713aSLionel Sambuc   case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
2850f4a2713aSLionel Sambuc   case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
2851f4a2713aSLionel Sambuc   case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
2852f4a2713aSLionel Sambuc   case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
2853f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2854f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2855f4a2713aSLionel Sambuc     break;
2856f4a2713aSLionel Sambuc   default:
2857f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2858f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2859f4a2713aSLionel Sambuc     break;
2860f4a2713aSLionel Sambuc   }
2861f4a2713aSLionel Sambuc   if (Rm != 0xF) {
2862f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2863f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2864f4a2713aSLionel Sambuc   }
2865f4a2713aSLionel Sambuc 
2866f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2867f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2868f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
2869f4a2713aSLionel Sambuc 
2870f4a2713aSLionel Sambuc   // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2871f4a2713aSLionel Sambuc   // variant encodes Rm == 0xf. Anything else is a register offset post-
2872f4a2713aSLionel Sambuc   // increment and we need to add the register operand to the instruction.
2873f4a2713aSLionel Sambuc   if (Rm != 0xD && Rm != 0xF &&
2874f4a2713aSLionel Sambuc       !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2875f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2876f4a2713aSLionel Sambuc 
2877f4a2713aSLionel Sambuc   return S;
2878f4a2713aSLionel Sambuc }
2879f4a2713aSLionel Sambuc 
DecodeVLD2DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2880f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
2881f4a2713aSLionel Sambuc                                     uint64_t Address, const void *Decoder) {
2882f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2883f4a2713aSLionel Sambuc 
2884f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2885f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2886f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2887f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2888f4a2713aSLionel Sambuc   unsigned align = fieldFromInstruction(Insn, 4, 1);
2889f4a2713aSLionel Sambuc   unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
2890f4a2713aSLionel Sambuc   align *= 2*size;
2891f4a2713aSLionel Sambuc 
2892f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
2893f4a2713aSLionel Sambuc   case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
2894f4a2713aSLionel Sambuc   case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
2895f4a2713aSLionel Sambuc   case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
2896f4a2713aSLionel Sambuc   case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
2897f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2898f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2899f4a2713aSLionel Sambuc     break;
2900f4a2713aSLionel Sambuc   case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
2901f4a2713aSLionel Sambuc   case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
2902f4a2713aSLionel Sambuc   case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
2903f4a2713aSLionel Sambuc   case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
2904f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2905f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2906f4a2713aSLionel Sambuc     break;
2907f4a2713aSLionel Sambuc   default:
2908f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2909f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2910f4a2713aSLionel Sambuc     break;
2911f4a2713aSLionel Sambuc   }
2912f4a2713aSLionel Sambuc 
2913f4a2713aSLionel Sambuc   if (Rm != 0xF)
2914f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(0));
2915f4a2713aSLionel Sambuc 
2916f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2917f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2918f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
2919f4a2713aSLionel Sambuc 
2920f4a2713aSLionel Sambuc   if (Rm != 0xD && Rm != 0xF) {
2921f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2922f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2923f4a2713aSLionel Sambuc   }
2924f4a2713aSLionel Sambuc 
2925f4a2713aSLionel Sambuc   return S;
2926f4a2713aSLionel Sambuc }
2927f4a2713aSLionel Sambuc 
DecodeVLD3DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2928f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
2929f4a2713aSLionel Sambuc                                     uint64_t Address, const void *Decoder) {
2930f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2931f4a2713aSLionel Sambuc 
2932f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2933f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2934f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2935f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2936f4a2713aSLionel Sambuc   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
2937f4a2713aSLionel Sambuc 
2938f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2939f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2940f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2941f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2942f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2943f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2944f4a2713aSLionel Sambuc   if (Rm != 0xF) {
2945f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2946f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2947f4a2713aSLionel Sambuc   }
2948f4a2713aSLionel Sambuc 
2949f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2950f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2951f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(0));
2952f4a2713aSLionel Sambuc 
2953f4a2713aSLionel Sambuc   if (Rm == 0xD)
2954f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(0));
2955f4a2713aSLionel Sambuc   else if (Rm != 0xF) {
2956f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2957f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2958f4a2713aSLionel Sambuc   }
2959f4a2713aSLionel Sambuc 
2960f4a2713aSLionel Sambuc   return S;
2961f4a2713aSLionel Sambuc }
2962f4a2713aSLionel Sambuc 
DecodeVLD4DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)2963f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
2964f4a2713aSLionel Sambuc                                     uint64_t Address, const void *Decoder) {
2965f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
2966f4a2713aSLionel Sambuc 
2967f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2968f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2969f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2970f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2971f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 6, 2);
2972f4a2713aSLionel Sambuc   unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
2973f4a2713aSLionel Sambuc   unsigned align = fieldFromInstruction(Insn, 4, 1);
2974f4a2713aSLionel Sambuc 
2975f4a2713aSLionel Sambuc   if (size == 0x3) {
2976f4a2713aSLionel Sambuc     if (align == 0)
2977f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2978f4a2713aSLionel Sambuc     align = 16;
2979f4a2713aSLionel Sambuc   } else {
2980f4a2713aSLionel Sambuc     if (size == 2) {
2981f4a2713aSLionel Sambuc       align *= 8;
2982f4a2713aSLionel Sambuc     } else {
2983f4a2713aSLionel Sambuc       size = 1 << size;
2984f4a2713aSLionel Sambuc       align *= 4*size;
2985f4a2713aSLionel Sambuc     }
2986f4a2713aSLionel Sambuc   }
2987f4a2713aSLionel Sambuc 
2988f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2989f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2990f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2991f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2992f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2993f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2994f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
2995f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
2996f4a2713aSLionel Sambuc   if (Rm != 0xF) {
2997f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2998f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
2999f4a2713aSLionel Sambuc   }
3000f4a2713aSLionel Sambuc 
3001f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3002f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3003f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
3004f4a2713aSLionel Sambuc 
3005f4a2713aSLionel Sambuc   if (Rm == 0xD)
3006f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(0));
3007f4a2713aSLionel Sambuc   else if (Rm != 0xF) {
3008f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3009f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3010f4a2713aSLionel Sambuc   }
3011f4a2713aSLionel Sambuc 
3012f4a2713aSLionel Sambuc   return S;
3013f4a2713aSLionel Sambuc }
3014f4a2713aSLionel Sambuc 
3015f4a2713aSLionel Sambuc static DecodeStatus
DecodeNEONModImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3016f4a2713aSLionel Sambuc DecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn,
3017f4a2713aSLionel Sambuc                             uint64_t Address, const void *Decoder) {
3018f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3019f4a2713aSLionel Sambuc 
3020f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3021f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3022f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 4);
3023f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 16, 3) << 4;
3024f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 24, 1) << 7;
3025f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 8, 4) << 8;
3026f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 5, 1) << 12;
3027f4a2713aSLionel Sambuc   unsigned Q = fieldFromInstruction(Insn, 6, 1);
3028f4a2713aSLionel Sambuc 
3029f4a2713aSLionel Sambuc   if (Q) {
3030f4a2713aSLionel Sambuc     if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3031f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3032f4a2713aSLionel Sambuc   } else {
3033f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3034f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3035f4a2713aSLionel Sambuc   }
3036f4a2713aSLionel Sambuc 
3037f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3038f4a2713aSLionel Sambuc 
3039f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
3040f4a2713aSLionel Sambuc     case ARM::VORRiv4i16:
3041f4a2713aSLionel Sambuc     case ARM::VORRiv2i32:
3042f4a2713aSLionel Sambuc     case ARM::VBICiv4i16:
3043f4a2713aSLionel Sambuc     case ARM::VBICiv2i32:
3044f4a2713aSLionel Sambuc       if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3045f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
3046f4a2713aSLionel Sambuc       break;
3047f4a2713aSLionel Sambuc     case ARM::VORRiv8i16:
3048f4a2713aSLionel Sambuc     case ARM::VORRiv4i32:
3049f4a2713aSLionel Sambuc     case ARM::VBICiv8i16:
3050f4a2713aSLionel Sambuc     case ARM::VBICiv4i32:
3051f4a2713aSLionel Sambuc       if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3052f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
3053f4a2713aSLionel Sambuc       break;
3054f4a2713aSLionel Sambuc     default:
3055f4a2713aSLionel Sambuc       break;
3056f4a2713aSLionel Sambuc   }
3057f4a2713aSLionel Sambuc 
3058f4a2713aSLionel Sambuc   return S;
3059f4a2713aSLionel Sambuc }
3060f4a2713aSLionel Sambuc 
DecodeVSHLMaxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3061f4a2713aSLionel Sambuc static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
3062f4a2713aSLionel Sambuc                                         uint64_t Address, const void *Decoder) {
3063f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3064f4a2713aSLionel Sambuc 
3065f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3066f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3067f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3068f4a2713aSLionel Sambuc   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3069f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 18, 2);
3070f4a2713aSLionel Sambuc 
3071f4a2713aSLionel Sambuc   if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3072f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3073f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3074f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3075f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(8 << size));
3076f4a2713aSLionel Sambuc 
3077f4a2713aSLionel Sambuc   return S;
3078f4a2713aSLionel Sambuc }
3079f4a2713aSLionel Sambuc 
DecodeShiftRight8Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3080f4a2713aSLionel Sambuc static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
3081f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
3082f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(8 - Val));
3083f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3084f4a2713aSLionel Sambuc }
3085f4a2713aSLionel Sambuc 
DecodeShiftRight16Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3086f4a2713aSLionel Sambuc static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
3087f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
3088f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(16 - Val));
3089f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3090f4a2713aSLionel Sambuc }
3091f4a2713aSLionel Sambuc 
DecodeShiftRight32Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3092f4a2713aSLionel Sambuc static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
3093f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
3094f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(32 - Val));
3095f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3096f4a2713aSLionel Sambuc }
3097f4a2713aSLionel Sambuc 
DecodeShiftRight64Imm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3098f4a2713aSLionel Sambuc static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
3099f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
3100f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(64 - Val));
3101f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3102f4a2713aSLionel Sambuc }
3103f4a2713aSLionel Sambuc 
DecodeTBLInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3104f4a2713aSLionel Sambuc static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
3105f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
3106f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3107f4a2713aSLionel Sambuc 
3108f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3109f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3110f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3111f4a2713aSLionel Sambuc   Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
3112f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3113f4a2713aSLionel Sambuc   Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3114f4a2713aSLionel Sambuc   unsigned op = fieldFromInstruction(Insn, 6, 1);
3115f4a2713aSLionel Sambuc 
3116f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3117f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3118f4a2713aSLionel Sambuc   if (op) {
3119f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3120f4a2713aSLionel Sambuc     return MCDisassembler::Fail; // Writeback
3121f4a2713aSLionel Sambuc   }
3122f4a2713aSLionel Sambuc 
3123f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
3124f4a2713aSLionel Sambuc   case ARM::VTBL2:
3125f4a2713aSLionel Sambuc   case ARM::VTBX2:
3126f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
3127f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3128f4a2713aSLionel Sambuc     break;
3129f4a2713aSLionel Sambuc   default:
3130f4a2713aSLionel Sambuc     if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
3131f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3132f4a2713aSLionel Sambuc   }
3133f4a2713aSLionel Sambuc 
3134f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3135f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3136f4a2713aSLionel Sambuc 
3137f4a2713aSLionel Sambuc   return S;
3138f4a2713aSLionel Sambuc }
3139f4a2713aSLionel Sambuc 
DecodeThumbAddSpecialReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)3140f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
3141f4a2713aSLionel Sambuc                                      uint64_t Address, const void *Decoder) {
3142f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3143f4a2713aSLionel Sambuc 
3144f4a2713aSLionel Sambuc   unsigned dst = fieldFromInstruction(Insn, 8, 3);
3145f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 8);
3146f4a2713aSLionel Sambuc 
3147f4a2713aSLionel Sambuc   if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
3148f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3149f4a2713aSLionel Sambuc 
3150f4a2713aSLionel Sambuc   switch(Inst.getOpcode()) {
3151f4a2713aSLionel Sambuc     default:
3152f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3153f4a2713aSLionel Sambuc     case ARM::tADR:
3154f4a2713aSLionel Sambuc       break; // tADR does not explicitly represent the PC as an operand.
3155f4a2713aSLionel Sambuc     case ARM::tADDrSPi:
3156f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3157f4a2713aSLionel Sambuc       break;
3158f4a2713aSLionel Sambuc   }
3159f4a2713aSLionel Sambuc 
3160f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3161f4a2713aSLionel Sambuc   return S;
3162f4a2713aSLionel Sambuc }
3163f4a2713aSLionel Sambuc 
DecodeThumbBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3164f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
3165f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
3166f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
3167f4a2713aSLionel Sambuc                                 true, 2, Inst, Decoder))
3168f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
3169f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3170f4a2713aSLionel Sambuc }
3171f4a2713aSLionel Sambuc 
DecodeT2BROperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3172f4a2713aSLionel Sambuc static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
3173f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
3174f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
3175f4a2713aSLionel Sambuc                                 true, 4, Inst, Decoder))
3176f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
3177f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3178f4a2713aSLionel Sambuc }
3179f4a2713aSLionel Sambuc 
DecodeThumbCmpBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3180f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
3181f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
3182f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
3183f4a2713aSLionel Sambuc                                 true, 2, Inst, Decoder))
3184f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(Val << 1));
3185f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3186f4a2713aSLionel Sambuc }
3187f4a2713aSLionel Sambuc 
DecodeThumbAddrModeRR(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3188f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
3189f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
3190f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3191f4a2713aSLionel Sambuc 
3192f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 0, 3);
3193f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Val, 3, 3);
3194f4a2713aSLionel Sambuc 
3195f4a2713aSLionel Sambuc   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3196f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3197f4a2713aSLionel Sambuc   if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
3198f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3199f4a2713aSLionel Sambuc 
3200f4a2713aSLionel Sambuc   return S;
3201f4a2713aSLionel Sambuc }
3202f4a2713aSLionel Sambuc 
DecodeThumbAddrModeIS(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3203f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
3204f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
3205f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3206f4a2713aSLionel Sambuc 
3207f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 0, 3);
3208f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 3, 5);
3209f4a2713aSLionel Sambuc 
3210f4a2713aSLionel Sambuc   if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3211f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3212f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3213f4a2713aSLionel Sambuc 
3214f4a2713aSLionel Sambuc   return S;
3215f4a2713aSLionel Sambuc }
3216f4a2713aSLionel Sambuc 
DecodeThumbAddrModePC(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3217f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
3218f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
3219f4a2713aSLionel Sambuc   unsigned imm = Val << 2;
3220f4a2713aSLionel Sambuc 
3221f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3222f4a2713aSLionel Sambuc   tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
3223f4a2713aSLionel Sambuc 
3224f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3225f4a2713aSLionel Sambuc }
3226f4a2713aSLionel Sambuc 
DecodeThumbAddrModeSP(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3227f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
3228f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
3229f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3230f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Val));
3231f4a2713aSLionel Sambuc 
3232f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3233f4a2713aSLionel Sambuc }
3234f4a2713aSLionel Sambuc 
DecodeT2AddrModeSOReg(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3235f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
3236f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
3237f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3238f4a2713aSLionel Sambuc 
3239f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 6, 4);
3240f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Val, 2, 4);
3241f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 0, 2);
3242f4a2713aSLionel Sambuc 
3243f4a2713aSLionel Sambuc   // Thumb stores cannot use PC as dest register.
3244f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
3245f4a2713aSLionel Sambuc   case ARM::t2STRHs:
3246f4a2713aSLionel Sambuc   case ARM::t2STRBs:
3247f4a2713aSLionel Sambuc   case ARM::t2STRs:
3248f4a2713aSLionel Sambuc     if (Rn == 15)
3249f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3250f4a2713aSLionel Sambuc   default:
3251f4a2713aSLionel Sambuc     break;
3252f4a2713aSLionel Sambuc   }
3253f4a2713aSLionel Sambuc 
3254f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3255f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3256f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3257f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3258f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3259f4a2713aSLionel Sambuc 
3260f4a2713aSLionel Sambuc   return S;
3261f4a2713aSLionel Sambuc }
3262f4a2713aSLionel Sambuc 
DecodeT2LoadShift(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3263f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
3264f4a2713aSLionel Sambuc                               uint64_t Address, const void *Decoder) {
3265f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3266f4a2713aSLionel Sambuc 
3267f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3268f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3269f4a2713aSLionel Sambuc 
3270*0a6a1f1dSLionel Sambuc   uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3271*0a6a1f1dSLionel Sambuc                                                           .getFeatureBits();
3272*0a6a1f1dSLionel Sambuc   bool hasMP = featureBits & ARM::FeatureMP;
3273*0a6a1f1dSLionel Sambuc   bool hasV7Ops = featureBits & ARM::HasV7Ops;
3274*0a6a1f1dSLionel Sambuc 
3275f4a2713aSLionel Sambuc   if (Rn == 15) {
3276f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
3277f4a2713aSLionel Sambuc     case ARM::t2LDRBs:
3278f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRBpci);
3279f4a2713aSLionel Sambuc       break;
3280f4a2713aSLionel Sambuc     case ARM::t2LDRHs:
3281f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRHpci);
3282f4a2713aSLionel Sambuc       break;
3283f4a2713aSLionel Sambuc     case ARM::t2LDRSHs:
3284f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRSHpci);
3285f4a2713aSLionel Sambuc       break;
3286f4a2713aSLionel Sambuc     case ARM::t2LDRSBs:
3287f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRSBpci);
3288f4a2713aSLionel Sambuc       break;
3289f4a2713aSLionel Sambuc     case ARM::t2LDRs:
3290f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRpci);
3291f4a2713aSLionel Sambuc       break;
3292f4a2713aSLionel Sambuc     case ARM::t2PLDs:
3293f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2PLDpci);
3294f4a2713aSLionel Sambuc       break;
3295f4a2713aSLionel Sambuc     case ARM::t2PLIs:
3296f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2PLIpci);
3297f4a2713aSLionel Sambuc       break;
3298f4a2713aSLionel Sambuc     default:
3299f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3300f4a2713aSLionel Sambuc     }
3301f4a2713aSLionel Sambuc 
3302f4a2713aSLionel Sambuc     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3303f4a2713aSLionel Sambuc   }
3304f4a2713aSLionel Sambuc 
3305f4a2713aSLionel Sambuc   if (Rt == 15) {
3306f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
3307f4a2713aSLionel Sambuc     case ARM::t2LDRSHs:
3308f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3309f4a2713aSLionel Sambuc     case ARM::t2LDRHs:
3310f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2PLDWs);
3311f4a2713aSLionel Sambuc       break;
3312*0a6a1f1dSLionel Sambuc     case ARM::t2LDRSBs:
3313*0a6a1f1dSLionel Sambuc       Inst.setOpcode(ARM::t2PLIs);
3314f4a2713aSLionel Sambuc     default:
3315f4a2713aSLionel Sambuc       break;
3316f4a2713aSLionel Sambuc     }
3317f4a2713aSLionel Sambuc   }
3318f4a2713aSLionel Sambuc 
3319f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
3320f4a2713aSLionel Sambuc     case ARM::t2PLDs:
3321*0a6a1f1dSLionel Sambuc       break;
3322f4a2713aSLionel Sambuc     case ARM::t2PLIs:
3323*0a6a1f1dSLionel Sambuc       if (!hasV7Ops)
3324*0a6a1f1dSLionel Sambuc         return MCDisassembler::Fail;
3325*0a6a1f1dSLionel Sambuc       break;
3326*0a6a1f1dSLionel Sambuc     case ARM::t2PLDWs:
3327*0a6a1f1dSLionel Sambuc       if (!hasV7Ops || !hasMP)
3328*0a6a1f1dSLionel Sambuc         return MCDisassembler::Fail;
3329f4a2713aSLionel Sambuc       break;
3330f4a2713aSLionel Sambuc     default:
3331f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3332f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
3333f4a2713aSLionel Sambuc   }
3334f4a2713aSLionel Sambuc 
3335f4a2713aSLionel Sambuc   unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
3336f4a2713aSLionel Sambuc   addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
3337f4a2713aSLionel Sambuc   addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
3338f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
3339f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3340f4a2713aSLionel Sambuc 
3341f4a2713aSLionel Sambuc   return S;
3342f4a2713aSLionel Sambuc }
3343f4a2713aSLionel Sambuc 
DecodeT2LoadImm8(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3344f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
3345f4a2713aSLionel Sambuc                                 uint64_t Address, const void* Decoder) {
3346f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3347f4a2713aSLionel Sambuc 
3348f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3349f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3350f4a2713aSLionel Sambuc   unsigned U = fieldFromInstruction(Insn, 9, 1);
3351f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 8);
3352f4a2713aSLionel Sambuc   imm |= (U << 8);
3353f4a2713aSLionel Sambuc   imm |= (Rn << 9);
3354*0a6a1f1dSLionel Sambuc   unsigned add = fieldFromInstruction(Insn, 9, 1);
3355*0a6a1f1dSLionel Sambuc 
3356*0a6a1f1dSLionel Sambuc   uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3357*0a6a1f1dSLionel Sambuc                                                           .getFeatureBits();
3358*0a6a1f1dSLionel Sambuc   bool hasMP = featureBits & ARM::FeatureMP;
3359*0a6a1f1dSLionel Sambuc   bool hasV7Ops = featureBits & ARM::HasV7Ops;
3360f4a2713aSLionel Sambuc 
3361f4a2713aSLionel Sambuc   if (Rn == 15) {
3362f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
3363f4a2713aSLionel Sambuc     case ARM::t2LDRi8:
3364f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRpci);
3365f4a2713aSLionel Sambuc       break;
3366f4a2713aSLionel Sambuc     case ARM::t2LDRBi8:
3367f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRBpci);
3368f4a2713aSLionel Sambuc       break;
3369f4a2713aSLionel Sambuc     case ARM::t2LDRSBi8:
3370f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRSBpci);
3371f4a2713aSLionel Sambuc       break;
3372f4a2713aSLionel Sambuc     case ARM::t2LDRHi8:
3373f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRHpci);
3374f4a2713aSLionel Sambuc       break;
3375f4a2713aSLionel Sambuc     case ARM::t2LDRSHi8:
3376f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRSHpci);
3377f4a2713aSLionel Sambuc       break;
3378f4a2713aSLionel Sambuc     case ARM::t2PLDi8:
3379f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2PLDpci);
3380f4a2713aSLionel Sambuc       break;
3381f4a2713aSLionel Sambuc     case ARM::t2PLIi8:
3382f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2PLIpci);
3383f4a2713aSLionel Sambuc       break;
3384f4a2713aSLionel Sambuc     default:
3385f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3386f4a2713aSLionel Sambuc     }
3387f4a2713aSLionel Sambuc     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3388f4a2713aSLionel Sambuc   }
3389f4a2713aSLionel Sambuc 
3390f4a2713aSLionel Sambuc   if (Rt == 15) {
3391f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
3392f4a2713aSLionel Sambuc     case ARM::t2LDRSHi8:
3393f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3394*0a6a1f1dSLionel Sambuc     case ARM::t2LDRHi8:
3395*0a6a1f1dSLionel Sambuc       if (!add)
3396*0a6a1f1dSLionel Sambuc         Inst.setOpcode(ARM::t2PLDWi8);
3397*0a6a1f1dSLionel Sambuc       break;
3398*0a6a1f1dSLionel Sambuc     case ARM::t2LDRSBi8:
3399*0a6a1f1dSLionel Sambuc       Inst.setOpcode(ARM::t2PLIi8);
3400*0a6a1f1dSLionel Sambuc       break;
3401f4a2713aSLionel Sambuc     default:
3402f4a2713aSLionel Sambuc       break;
3403f4a2713aSLionel Sambuc     }
3404f4a2713aSLionel Sambuc   }
3405f4a2713aSLionel Sambuc 
3406f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
3407f4a2713aSLionel Sambuc   case ARM::t2PLDi8:
3408*0a6a1f1dSLionel Sambuc     break;
3409f4a2713aSLionel Sambuc   case ARM::t2PLIi8:
3410*0a6a1f1dSLionel Sambuc     if (!hasV7Ops)
3411*0a6a1f1dSLionel Sambuc       return MCDisassembler::Fail;
3412*0a6a1f1dSLionel Sambuc     break;
3413f4a2713aSLionel Sambuc   case ARM::t2PLDWi8:
3414*0a6a1f1dSLionel Sambuc       if (!hasV7Ops || !hasMP)
3415*0a6a1f1dSLionel Sambuc         return MCDisassembler::Fail;
3416f4a2713aSLionel Sambuc       break;
3417f4a2713aSLionel Sambuc   default:
3418f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3419f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3420f4a2713aSLionel Sambuc   }
3421f4a2713aSLionel Sambuc 
3422f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3423f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3424f4a2713aSLionel Sambuc   return S;
3425f4a2713aSLionel Sambuc }
3426f4a2713aSLionel Sambuc 
DecodeT2LoadImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3427f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
3428f4a2713aSLionel Sambuc                                 uint64_t Address, const void* Decoder) {
3429f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3430f4a2713aSLionel Sambuc 
3431f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3432f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3433f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 12);
3434f4a2713aSLionel Sambuc   imm |= (Rn << 13);
3435f4a2713aSLionel Sambuc 
3436*0a6a1f1dSLionel Sambuc   uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3437*0a6a1f1dSLionel Sambuc                                                           .getFeatureBits();
3438*0a6a1f1dSLionel Sambuc   bool hasMP = (featureBits & ARM::FeatureMP);
3439*0a6a1f1dSLionel Sambuc   bool hasV7Ops = (featureBits & ARM::HasV7Ops);
3440*0a6a1f1dSLionel Sambuc 
3441f4a2713aSLionel Sambuc   if (Rn == 15) {
3442f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
3443f4a2713aSLionel Sambuc     case ARM::t2LDRi12:
3444f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRpci);
3445f4a2713aSLionel Sambuc       break;
3446f4a2713aSLionel Sambuc     case ARM::t2LDRHi12:
3447f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRHpci);
3448f4a2713aSLionel Sambuc       break;
3449f4a2713aSLionel Sambuc     case ARM::t2LDRSHi12:
3450f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRSHpci);
3451f4a2713aSLionel Sambuc       break;
3452f4a2713aSLionel Sambuc     case ARM::t2LDRBi12:
3453f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRBpci);
3454f4a2713aSLionel Sambuc       break;
3455f4a2713aSLionel Sambuc     case ARM::t2LDRSBi12:
3456f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRSBpci);
3457f4a2713aSLionel Sambuc       break;
3458f4a2713aSLionel Sambuc     case ARM::t2PLDi12:
3459f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2PLDpci);
3460f4a2713aSLionel Sambuc       break;
3461f4a2713aSLionel Sambuc     case ARM::t2PLIi12:
3462f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2PLIpci);
3463f4a2713aSLionel Sambuc       break;
3464f4a2713aSLionel Sambuc     default:
3465f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3466f4a2713aSLionel Sambuc     }
3467f4a2713aSLionel Sambuc     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3468f4a2713aSLionel Sambuc   }
3469f4a2713aSLionel Sambuc 
3470f4a2713aSLionel Sambuc   if (Rt == 15) {
3471f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
3472f4a2713aSLionel Sambuc     case ARM::t2LDRSHi12:
3473f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3474f4a2713aSLionel Sambuc     case ARM::t2LDRHi12:
3475*0a6a1f1dSLionel Sambuc       Inst.setOpcode(ARM::t2PLDWi12);
3476*0a6a1f1dSLionel Sambuc       break;
3477*0a6a1f1dSLionel Sambuc     case ARM::t2LDRSBi12:
3478*0a6a1f1dSLionel Sambuc       Inst.setOpcode(ARM::t2PLIi12);
3479f4a2713aSLionel Sambuc       break;
3480f4a2713aSLionel Sambuc     default:
3481f4a2713aSLionel Sambuc       break;
3482f4a2713aSLionel Sambuc     }
3483f4a2713aSLionel Sambuc   }
3484f4a2713aSLionel Sambuc 
3485f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
3486f4a2713aSLionel Sambuc   case ARM::t2PLDi12:
3487*0a6a1f1dSLionel Sambuc     break;
3488f4a2713aSLionel Sambuc   case ARM::t2PLIi12:
3489*0a6a1f1dSLionel Sambuc     if (!hasV7Ops)
3490*0a6a1f1dSLionel Sambuc       return MCDisassembler::Fail;
3491*0a6a1f1dSLionel Sambuc     break;
3492*0a6a1f1dSLionel Sambuc   case ARM::t2PLDWi12:
3493*0a6a1f1dSLionel Sambuc       if (!hasV7Ops || !hasMP)
3494*0a6a1f1dSLionel Sambuc         return MCDisassembler::Fail;
3495f4a2713aSLionel Sambuc       break;
3496f4a2713aSLionel Sambuc   default:
3497f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3498f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3499f4a2713aSLionel Sambuc   }
3500f4a2713aSLionel Sambuc 
3501f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
3502f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3503f4a2713aSLionel Sambuc   return S;
3504f4a2713aSLionel Sambuc }
3505f4a2713aSLionel Sambuc 
DecodeT2LoadT(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3506f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
3507f4a2713aSLionel Sambuc                                 uint64_t Address, const void* Decoder) {
3508f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3509f4a2713aSLionel Sambuc 
3510f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3511f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3512f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 8);
3513f4a2713aSLionel Sambuc   imm |= (Rn << 9);
3514f4a2713aSLionel Sambuc 
3515f4a2713aSLionel Sambuc   if (Rn == 15) {
3516f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
3517f4a2713aSLionel Sambuc     case ARM::t2LDRT:
3518f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRpci);
3519f4a2713aSLionel Sambuc       break;
3520f4a2713aSLionel Sambuc     case ARM::t2LDRBT:
3521f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRBpci);
3522f4a2713aSLionel Sambuc       break;
3523f4a2713aSLionel Sambuc     case ARM::t2LDRHT:
3524f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRHpci);
3525f4a2713aSLionel Sambuc       break;
3526f4a2713aSLionel Sambuc     case ARM::t2LDRSBT:
3527f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRSBpci);
3528f4a2713aSLionel Sambuc       break;
3529f4a2713aSLionel Sambuc     case ARM::t2LDRSHT:
3530f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRSHpci);
3531f4a2713aSLionel Sambuc       break;
3532f4a2713aSLionel Sambuc     default:
3533f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3534f4a2713aSLionel Sambuc     }
3535f4a2713aSLionel Sambuc     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3536f4a2713aSLionel Sambuc   }
3537f4a2713aSLionel Sambuc 
3538f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3539f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3540f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3541f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3542f4a2713aSLionel Sambuc   return S;
3543f4a2713aSLionel Sambuc }
3544f4a2713aSLionel Sambuc 
DecodeT2LoadLabel(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3545f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
3546f4a2713aSLionel Sambuc                                 uint64_t Address, const void* Decoder) {
3547f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3548f4a2713aSLionel Sambuc 
3549f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3550f4a2713aSLionel Sambuc   unsigned U = fieldFromInstruction(Insn, 23, 1);
3551f4a2713aSLionel Sambuc   int imm = fieldFromInstruction(Insn, 0, 12);
3552f4a2713aSLionel Sambuc 
3553*0a6a1f1dSLionel Sambuc   uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3554*0a6a1f1dSLionel Sambuc                                                           .getFeatureBits();
3555*0a6a1f1dSLionel Sambuc   bool hasV7Ops = (featureBits & ARM::HasV7Ops);
3556*0a6a1f1dSLionel Sambuc 
3557f4a2713aSLionel Sambuc   if (Rt == 15) {
3558f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
3559f4a2713aSLionel Sambuc       case ARM::t2LDRBpci:
3560f4a2713aSLionel Sambuc       case ARM::t2LDRHpci:
3561f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::t2PLDpci);
3562f4a2713aSLionel Sambuc         break;
3563f4a2713aSLionel Sambuc       case ARM::t2LDRSBpci:
3564f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::t2PLIpci);
3565f4a2713aSLionel Sambuc         break;
3566f4a2713aSLionel Sambuc       case ARM::t2LDRSHpci:
3567f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
3568f4a2713aSLionel Sambuc       default:
3569f4a2713aSLionel Sambuc         break;
3570f4a2713aSLionel Sambuc     }
3571f4a2713aSLionel Sambuc   }
3572f4a2713aSLionel Sambuc 
3573f4a2713aSLionel Sambuc   switch(Inst.getOpcode()) {
3574f4a2713aSLionel Sambuc   case ARM::t2PLDpci:
3575*0a6a1f1dSLionel Sambuc     break;
3576f4a2713aSLionel Sambuc   case ARM::t2PLIpci:
3577*0a6a1f1dSLionel Sambuc     if (!hasV7Ops)
3578*0a6a1f1dSLionel Sambuc       return MCDisassembler::Fail;
3579f4a2713aSLionel Sambuc     break;
3580f4a2713aSLionel Sambuc   default:
3581f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3582f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3583f4a2713aSLionel Sambuc   }
3584f4a2713aSLionel Sambuc 
3585f4a2713aSLionel Sambuc   if (!U) {
3586f4a2713aSLionel Sambuc     // Special case for #-0.
3587f4a2713aSLionel Sambuc     if (imm == 0)
3588f4a2713aSLionel Sambuc       imm = INT32_MIN;
3589f4a2713aSLionel Sambuc     else
3590f4a2713aSLionel Sambuc       imm = -imm;
3591f4a2713aSLionel Sambuc   }
3592f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3593f4a2713aSLionel Sambuc 
3594f4a2713aSLionel Sambuc   return S;
3595f4a2713aSLionel Sambuc }
3596f4a2713aSLionel Sambuc 
DecodeT2Imm8S4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3597f4a2713aSLionel Sambuc static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
3598f4a2713aSLionel Sambuc                            uint64_t Address, const void *Decoder) {
3599f4a2713aSLionel Sambuc   if (Val == 0)
3600f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(INT32_MIN));
3601f4a2713aSLionel Sambuc   else {
3602f4a2713aSLionel Sambuc     int imm = Val & 0xFF;
3603f4a2713aSLionel Sambuc 
3604f4a2713aSLionel Sambuc     if (!(Val & 0x100)) imm *= -1;
3605f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imm * 4));
3606f4a2713aSLionel Sambuc   }
3607f4a2713aSLionel Sambuc 
3608f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3609f4a2713aSLionel Sambuc }
3610f4a2713aSLionel Sambuc 
DecodeT2AddrModeImm8s4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3611f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
3612f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
3613f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3614f4a2713aSLionel Sambuc 
3615f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 9, 4);
3616f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 0, 9);
3617f4a2713aSLionel Sambuc 
3618f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3619f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3620f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
3621f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3622f4a2713aSLionel Sambuc 
3623f4a2713aSLionel Sambuc   return S;
3624f4a2713aSLionel Sambuc }
3625f4a2713aSLionel Sambuc 
DecodeT2AddrModeImm0_1020s4(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3626f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
3627f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
3628f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3629f4a2713aSLionel Sambuc 
3630f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 8, 4);
3631f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 0, 8);
3632f4a2713aSLionel Sambuc 
3633f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
3634f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3635f4a2713aSLionel Sambuc 
3636f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3637f4a2713aSLionel Sambuc 
3638f4a2713aSLionel Sambuc   return S;
3639f4a2713aSLionel Sambuc }
3640f4a2713aSLionel Sambuc 
DecodeT2Imm8(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3641f4a2713aSLionel Sambuc static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
3642f4a2713aSLionel Sambuc                          uint64_t Address, const void *Decoder) {
3643f4a2713aSLionel Sambuc   int imm = Val & 0xFF;
3644f4a2713aSLionel Sambuc   if (Val == 0)
3645f4a2713aSLionel Sambuc     imm = INT32_MIN;
3646f4a2713aSLionel Sambuc   else if (!(Val & 0x100))
3647f4a2713aSLionel Sambuc     imm *= -1;
3648f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3649f4a2713aSLionel Sambuc 
3650f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3651f4a2713aSLionel Sambuc }
3652f4a2713aSLionel Sambuc 
3653f4a2713aSLionel Sambuc 
DecodeT2AddrModeImm8(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3654f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
3655f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
3656f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3657f4a2713aSLionel Sambuc 
3658f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 9, 4);
3659f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 0, 9);
3660f4a2713aSLionel Sambuc 
3661f4a2713aSLionel Sambuc   // Thumb stores cannot use PC as dest register.
3662f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
3663f4a2713aSLionel Sambuc   case ARM::t2STRT:
3664f4a2713aSLionel Sambuc   case ARM::t2STRBT:
3665f4a2713aSLionel Sambuc   case ARM::t2STRHT:
3666f4a2713aSLionel Sambuc   case ARM::t2STRi8:
3667f4a2713aSLionel Sambuc   case ARM::t2STRHi8:
3668f4a2713aSLionel Sambuc   case ARM::t2STRBi8:
3669f4a2713aSLionel Sambuc     if (Rn == 15)
3670f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3671f4a2713aSLionel Sambuc     break;
3672f4a2713aSLionel Sambuc   default:
3673f4a2713aSLionel Sambuc     break;
3674f4a2713aSLionel Sambuc   }
3675f4a2713aSLionel Sambuc 
3676f4a2713aSLionel Sambuc   // Some instructions always use an additive offset.
3677f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
3678f4a2713aSLionel Sambuc     case ARM::t2LDRT:
3679f4a2713aSLionel Sambuc     case ARM::t2LDRBT:
3680f4a2713aSLionel Sambuc     case ARM::t2LDRHT:
3681f4a2713aSLionel Sambuc     case ARM::t2LDRSBT:
3682f4a2713aSLionel Sambuc     case ARM::t2LDRSHT:
3683f4a2713aSLionel Sambuc     case ARM::t2STRT:
3684f4a2713aSLionel Sambuc     case ARM::t2STRBT:
3685f4a2713aSLionel Sambuc     case ARM::t2STRHT:
3686f4a2713aSLionel Sambuc       imm |= 0x100;
3687f4a2713aSLionel Sambuc       break;
3688f4a2713aSLionel Sambuc     default:
3689f4a2713aSLionel Sambuc       break;
3690f4a2713aSLionel Sambuc   }
3691f4a2713aSLionel Sambuc 
3692f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3693f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3694f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
3695f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3696f4a2713aSLionel Sambuc 
3697f4a2713aSLionel Sambuc   return S;
3698f4a2713aSLionel Sambuc }
3699f4a2713aSLionel Sambuc 
DecodeT2LdStPre(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3700f4a2713aSLionel Sambuc static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
3701f4a2713aSLionel Sambuc                                     uint64_t Address, const void *Decoder) {
3702f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3703f4a2713aSLionel Sambuc 
3704f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3705f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3706f4a2713aSLionel Sambuc   unsigned addr = fieldFromInstruction(Insn, 0, 8);
3707f4a2713aSLionel Sambuc   addr |= fieldFromInstruction(Insn, 9, 1) << 8;
3708f4a2713aSLionel Sambuc   addr |= Rn << 9;
3709f4a2713aSLionel Sambuc   unsigned load = fieldFromInstruction(Insn, 20, 1);
3710f4a2713aSLionel Sambuc 
3711f4a2713aSLionel Sambuc   if (Rn == 15) {
3712f4a2713aSLionel Sambuc     switch (Inst.getOpcode()) {
3713f4a2713aSLionel Sambuc     case ARM::t2LDR_PRE:
3714f4a2713aSLionel Sambuc     case ARM::t2LDR_POST:
3715f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRpci);
3716f4a2713aSLionel Sambuc       break;
3717f4a2713aSLionel Sambuc     case ARM::t2LDRB_PRE:
3718f4a2713aSLionel Sambuc     case ARM::t2LDRB_POST:
3719f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRBpci);
3720f4a2713aSLionel Sambuc       break;
3721f4a2713aSLionel Sambuc     case ARM::t2LDRH_PRE:
3722f4a2713aSLionel Sambuc     case ARM::t2LDRH_POST:
3723f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRHpci);
3724f4a2713aSLionel Sambuc       break;
3725f4a2713aSLionel Sambuc     case ARM::t2LDRSB_PRE:
3726f4a2713aSLionel Sambuc     case ARM::t2LDRSB_POST:
3727f4a2713aSLionel Sambuc       if (Rt == 15)
3728f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::t2PLIpci);
3729f4a2713aSLionel Sambuc       else
3730f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::t2LDRSBpci);
3731f4a2713aSLionel Sambuc       break;
3732f4a2713aSLionel Sambuc     case ARM::t2LDRSH_PRE:
3733f4a2713aSLionel Sambuc     case ARM::t2LDRSH_POST:
3734f4a2713aSLionel Sambuc       Inst.setOpcode(ARM::t2LDRSHpci);
3735f4a2713aSLionel Sambuc       break;
3736f4a2713aSLionel Sambuc     default:
3737f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3738f4a2713aSLionel Sambuc     }
3739f4a2713aSLionel Sambuc     return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3740f4a2713aSLionel Sambuc   }
3741f4a2713aSLionel Sambuc 
3742f4a2713aSLionel Sambuc   if (!load) {
3743f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3744f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3745f4a2713aSLionel Sambuc   }
3746f4a2713aSLionel Sambuc 
3747f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3748f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3749f4a2713aSLionel Sambuc 
3750f4a2713aSLionel Sambuc   if (load) {
3751f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3752f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3753f4a2713aSLionel Sambuc   }
3754f4a2713aSLionel Sambuc 
3755f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
3756f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3757f4a2713aSLionel Sambuc 
3758f4a2713aSLionel Sambuc   return S;
3759f4a2713aSLionel Sambuc }
3760f4a2713aSLionel Sambuc 
DecodeT2AddrModeImm12(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3761f4a2713aSLionel Sambuc static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
3762f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
3763f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3764f4a2713aSLionel Sambuc 
3765f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 13, 4);
3766f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Val, 0, 12);
3767f4a2713aSLionel Sambuc 
3768f4a2713aSLionel Sambuc   // Thumb stores cannot use PC as dest register.
3769f4a2713aSLionel Sambuc   switch (Inst.getOpcode()) {
3770f4a2713aSLionel Sambuc   case ARM::t2STRi12:
3771f4a2713aSLionel Sambuc   case ARM::t2STRBi12:
3772f4a2713aSLionel Sambuc   case ARM::t2STRHi12:
3773f4a2713aSLionel Sambuc     if (Rn == 15)
3774f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
3775f4a2713aSLionel Sambuc   default:
3776f4a2713aSLionel Sambuc     break;
3777f4a2713aSLionel Sambuc   }
3778f4a2713aSLionel Sambuc 
3779f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3780f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3781f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3782f4a2713aSLionel Sambuc 
3783f4a2713aSLionel Sambuc   return S;
3784f4a2713aSLionel Sambuc }
3785f4a2713aSLionel Sambuc 
3786f4a2713aSLionel Sambuc 
DecodeThumbAddSPImm(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)3787f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
3788f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder) {
3789f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 7);
3790f4a2713aSLionel Sambuc 
3791f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3792f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3793f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imm));
3794f4a2713aSLionel Sambuc 
3795f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3796f4a2713aSLionel Sambuc }
3797f4a2713aSLionel Sambuc 
DecodeThumbAddSPReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)3798f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
3799f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder) {
3800f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3801f4a2713aSLionel Sambuc 
3802f4a2713aSLionel Sambuc   if (Inst.getOpcode() == ARM::tADDrSP) {
3803f4a2713aSLionel Sambuc     unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
3804f4a2713aSLionel Sambuc     Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
3805f4a2713aSLionel Sambuc 
3806f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3807f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3808f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3809f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3810f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3811f4a2713aSLionel Sambuc   } else if (Inst.getOpcode() == ARM::tADDspr) {
3812f4a2713aSLionel Sambuc     unsigned Rm = fieldFromInstruction(Insn, 3, 4);
3813f4a2713aSLionel Sambuc 
3814f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3815f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3816f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3817f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3818f4a2713aSLionel Sambuc   }
3819f4a2713aSLionel Sambuc 
3820f4a2713aSLionel Sambuc   return S;
3821f4a2713aSLionel Sambuc }
3822f4a2713aSLionel Sambuc 
DecodeThumbCPS(MCInst & Inst,uint16_t Insn,uint64_t Address,const void * Decoder)3823f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
3824f4a2713aSLionel Sambuc                            uint64_t Address, const void *Decoder) {
3825f4a2713aSLionel Sambuc   unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
3826f4a2713aSLionel Sambuc   unsigned flags = fieldFromInstruction(Insn, 0, 3);
3827f4a2713aSLionel Sambuc 
3828f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(imod));
3829f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(flags));
3830f4a2713aSLionel Sambuc 
3831f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3832f4a2713aSLionel Sambuc }
3833f4a2713aSLionel Sambuc 
DecodePostIdxReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3834f4a2713aSLionel Sambuc static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
3835f4a2713aSLionel Sambuc                              uint64_t Address, const void *Decoder) {
3836f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3837f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3838f4a2713aSLionel Sambuc   unsigned add = fieldFromInstruction(Insn, 4, 1);
3839f4a2713aSLionel Sambuc 
3840f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
3841f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3842f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(add));
3843f4a2713aSLionel Sambuc 
3844f4a2713aSLionel Sambuc   return S;
3845f4a2713aSLionel Sambuc }
3846f4a2713aSLionel Sambuc 
DecodeThumbBLXOffset(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3847f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
3848f4a2713aSLionel Sambuc                                  uint64_t Address, const void *Decoder) {
3849f4a2713aSLionel Sambuc   // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
3850f4a2713aSLionel Sambuc   // Note only one trailing zero not two.  Also the J1 and J2 values are from
3851f4a2713aSLionel Sambuc   // the encoded instruction.  So here change to I1 and I2 values via:
3852f4a2713aSLionel Sambuc   // I1 = NOT(J1 EOR S);
3853f4a2713aSLionel Sambuc   // I2 = NOT(J2 EOR S);
3854f4a2713aSLionel Sambuc   // and build the imm32 with two trailing zeros as documented:
3855f4a2713aSLionel Sambuc   // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
3856f4a2713aSLionel Sambuc   unsigned S = (Val >> 23) & 1;
3857f4a2713aSLionel Sambuc   unsigned J1 = (Val >> 22) & 1;
3858f4a2713aSLionel Sambuc   unsigned J2 = (Val >> 21) & 1;
3859f4a2713aSLionel Sambuc   unsigned I1 = !(J1 ^ S);
3860f4a2713aSLionel Sambuc   unsigned I2 = !(J2 ^ S);
3861f4a2713aSLionel Sambuc   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
3862f4a2713aSLionel Sambuc   int imm32 = SignExtend32<25>(tmp << 1);
3863f4a2713aSLionel Sambuc 
3864f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address,
3865f4a2713aSLionel Sambuc                                 (Address & ~2u) + imm32 + 4,
3866f4a2713aSLionel Sambuc                                 true, 4, Inst, Decoder))
3867f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imm32));
3868f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3869f4a2713aSLionel Sambuc }
3870f4a2713aSLionel Sambuc 
DecodeCoprocessor(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3871f4a2713aSLionel Sambuc static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
3872f4a2713aSLionel Sambuc                               uint64_t Address, const void *Decoder) {
3873f4a2713aSLionel Sambuc   if (Val == 0xA || Val == 0xB)
3874f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3875f4a2713aSLionel Sambuc 
3876f4a2713aSLionel Sambuc   uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3877f4a2713aSLionel Sambuc                                                           .getFeatureBits();
3878f4a2713aSLionel Sambuc   if ((featureBits & ARM::HasV8Ops) && !(Val == 14 || Val == 15))
3879f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3880f4a2713aSLionel Sambuc 
3881f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Val));
3882f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3883f4a2713aSLionel Sambuc }
3884f4a2713aSLionel Sambuc 
3885f4a2713aSLionel Sambuc static DecodeStatus
DecodeThumbTableBranch(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3886f4a2713aSLionel Sambuc DecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
3887f4a2713aSLionel Sambuc                        uint64_t Address, const void *Decoder) {
3888f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3889f4a2713aSLionel Sambuc 
3890f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3891f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3892f4a2713aSLionel Sambuc 
3893f4a2713aSLionel Sambuc   if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
3894f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3895f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3896f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3897f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3898f4a2713aSLionel Sambuc   return S;
3899f4a2713aSLionel Sambuc }
3900f4a2713aSLionel Sambuc 
3901f4a2713aSLionel Sambuc static DecodeStatus
DecodeThumb2BCCInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)3902f4a2713aSLionel Sambuc DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
3903f4a2713aSLionel Sambuc                            uint64_t Address, const void *Decoder) {
3904f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
3905f4a2713aSLionel Sambuc 
3906f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 22, 4);
3907f4a2713aSLionel Sambuc   if (pred == 0xE || pred == 0xF) {
3908f4a2713aSLionel Sambuc     unsigned opc = fieldFromInstruction(Insn, 4, 28);
3909f4a2713aSLionel Sambuc     switch (opc) {
3910f4a2713aSLionel Sambuc       default:
3911f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
3912f4a2713aSLionel Sambuc       case 0xf3bf8f4:
3913f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::t2DSB);
3914f4a2713aSLionel Sambuc         break;
3915f4a2713aSLionel Sambuc       case 0xf3bf8f5:
3916f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::t2DMB);
3917f4a2713aSLionel Sambuc         break;
3918f4a2713aSLionel Sambuc       case 0xf3bf8f6:
3919f4a2713aSLionel Sambuc         Inst.setOpcode(ARM::t2ISB);
3920f4a2713aSLionel Sambuc         break;
3921f4a2713aSLionel Sambuc     }
3922f4a2713aSLionel Sambuc 
3923f4a2713aSLionel Sambuc     unsigned imm = fieldFromInstruction(Insn, 0, 4);
3924f4a2713aSLionel Sambuc     return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
3925f4a2713aSLionel Sambuc   }
3926f4a2713aSLionel Sambuc 
3927f4a2713aSLionel Sambuc   unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
3928f4a2713aSLionel Sambuc   brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
3929f4a2713aSLionel Sambuc   brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
3930f4a2713aSLionel Sambuc   brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
3931f4a2713aSLionel Sambuc   brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
3932f4a2713aSLionel Sambuc 
3933f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
3934f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3935f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3936f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
3937f4a2713aSLionel Sambuc 
3938f4a2713aSLionel Sambuc   return S;
3939f4a2713aSLionel Sambuc }
3940f4a2713aSLionel Sambuc 
3941f4a2713aSLionel Sambuc // Decode a shifted immediate operand.  These basically consist
3942f4a2713aSLionel Sambuc // of an 8-bit value, and a 4-bit directive that specifies either
3943f4a2713aSLionel Sambuc // a splat operation or a rotation.
DecodeT2SOImm(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3944f4a2713aSLionel Sambuc static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
3945f4a2713aSLionel Sambuc                           uint64_t Address, const void *Decoder) {
3946f4a2713aSLionel Sambuc   unsigned ctrl = fieldFromInstruction(Val, 10, 2);
3947f4a2713aSLionel Sambuc   if (ctrl == 0) {
3948f4a2713aSLionel Sambuc     unsigned byte = fieldFromInstruction(Val, 8, 2);
3949f4a2713aSLionel Sambuc     unsigned imm = fieldFromInstruction(Val, 0, 8);
3950f4a2713aSLionel Sambuc     switch (byte) {
3951f4a2713aSLionel Sambuc       case 0:
3952f4a2713aSLionel Sambuc         Inst.addOperand(MCOperand::CreateImm(imm));
3953f4a2713aSLionel Sambuc         break;
3954f4a2713aSLionel Sambuc       case 1:
3955f4a2713aSLionel Sambuc         Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm));
3956f4a2713aSLionel Sambuc         break;
3957f4a2713aSLionel Sambuc       case 2:
3958f4a2713aSLionel Sambuc         Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8)));
3959f4a2713aSLionel Sambuc         break;
3960f4a2713aSLionel Sambuc       case 3:
3961f4a2713aSLionel Sambuc         Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) |
3962f4a2713aSLionel Sambuc                                              (imm << 8)  |  imm));
3963f4a2713aSLionel Sambuc         break;
3964f4a2713aSLionel Sambuc     }
3965f4a2713aSLionel Sambuc   } else {
3966f4a2713aSLionel Sambuc     unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
3967f4a2713aSLionel Sambuc     unsigned rot = fieldFromInstruction(Val, 7, 5);
3968f4a2713aSLionel Sambuc     unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
3969f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imm));
3970f4a2713aSLionel Sambuc   }
3971f4a2713aSLionel Sambuc 
3972f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3973f4a2713aSLionel Sambuc }
3974f4a2713aSLionel Sambuc 
3975f4a2713aSLionel Sambuc static DecodeStatus
DecodeThumbBCCTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3976f4a2713aSLionel Sambuc DecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
3977f4a2713aSLionel Sambuc                             uint64_t Address, const void *Decoder){
3978f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
3979f4a2713aSLionel Sambuc                                 true, 2, Inst, Decoder))
3980f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(SignExtend32<9>(Val << 1)));
3981f4a2713aSLionel Sambuc   return MCDisassembler::Success;
3982f4a2713aSLionel Sambuc }
3983f4a2713aSLionel Sambuc 
DecodeThumbBLTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)3984f4a2713aSLionel Sambuc static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
3985f4a2713aSLionel Sambuc                                        uint64_t Address, const void *Decoder){
3986f4a2713aSLionel Sambuc   // Val is passed in as S:J1:J2:imm10:imm11
3987f4a2713aSLionel Sambuc   // Note no trailing zero after imm11.  Also the J1 and J2 values are from
3988f4a2713aSLionel Sambuc   // the encoded instruction.  So here change to I1 and I2 values via:
3989f4a2713aSLionel Sambuc   // I1 = NOT(J1 EOR S);
3990f4a2713aSLionel Sambuc   // I2 = NOT(J2 EOR S);
3991f4a2713aSLionel Sambuc   // and build the imm32 with one trailing zero as documented:
3992f4a2713aSLionel Sambuc   // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
3993f4a2713aSLionel Sambuc   unsigned S = (Val >> 23) & 1;
3994f4a2713aSLionel Sambuc   unsigned J1 = (Val >> 22) & 1;
3995f4a2713aSLionel Sambuc   unsigned J2 = (Val >> 21) & 1;
3996f4a2713aSLionel Sambuc   unsigned I1 = !(J1 ^ S);
3997f4a2713aSLionel Sambuc   unsigned I2 = !(J2 ^ S);
3998f4a2713aSLionel Sambuc   unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
3999f4a2713aSLionel Sambuc   int imm32 = SignExtend32<25>(tmp << 1);
4000f4a2713aSLionel Sambuc 
4001f4a2713aSLionel Sambuc   if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
4002f4a2713aSLionel Sambuc                                 true, 4, Inst, Decoder))
4003f4a2713aSLionel Sambuc     Inst.addOperand(MCOperand::CreateImm(imm32));
4004f4a2713aSLionel Sambuc   return MCDisassembler::Success;
4005f4a2713aSLionel Sambuc }
4006f4a2713aSLionel Sambuc 
DecodeMemBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4007f4a2713aSLionel Sambuc static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
4008f4a2713aSLionel Sambuc                                    uint64_t Address, const void *Decoder) {
4009f4a2713aSLionel Sambuc   if (Val & ~0xf)
4010f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4011f4a2713aSLionel Sambuc 
4012f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Val));
4013f4a2713aSLionel Sambuc   return MCDisassembler::Success;
4014f4a2713aSLionel Sambuc }
4015f4a2713aSLionel Sambuc 
DecodeInstSyncBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4016f4a2713aSLionel Sambuc static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
4017f4a2713aSLionel Sambuc                                         uint64_t Address, const void *Decoder) {
4018f4a2713aSLionel Sambuc   if (Val & ~0xf)
4019f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4020f4a2713aSLionel Sambuc 
4021f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Val));
4022f4a2713aSLionel Sambuc   return MCDisassembler::Success;
4023f4a2713aSLionel Sambuc }
4024f4a2713aSLionel Sambuc 
DecodeMSRMask(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4025f4a2713aSLionel Sambuc static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
4026f4a2713aSLionel Sambuc                           uint64_t Address, const void *Decoder) {
4027*0a6a1f1dSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4028*0a6a1f1dSLionel Sambuc   uint64_t FeatureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
4029*0a6a1f1dSLionel Sambuc                                                           .getFeatureBits();
4030*0a6a1f1dSLionel Sambuc   if (FeatureBits & ARM::FeatureMClass) {
4031*0a6a1f1dSLionel Sambuc     unsigned ValLow = Val & 0xff;
4032*0a6a1f1dSLionel Sambuc 
4033*0a6a1f1dSLionel Sambuc     // Validate the SYSm value first.
4034*0a6a1f1dSLionel Sambuc     switch (ValLow) {
4035*0a6a1f1dSLionel Sambuc     case  0: // apsr
4036*0a6a1f1dSLionel Sambuc     case  1: // iapsr
4037*0a6a1f1dSLionel Sambuc     case  2: // eapsr
4038*0a6a1f1dSLionel Sambuc     case  3: // xpsr
4039*0a6a1f1dSLionel Sambuc     case  5: // ipsr
4040*0a6a1f1dSLionel Sambuc     case  6: // epsr
4041*0a6a1f1dSLionel Sambuc     case  7: // iepsr
4042*0a6a1f1dSLionel Sambuc     case  8: // msp
4043*0a6a1f1dSLionel Sambuc     case  9: // psp
4044*0a6a1f1dSLionel Sambuc     case 16: // primask
4045*0a6a1f1dSLionel Sambuc     case 20: // control
4046*0a6a1f1dSLionel Sambuc       break;
4047*0a6a1f1dSLionel Sambuc     case 17: // basepri
4048*0a6a1f1dSLionel Sambuc     case 18: // basepri_max
4049*0a6a1f1dSLionel Sambuc     case 19: // faultmask
4050*0a6a1f1dSLionel Sambuc       if (!(FeatureBits & ARM::HasV7Ops))
4051*0a6a1f1dSLionel Sambuc         // Values basepri, basepri_max and faultmask are only valid for v7m.
4052*0a6a1f1dSLionel Sambuc         return MCDisassembler::Fail;
4053*0a6a1f1dSLionel Sambuc       break;
4054*0a6a1f1dSLionel Sambuc     default:
4055*0a6a1f1dSLionel Sambuc       return MCDisassembler::Fail;
4056*0a6a1f1dSLionel Sambuc     }
4057*0a6a1f1dSLionel Sambuc 
4058*0a6a1f1dSLionel Sambuc     if (Inst.getOpcode() == ARM::t2MSR_M) {
4059*0a6a1f1dSLionel Sambuc       unsigned Mask = fieldFromInstruction(Val, 10, 2);
4060*0a6a1f1dSLionel Sambuc       if (!(FeatureBits & ARM::HasV7Ops)) {
4061*0a6a1f1dSLionel Sambuc         // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
4062*0a6a1f1dSLionel Sambuc         // unpredictable.
4063*0a6a1f1dSLionel Sambuc         if (Mask != 2)
4064*0a6a1f1dSLionel Sambuc           S = MCDisassembler::SoftFail;
4065*0a6a1f1dSLionel Sambuc       }
4066*0a6a1f1dSLionel Sambuc       else {
4067*0a6a1f1dSLionel Sambuc         // The ARMv7-M architecture stores an additional 2-bit mask value in
4068*0a6a1f1dSLionel Sambuc         // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
4069*0a6a1f1dSLionel Sambuc         // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
4070*0a6a1f1dSLionel Sambuc         // the NZCVQ bits should be moved by the instruction. Bit mask{0}
4071*0a6a1f1dSLionel Sambuc         // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
4072*0a6a1f1dSLionel Sambuc         // only if the processor includes the DSP extension.
4073*0a6a1f1dSLionel Sambuc         if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
4074*0a6a1f1dSLionel Sambuc             (!(FeatureBits & ARM::FeatureDSPThumb2) && (Mask & 1)))
4075*0a6a1f1dSLionel Sambuc           S = MCDisassembler::SoftFail;
4076*0a6a1f1dSLionel Sambuc       }
4077*0a6a1f1dSLionel Sambuc     }
4078*0a6a1f1dSLionel Sambuc   } else {
4079*0a6a1f1dSLionel Sambuc     // A/R class
4080*0a6a1f1dSLionel Sambuc     if (Val == 0)
4081*0a6a1f1dSLionel Sambuc       return MCDisassembler::Fail;
4082*0a6a1f1dSLionel Sambuc   }
4083*0a6a1f1dSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Val));
4084*0a6a1f1dSLionel Sambuc   return S;
4085*0a6a1f1dSLionel Sambuc }
4086*0a6a1f1dSLionel Sambuc 
DecodeBankedReg(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)4087*0a6a1f1dSLionel Sambuc static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
4088*0a6a1f1dSLionel Sambuc                                     uint64_t Address, const void *Decoder) {
4089*0a6a1f1dSLionel Sambuc 
4090*0a6a1f1dSLionel Sambuc   unsigned R = fieldFromInstruction(Val, 5, 1);
4091*0a6a1f1dSLionel Sambuc   unsigned SysM = fieldFromInstruction(Val, 0, 5);
4092*0a6a1f1dSLionel Sambuc 
4093*0a6a1f1dSLionel Sambuc   // The table of encodings for these banked registers comes from B9.2.3 of the
4094*0a6a1f1dSLionel Sambuc   // ARM ARM. There are patterns, but nothing regular enough to make this logic
4095*0a6a1f1dSLionel Sambuc   // neater. So by fiat, these values are UNPREDICTABLE:
4096*0a6a1f1dSLionel Sambuc   if (!R) {
4097*0a6a1f1dSLionel Sambuc     if (SysM == 0x7 || SysM == 0xf || SysM == 0x18 || SysM == 0x19 ||
4098*0a6a1f1dSLionel Sambuc         SysM == 0x1a || SysM == 0x1b)
4099*0a6a1f1dSLionel Sambuc       return MCDisassembler::SoftFail;
4100*0a6a1f1dSLionel Sambuc   } else {
4101*0a6a1f1dSLionel Sambuc     if (SysM != 0xe && SysM != 0x10 && SysM != 0x12 && SysM != 0x14 &&
4102*0a6a1f1dSLionel Sambuc         SysM != 0x16 && SysM != 0x1c && SysM != 0x1e)
4103*0a6a1f1dSLionel Sambuc       return MCDisassembler::SoftFail;
4104*0a6a1f1dSLionel Sambuc   }
4105*0a6a1f1dSLionel Sambuc 
4106f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Val));
4107f4a2713aSLionel Sambuc   return MCDisassembler::Success;
4108f4a2713aSLionel Sambuc }
4109f4a2713aSLionel Sambuc 
DecodeDoubleRegLoad(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4110f4a2713aSLionel Sambuc static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
4111f4a2713aSLionel Sambuc                                         uint64_t Address, const void *Decoder) {
4112f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4113f4a2713aSLionel Sambuc 
4114f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4115f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4116f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
4117f4a2713aSLionel Sambuc 
4118f4a2713aSLionel Sambuc   if (Rn == 0xF)
4119f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
4120f4a2713aSLionel Sambuc 
4121f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
4122f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4123f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4124f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4125f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4126f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4127f4a2713aSLionel Sambuc 
4128f4a2713aSLionel Sambuc   return S;
4129f4a2713aSLionel Sambuc }
4130f4a2713aSLionel Sambuc 
DecodeDoubleRegStore(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4131f4a2713aSLionel Sambuc static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
4132f4a2713aSLionel Sambuc                                          uint64_t Address, const void *Decoder){
4133f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4134f4a2713aSLionel Sambuc 
4135f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4136f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 0, 4);
4137f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4138f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
4139f4a2713aSLionel Sambuc 
4140f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
4141f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4142f4a2713aSLionel Sambuc 
4143f4a2713aSLionel Sambuc   if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
4144f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
4145f4a2713aSLionel Sambuc 
4146f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
4147f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4148f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4149f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4150f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4151f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4152f4a2713aSLionel Sambuc 
4153f4a2713aSLionel Sambuc   return S;
4154f4a2713aSLionel Sambuc }
4155f4a2713aSLionel Sambuc 
DecodeLDRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4156f4a2713aSLionel Sambuc static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
4157f4a2713aSLionel Sambuc                             uint64_t Address, const void *Decoder) {
4158f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4159f4a2713aSLionel Sambuc 
4160f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4161f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4162f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 12);
4163f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4164f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4165f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
4166f4a2713aSLionel Sambuc 
4167f4a2713aSLionel Sambuc   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4168f4a2713aSLionel Sambuc 
4169f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4170f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4171f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4172f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4173f4a2713aSLionel Sambuc   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4174f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4175f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4176f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4177f4a2713aSLionel Sambuc 
4178f4a2713aSLionel Sambuc   return S;
4179f4a2713aSLionel Sambuc }
4180f4a2713aSLionel Sambuc 
DecodeLDRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4181f4a2713aSLionel Sambuc static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
4182f4a2713aSLionel Sambuc                             uint64_t Address, const void *Decoder) {
4183f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4184f4a2713aSLionel Sambuc 
4185f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4186f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4187f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 12);
4188f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4189f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4190f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
4191f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4192f4a2713aSLionel Sambuc 
4193f4a2713aSLionel Sambuc   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4194f4a2713aSLionel Sambuc   if (Rm == 0xF) S = MCDisassembler::SoftFail;
4195f4a2713aSLionel Sambuc 
4196f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4197f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4198f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4199f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4200f4a2713aSLionel Sambuc   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4201f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4202f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4203f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4204f4a2713aSLionel Sambuc 
4205f4a2713aSLionel Sambuc   return S;
4206f4a2713aSLionel Sambuc }
4207f4a2713aSLionel Sambuc 
4208f4a2713aSLionel Sambuc 
DecodeSTRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4209f4a2713aSLionel Sambuc static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
4210f4a2713aSLionel Sambuc                             uint64_t Address, const void *Decoder) {
4211f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4212f4a2713aSLionel Sambuc 
4213f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4214f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4215f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 12);
4216f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4217f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4218f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
4219f4a2713aSLionel Sambuc 
4220f4a2713aSLionel Sambuc   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4221f4a2713aSLionel Sambuc 
4222f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4223f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4224f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4225f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4226f4a2713aSLionel Sambuc   if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4227f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4228f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4229f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4230f4a2713aSLionel Sambuc 
4231f4a2713aSLionel Sambuc   return S;
4232f4a2713aSLionel Sambuc }
4233f4a2713aSLionel Sambuc 
DecodeSTRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4234f4a2713aSLionel Sambuc static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
4235f4a2713aSLionel Sambuc                             uint64_t Address, const void *Decoder) {
4236f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4237f4a2713aSLionel Sambuc 
4238f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4239f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4240f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 0, 12);
4241f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4242f4a2713aSLionel Sambuc   imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4243f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
4244f4a2713aSLionel Sambuc 
4245f4a2713aSLionel Sambuc   if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4246f4a2713aSLionel Sambuc 
4247f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4248f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4249f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4250f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4251f4a2713aSLionel Sambuc   if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4252f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4253f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4254f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4255f4a2713aSLionel Sambuc 
4256f4a2713aSLionel Sambuc   return S;
4257f4a2713aSLionel Sambuc }
4258f4a2713aSLionel Sambuc 
DecodeVLD1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4259f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
4260f4a2713aSLionel Sambuc                          uint64_t Address, const void *Decoder) {
4261f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4262f4a2713aSLionel Sambuc 
4263f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4264f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4265f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4266f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4267f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 10, 2);
4268f4a2713aSLionel Sambuc 
4269f4a2713aSLionel Sambuc   unsigned align = 0;
4270f4a2713aSLionel Sambuc   unsigned index = 0;
4271f4a2713aSLionel Sambuc   switch (size) {
4272f4a2713aSLionel Sambuc     default:
4273f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4274f4a2713aSLionel Sambuc     case 0:
4275f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4276f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4277f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 5, 3);
4278f4a2713aSLionel Sambuc       break;
4279f4a2713aSLionel Sambuc     case 1:
4280f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4281f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4282f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 6, 2);
4283f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4284f4a2713aSLionel Sambuc         align = 2;
4285f4a2713aSLionel Sambuc       break;
4286f4a2713aSLionel Sambuc     case 2:
4287f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 6, 1))
4288f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4289f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 7, 1);
4290f4a2713aSLionel Sambuc 
4291f4a2713aSLionel Sambuc       switch (fieldFromInstruction(Insn, 4, 2)) {
4292f4a2713aSLionel Sambuc         case 0 :
4293f4a2713aSLionel Sambuc           align = 0; break;
4294f4a2713aSLionel Sambuc         case 3:
4295f4a2713aSLionel Sambuc           align = 4; break;
4296f4a2713aSLionel Sambuc         default:
4297f4a2713aSLionel Sambuc           return MCDisassembler::Fail;
4298f4a2713aSLionel Sambuc       }
4299f4a2713aSLionel Sambuc       break;
4300f4a2713aSLionel Sambuc   }
4301f4a2713aSLionel Sambuc 
4302f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4303f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4304f4a2713aSLionel Sambuc   if (Rm != 0xF) { // Writeback
4305f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4306f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4307f4a2713aSLionel Sambuc   }
4308f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4309f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4310f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
4311f4a2713aSLionel Sambuc   if (Rm != 0xF) {
4312f4a2713aSLionel Sambuc     if (Rm != 0xD) {
4313f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4314f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
4315f4a2713aSLionel Sambuc     } else
4316f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(0));
4317f4a2713aSLionel Sambuc   }
4318f4a2713aSLionel Sambuc 
4319f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4320f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4321f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(index));
4322f4a2713aSLionel Sambuc 
4323f4a2713aSLionel Sambuc   return S;
4324f4a2713aSLionel Sambuc }
4325f4a2713aSLionel Sambuc 
DecodeVST1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4326f4a2713aSLionel Sambuc static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
4327f4a2713aSLionel Sambuc                          uint64_t Address, const void *Decoder) {
4328f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4329f4a2713aSLionel Sambuc 
4330f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4331f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4332f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4333f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4334f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 10, 2);
4335f4a2713aSLionel Sambuc 
4336f4a2713aSLionel Sambuc   unsigned align = 0;
4337f4a2713aSLionel Sambuc   unsigned index = 0;
4338f4a2713aSLionel Sambuc   switch (size) {
4339f4a2713aSLionel Sambuc     default:
4340f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4341f4a2713aSLionel Sambuc     case 0:
4342f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4343f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4344f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 5, 3);
4345f4a2713aSLionel Sambuc       break;
4346f4a2713aSLionel Sambuc     case 1:
4347f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4348f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4349f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 6, 2);
4350f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4351f4a2713aSLionel Sambuc         align = 2;
4352f4a2713aSLionel Sambuc       break;
4353f4a2713aSLionel Sambuc     case 2:
4354f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 6, 1))
4355f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4356f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 7, 1);
4357f4a2713aSLionel Sambuc 
4358f4a2713aSLionel Sambuc       switch (fieldFromInstruction(Insn, 4, 2)) {
4359f4a2713aSLionel Sambuc         case 0:
4360f4a2713aSLionel Sambuc           align = 0; break;
4361f4a2713aSLionel Sambuc         case 3:
4362f4a2713aSLionel Sambuc           align = 4; break;
4363f4a2713aSLionel Sambuc         default:
4364f4a2713aSLionel Sambuc           return MCDisassembler::Fail;
4365f4a2713aSLionel Sambuc       }
4366f4a2713aSLionel Sambuc       break;
4367f4a2713aSLionel Sambuc   }
4368f4a2713aSLionel Sambuc 
4369f4a2713aSLionel Sambuc   if (Rm != 0xF) { // Writeback
4370f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4371f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4372f4a2713aSLionel Sambuc   }
4373f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4374f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4375f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
4376f4a2713aSLionel Sambuc   if (Rm != 0xF) {
4377f4a2713aSLionel Sambuc     if (Rm != 0xD) {
4378f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4379f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4380f4a2713aSLionel Sambuc     } else
4381f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(0));
4382f4a2713aSLionel Sambuc   }
4383f4a2713aSLionel Sambuc 
4384f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4385f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4386f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(index));
4387f4a2713aSLionel Sambuc 
4388f4a2713aSLionel Sambuc   return S;
4389f4a2713aSLionel Sambuc }
4390f4a2713aSLionel Sambuc 
4391f4a2713aSLionel Sambuc 
DecodeVLD2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4392f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
4393f4a2713aSLionel Sambuc                          uint64_t Address, const void *Decoder) {
4394f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4395f4a2713aSLionel Sambuc 
4396f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4397f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4398f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4399f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4400f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 10, 2);
4401f4a2713aSLionel Sambuc 
4402f4a2713aSLionel Sambuc   unsigned align = 0;
4403f4a2713aSLionel Sambuc   unsigned index = 0;
4404f4a2713aSLionel Sambuc   unsigned inc = 1;
4405f4a2713aSLionel Sambuc   switch (size) {
4406f4a2713aSLionel Sambuc     default:
4407f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4408f4a2713aSLionel Sambuc     case 0:
4409f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 5, 3);
4410f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4411f4a2713aSLionel Sambuc         align = 2;
4412f4a2713aSLionel Sambuc       break;
4413f4a2713aSLionel Sambuc     case 1:
4414f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 6, 2);
4415f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4416f4a2713aSLionel Sambuc         align = 4;
4417f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4418f4a2713aSLionel Sambuc         inc = 2;
4419f4a2713aSLionel Sambuc       break;
4420f4a2713aSLionel Sambuc     case 2:
4421f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4422f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4423f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 7, 1);
4424f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1) != 0)
4425f4a2713aSLionel Sambuc         align = 8;
4426f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 6, 1))
4427f4a2713aSLionel Sambuc         inc = 2;
4428f4a2713aSLionel Sambuc       break;
4429f4a2713aSLionel Sambuc   }
4430f4a2713aSLionel Sambuc 
4431f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4432f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4433f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4434f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4435f4a2713aSLionel Sambuc   if (Rm != 0xF) { // Writeback
4436f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4437f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4438f4a2713aSLionel Sambuc   }
4439f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4440f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4441f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
4442f4a2713aSLionel Sambuc   if (Rm != 0xF) {
4443f4a2713aSLionel Sambuc     if (Rm != 0xD) {
4444f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4445f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
4446f4a2713aSLionel Sambuc     } else
4447f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(0));
4448f4a2713aSLionel Sambuc   }
4449f4a2713aSLionel Sambuc 
4450f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4451f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4452f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4453f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4454f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(index));
4455f4a2713aSLionel Sambuc 
4456f4a2713aSLionel Sambuc   return S;
4457f4a2713aSLionel Sambuc }
4458f4a2713aSLionel Sambuc 
DecodeVST2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4459f4a2713aSLionel Sambuc static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
4460f4a2713aSLionel Sambuc                          uint64_t Address, const void *Decoder) {
4461f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4462f4a2713aSLionel Sambuc 
4463f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4464f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4465f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4466f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4467f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 10, 2);
4468f4a2713aSLionel Sambuc 
4469f4a2713aSLionel Sambuc   unsigned align = 0;
4470f4a2713aSLionel Sambuc   unsigned index = 0;
4471f4a2713aSLionel Sambuc   unsigned inc = 1;
4472f4a2713aSLionel Sambuc   switch (size) {
4473f4a2713aSLionel Sambuc     default:
4474f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4475f4a2713aSLionel Sambuc     case 0:
4476f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 5, 3);
4477f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4478f4a2713aSLionel Sambuc         align = 2;
4479f4a2713aSLionel Sambuc       break;
4480f4a2713aSLionel Sambuc     case 1:
4481f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 6, 2);
4482f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4483f4a2713aSLionel Sambuc         align = 4;
4484f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4485f4a2713aSLionel Sambuc         inc = 2;
4486f4a2713aSLionel Sambuc       break;
4487f4a2713aSLionel Sambuc     case 2:
4488f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4489f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4490f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 7, 1);
4491f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1) != 0)
4492f4a2713aSLionel Sambuc         align = 8;
4493f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 6, 1))
4494f4a2713aSLionel Sambuc         inc = 2;
4495f4a2713aSLionel Sambuc       break;
4496f4a2713aSLionel Sambuc   }
4497f4a2713aSLionel Sambuc 
4498f4a2713aSLionel Sambuc   if (Rm != 0xF) { // Writeback
4499f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4500f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4501f4a2713aSLionel Sambuc   }
4502f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4503f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4504f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
4505f4a2713aSLionel Sambuc   if (Rm != 0xF) {
4506f4a2713aSLionel Sambuc     if (Rm != 0xD) {
4507f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4508f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
4509f4a2713aSLionel Sambuc     } else
4510f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(0));
4511f4a2713aSLionel Sambuc   }
4512f4a2713aSLionel Sambuc 
4513f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4514f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4515f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4516f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4517f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(index));
4518f4a2713aSLionel Sambuc 
4519f4a2713aSLionel Sambuc   return S;
4520f4a2713aSLionel Sambuc }
4521f4a2713aSLionel Sambuc 
4522f4a2713aSLionel Sambuc 
DecodeVLD3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4523f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
4524f4a2713aSLionel Sambuc                          uint64_t Address, const void *Decoder) {
4525f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4526f4a2713aSLionel Sambuc 
4527f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4528f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4529f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4530f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4531f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 10, 2);
4532f4a2713aSLionel Sambuc 
4533f4a2713aSLionel Sambuc   unsigned align = 0;
4534f4a2713aSLionel Sambuc   unsigned index = 0;
4535f4a2713aSLionel Sambuc   unsigned inc = 1;
4536f4a2713aSLionel Sambuc   switch (size) {
4537f4a2713aSLionel Sambuc     default:
4538f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4539f4a2713aSLionel Sambuc     case 0:
4540f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4541f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4542f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 5, 3);
4543f4a2713aSLionel Sambuc       break;
4544f4a2713aSLionel Sambuc     case 1:
4545f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4546f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4547f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 6, 2);
4548f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4549f4a2713aSLionel Sambuc         inc = 2;
4550f4a2713aSLionel Sambuc       break;
4551f4a2713aSLionel Sambuc     case 2:
4552f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 2))
4553f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4554f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 7, 1);
4555f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 6, 1))
4556f4a2713aSLionel Sambuc         inc = 2;
4557f4a2713aSLionel Sambuc       break;
4558f4a2713aSLionel Sambuc   }
4559f4a2713aSLionel Sambuc 
4560f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4561f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4562f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4563f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4564f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4565f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4566f4a2713aSLionel Sambuc 
4567f4a2713aSLionel Sambuc   if (Rm != 0xF) { // Writeback
4568f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4569f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4570f4a2713aSLionel Sambuc   }
4571f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4572f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4573f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
4574f4a2713aSLionel Sambuc   if (Rm != 0xF) {
4575f4a2713aSLionel Sambuc     if (Rm != 0xD) {
4576f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4577f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4578f4a2713aSLionel Sambuc     } else
4579f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(0));
4580f4a2713aSLionel Sambuc   }
4581f4a2713aSLionel Sambuc 
4582f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4583f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4584f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4585f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4586f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4587f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4588f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(index));
4589f4a2713aSLionel Sambuc 
4590f4a2713aSLionel Sambuc   return S;
4591f4a2713aSLionel Sambuc }
4592f4a2713aSLionel Sambuc 
DecodeVST3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4593f4a2713aSLionel Sambuc static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
4594f4a2713aSLionel Sambuc                          uint64_t Address, const void *Decoder) {
4595f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4596f4a2713aSLionel Sambuc 
4597f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4598f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4599f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4600f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4601f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 10, 2);
4602f4a2713aSLionel Sambuc 
4603f4a2713aSLionel Sambuc   unsigned align = 0;
4604f4a2713aSLionel Sambuc   unsigned index = 0;
4605f4a2713aSLionel Sambuc   unsigned inc = 1;
4606f4a2713aSLionel Sambuc   switch (size) {
4607f4a2713aSLionel Sambuc     default:
4608f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4609f4a2713aSLionel Sambuc     case 0:
4610f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4611f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4612f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 5, 3);
4613f4a2713aSLionel Sambuc       break;
4614f4a2713aSLionel Sambuc     case 1:
4615f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4616f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4617f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 6, 2);
4618f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4619f4a2713aSLionel Sambuc         inc = 2;
4620f4a2713aSLionel Sambuc       break;
4621f4a2713aSLionel Sambuc     case 2:
4622f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 2))
4623f4a2713aSLionel Sambuc         return MCDisassembler::Fail; // UNDEFINED
4624f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 7, 1);
4625f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 6, 1))
4626f4a2713aSLionel Sambuc         inc = 2;
4627f4a2713aSLionel Sambuc       break;
4628f4a2713aSLionel Sambuc   }
4629f4a2713aSLionel Sambuc 
4630f4a2713aSLionel Sambuc   if (Rm != 0xF) { // Writeback
4631f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4632f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4633f4a2713aSLionel Sambuc   }
4634f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4635f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4636f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
4637f4a2713aSLionel Sambuc   if (Rm != 0xF) {
4638f4a2713aSLionel Sambuc     if (Rm != 0xD) {
4639f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4640f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4641f4a2713aSLionel Sambuc     } else
4642f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(0));
4643f4a2713aSLionel Sambuc   }
4644f4a2713aSLionel Sambuc 
4645f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4646f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4647f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4648f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4649f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4650f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4651f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(index));
4652f4a2713aSLionel Sambuc 
4653f4a2713aSLionel Sambuc   return S;
4654f4a2713aSLionel Sambuc }
4655f4a2713aSLionel Sambuc 
4656f4a2713aSLionel Sambuc 
DecodeVLD4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4657f4a2713aSLionel Sambuc static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
4658f4a2713aSLionel Sambuc                          uint64_t Address, const void *Decoder) {
4659f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4660f4a2713aSLionel Sambuc 
4661f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4662f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4663f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4664f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4665f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 10, 2);
4666f4a2713aSLionel Sambuc 
4667f4a2713aSLionel Sambuc   unsigned align = 0;
4668f4a2713aSLionel Sambuc   unsigned index = 0;
4669f4a2713aSLionel Sambuc   unsigned inc = 1;
4670f4a2713aSLionel Sambuc   switch (size) {
4671f4a2713aSLionel Sambuc     default:
4672f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4673f4a2713aSLionel Sambuc     case 0:
4674f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4675f4a2713aSLionel Sambuc         align = 4;
4676f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 5, 3);
4677f4a2713aSLionel Sambuc       break;
4678f4a2713aSLionel Sambuc     case 1:
4679f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4680f4a2713aSLionel Sambuc         align = 8;
4681f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 6, 2);
4682f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4683f4a2713aSLionel Sambuc         inc = 2;
4684f4a2713aSLionel Sambuc       break;
4685f4a2713aSLionel Sambuc     case 2:
4686f4a2713aSLionel Sambuc       switch (fieldFromInstruction(Insn, 4, 2)) {
4687f4a2713aSLionel Sambuc         case 0:
4688f4a2713aSLionel Sambuc           align = 0; break;
4689f4a2713aSLionel Sambuc         case 3:
4690f4a2713aSLionel Sambuc           return MCDisassembler::Fail;
4691f4a2713aSLionel Sambuc         default:
4692f4a2713aSLionel Sambuc           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
4693f4a2713aSLionel Sambuc       }
4694f4a2713aSLionel Sambuc 
4695f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 7, 1);
4696f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 6, 1))
4697f4a2713aSLionel Sambuc         inc = 2;
4698f4a2713aSLionel Sambuc       break;
4699f4a2713aSLionel Sambuc   }
4700f4a2713aSLionel Sambuc 
4701f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4702f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4703f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4704f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4705f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4706f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4707f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4708f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4709f4a2713aSLionel Sambuc 
4710f4a2713aSLionel Sambuc   if (Rm != 0xF) { // Writeback
4711f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4712f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4713f4a2713aSLionel Sambuc   }
4714f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4715f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4716f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
4717f4a2713aSLionel Sambuc   if (Rm != 0xF) {
4718f4a2713aSLionel Sambuc     if (Rm != 0xD) {
4719f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4720f4a2713aSLionel Sambuc         return MCDisassembler::Fail;
4721f4a2713aSLionel Sambuc     } else
4722f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(0));
4723f4a2713aSLionel Sambuc   }
4724f4a2713aSLionel Sambuc 
4725f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4726f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4727f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4728f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4729f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4730f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4731f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4732f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4733f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(index));
4734f4a2713aSLionel Sambuc 
4735f4a2713aSLionel Sambuc   return S;
4736f4a2713aSLionel Sambuc }
4737f4a2713aSLionel Sambuc 
DecodeVST4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4738f4a2713aSLionel Sambuc static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
4739f4a2713aSLionel Sambuc                          uint64_t Address, const void *Decoder) {
4740f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4741f4a2713aSLionel Sambuc 
4742f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4743f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4744f4a2713aSLionel Sambuc   unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4745f4a2713aSLionel Sambuc   Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4746f4a2713aSLionel Sambuc   unsigned size = fieldFromInstruction(Insn, 10, 2);
4747f4a2713aSLionel Sambuc 
4748f4a2713aSLionel Sambuc   unsigned align = 0;
4749f4a2713aSLionel Sambuc   unsigned index = 0;
4750f4a2713aSLionel Sambuc   unsigned inc = 1;
4751f4a2713aSLionel Sambuc   switch (size) {
4752f4a2713aSLionel Sambuc     default:
4753f4a2713aSLionel Sambuc       return MCDisassembler::Fail;
4754f4a2713aSLionel Sambuc     case 0:
4755f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4756f4a2713aSLionel Sambuc         align = 4;
4757f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 5, 3);
4758f4a2713aSLionel Sambuc       break;
4759f4a2713aSLionel Sambuc     case 1:
4760f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 4, 1))
4761f4a2713aSLionel Sambuc         align = 8;
4762f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 6, 2);
4763f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 5, 1))
4764f4a2713aSLionel Sambuc         inc = 2;
4765f4a2713aSLionel Sambuc       break;
4766f4a2713aSLionel Sambuc     case 2:
4767f4a2713aSLionel Sambuc       switch (fieldFromInstruction(Insn, 4, 2)) {
4768f4a2713aSLionel Sambuc         case 0:
4769f4a2713aSLionel Sambuc           align = 0; break;
4770f4a2713aSLionel Sambuc         case 3:
4771f4a2713aSLionel Sambuc           return MCDisassembler::Fail;
4772f4a2713aSLionel Sambuc         default:
4773f4a2713aSLionel Sambuc           align = 4 << fieldFromInstruction(Insn, 4, 2); break;
4774f4a2713aSLionel Sambuc       }
4775f4a2713aSLionel Sambuc 
4776f4a2713aSLionel Sambuc       index = fieldFromInstruction(Insn, 7, 1);
4777f4a2713aSLionel Sambuc       if (fieldFromInstruction(Insn, 6, 1))
4778f4a2713aSLionel Sambuc         inc = 2;
4779f4a2713aSLionel Sambuc       break;
4780f4a2713aSLionel Sambuc   }
4781f4a2713aSLionel Sambuc 
4782f4a2713aSLionel Sambuc   if (Rm != 0xF) { // Writeback
4783f4a2713aSLionel Sambuc     if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4784f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4785f4a2713aSLionel Sambuc   }
4786f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4787f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4788f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(align));
4789f4a2713aSLionel Sambuc   if (Rm != 0xF) {
4790f4a2713aSLionel Sambuc     if (Rm != 0xD) {
4791f4a2713aSLionel Sambuc       if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4792f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4793f4a2713aSLionel Sambuc     } else
4794f4a2713aSLionel Sambuc       Inst.addOperand(MCOperand::CreateReg(0));
4795f4a2713aSLionel Sambuc   }
4796f4a2713aSLionel Sambuc 
4797f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4798f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4799f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4800f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4801f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4802f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4803f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4804f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4805f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(index));
4806f4a2713aSLionel Sambuc 
4807f4a2713aSLionel Sambuc   return S;
4808f4a2713aSLionel Sambuc }
4809f4a2713aSLionel Sambuc 
DecodeVMOVSRR(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4810f4a2713aSLionel Sambuc static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
4811f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
4812f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4813f4a2713aSLionel Sambuc   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
4814f4a2713aSLionel Sambuc   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
4815f4a2713aSLionel Sambuc   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
4816f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
4817f4a2713aSLionel Sambuc   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
4818f4a2713aSLionel Sambuc 
4819f4a2713aSLionel Sambuc   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4820f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
4821f4a2713aSLionel Sambuc 
4822f4a2713aSLionel Sambuc   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4823f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4824f4a2713aSLionel Sambuc   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4825f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4826f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4827f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4828f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4829f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4830f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4831f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4832f4a2713aSLionel Sambuc 
4833f4a2713aSLionel Sambuc   return S;
4834f4a2713aSLionel Sambuc }
4835f4a2713aSLionel Sambuc 
DecodeVMOVRRS(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4836f4a2713aSLionel Sambuc static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
4837f4a2713aSLionel Sambuc                                   uint64_t Address, const void *Decoder) {
4838f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4839f4a2713aSLionel Sambuc   unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
4840f4a2713aSLionel Sambuc   unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
4841f4a2713aSLionel Sambuc   unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
4842f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
4843f4a2713aSLionel Sambuc   Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
4844f4a2713aSLionel Sambuc 
4845f4a2713aSLionel Sambuc   if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4846f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
4847f4a2713aSLionel Sambuc 
4848f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4849f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4850f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4851f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4852f4a2713aSLionel Sambuc   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4853f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4854f4a2713aSLionel Sambuc   if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4855f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4856f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4857f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4858f4a2713aSLionel Sambuc 
4859f4a2713aSLionel Sambuc   return S;
4860f4a2713aSLionel Sambuc }
4861f4a2713aSLionel Sambuc 
DecodeIT(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4862f4a2713aSLionel Sambuc static DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn,
4863f4a2713aSLionel Sambuc                              uint64_t Address, const void *Decoder) {
4864f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4865f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 4, 4);
4866f4a2713aSLionel Sambuc   unsigned mask = fieldFromInstruction(Insn, 0, 4);
4867f4a2713aSLionel Sambuc 
4868f4a2713aSLionel Sambuc   if (pred == 0xF) {
4869f4a2713aSLionel Sambuc     pred = 0xE;
4870f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
4871f4a2713aSLionel Sambuc   }
4872f4a2713aSLionel Sambuc 
4873f4a2713aSLionel Sambuc   if (mask == 0x0)
4874f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4875f4a2713aSLionel Sambuc 
4876f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(pred));
4877f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(mask));
4878f4a2713aSLionel Sambuc   return S;
4879f4a2713aSLionel Sambuc }
4880f4a2713aSLionel Sambuc 
4881f4a2713aSLionel Sambuc static DecodeStatus
DecodeT2LDRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4882f4a2713aSLionel Sambuc DecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
4883f4a2713aSLionel Sambuc                            uint64_t Address, const void *Decoder) {
4884f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4885f4a2713aSLionel Sambuc 
4886f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4887f4a2713aSLionel Sambuc   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
4888f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4889f4a2713aSLionel Sambuc   unsigned addr = fieldFromInstruction(Insn, 0, 8);
4890f4a2713aSLionel Sambuc   unsigned W = fieldFromInstruction(Insn, 21, 1);
4891f4a2713aSLionel Sambuc   unsigned U = fieldFromInstruction(Insn, 23, 1);
4892f4a2713aSLionel Sambuc   unsigned P = fieldFromInstruction(Insn, 24, 1);
4893f4a2713aSLionel Sambuc   bool writeback = (W == 1) | (P == 0);
4894f4a2713aSLionel Sambuc 
4895f4a2713aSLionel Sambuc   addr |= (U << 8) | (Rn << 9);
4896f4a2713aSLionel Sambuc 
4897f4a2713aSLionel Sambuc   if (writeback && (Rn == Rt || Rn == Rt2))
4898f4a2713aSLionel Sambuc     Check(S, MCDisassembler::SoftFail);
4899f4a2713aSLionel Sambuc   if (Rt == Rt2)
4900f4a2713aSLionel Sambuc     Check(S, MCDisassembler::SoftFail);
4901f4a2713aSLionel Sambuc 
4902f4a2713aSLionel Sambuc   // Rt
4903f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4904f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4905f4a2713aSLionel Sambuc   // Rt2
4906f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4907f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4908f4a2713aSLionel Sambuc   // Writeback operand
4909f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4910f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4911f4a2713aSLionel Sambuc   // addr
4912f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4913f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4914f4a2713aSLionel Sambuc 
4915f4a2713aSLionel Sambuc   return S;
4916f4a2713aSLionel Sambuc }
4917f4a2713aSLionel Sambuc 
4918f4a2713aSLionel Sambuc static DecodeStatus
DecodeT2STRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4919f4a2713aSLionel Sambuc DecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
4920f4a2713aSLionel Sambuc                            uint64_t Address, const void *Decoder) {
4921f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4922f4a2713aSLionel Sambuc 
4923f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4924f4a2713aSLionel Sambuc   unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
4925f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4926f4a2713aSLionel Sambuc   unsigned addr = fieldFromInstruction(Insn, 0, 8);
4927f4a2713aSLionel Sambuc   unsigned W = fieldFromInstruction(Insn, 21, 1);
4928f4a2713aSLionel Sambuc   unsigned U = fieldFromInstruction(Insn, 23, 1);
4929f4a2713aSLionel Sambuc   unsigned P = fieldFromInstruction(Insn, 24, 1);
4930f4a2713aSLionel Sambuc   bool writeback = (W == 1) | (P == 0);
4931f4a2713aSLionel Sambuc 
4932f4a2713aSLionel Sambuc   addr |= (U << 8) | (Rn << 9);
4933f4a2713aSLionel Sambuc 
4934f4a2713aSLionel Sambuc   if (writeback && (Rn == Rt || Rn == Rt2))
4935f4a2713aSLionel Sambuc     Check(S, MCDisassembler::SoftFail);
4936f4a2713aSLionel Sambuc 
4937f4a2713aSLionel Sambuc   // Writeback operand
4938f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4939f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4940f4a2713aSLionel Sambuc   // Rt
4941f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4942f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4943f4a2713aSLionel Sambuc   // Rt2
4944f4a2713aSLionel Sambuc   if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4945f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4946f4a2713aSLionel Sambuc   // addr
4947f4a2713aSLionel Sambuc   if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4948f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4949f4a2713aSLionel Sambuc 
4950f4a2713aSLionel Sambuc   return S;
4951f4a2713aSLionel Sambuc }
4952f4a2713aSLionel Sambuc 
DecodeT2Adr(MCInst & Inst,uint32_t Insn,uint64_t Address,const void * Decoder)4953f4a2713aSLionel Sambuc static DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn,
4954f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder) {
4955f4a2713aSLionel Sambuc   unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
4956f4a2713aSLionel Sambuc   unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
4957f4a2713aSLionel Sambuc   if (sign1 != sign2) return MCDisassembler::Fail;
4958f4a2713aSLionel Sambuc 
4959f4a2713aSLionel Sambuc   unsigned Val = fieldFromInstruction(Insn, 0, 8);
4960f4a2713aSLionel Sambuc   Val |= fieldFromInstruction(Insn, 12, 3) << 8;
4961f4a2713aSLionel Sambuc   Val |= fieldFromInstruction(Insn, 26, 1) << 11;
4962f4a2713aSLionel Sambuc   Val |= sign1 << 12;
4963f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val)));
4964f4a2713aSLionel Sambuc 
4965f4a2713aSLionel Sambuc   return MCDisassembler::Success;
4966f4a2713aSLionel Sambuc }
4967f4a2713aSLionel Sambuc 
DecodeT2ShifterImmOperand(MCInst & Inst,uint32_t Val,uint64_t Address,const void * Decoder)4968f4a2713aSLionel Sambuc static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
4969f4a2713aSLionel Sambuc                                               uint64_t Address,
4970f4a2713aSLionel Sambuc                                               const void *Decoder) {
4971f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4972f4a2713aSLionel Sambuc 
4973f4a2713aSLionel Sambuc   // Shift of "asr #32" is not allowed in Thumb2 mode.
4974f4a2713aSLionel Sambuc   if (Val == 0x20) S = MCDisassembler::SoftFail;
4975f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(Val));
4976f4a2713aSLionel Sambuc   return S;
4977f4a2713aSLionel Sambuc }
4978f4a2713aSLionel Sambuc 
DecodeSwap(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)4979f4a2713aSLionel Sambuc static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
4980f4a2713aSLionel Sambuc                                uint64_t Address, const void *Decoder) {
4981f4a2713aSLionel Sambuc   unsigned Rt   = fieldFromInstruction(Insn, 12, 4);
4982f4a2713aSLionel Sambuc   unsigned Rt2  = fieldFromInstruction(Insn, 0,  4);
4983f4a2713aSLionel Sambuc   unsigned Rn   = fieldFromInstruction(Insn, 16, 4);
4984f4a2713aSLionel Sambuc   unsigned pred = fieldFromInstruction(Insn, 28, 4);
4985f4a2713aSLionel Sambuc 
4986f4a2713aSLionel Sambuc   if (pred == 0xF)
4987f4a2713aSLionel Sambuc     return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
4988f4a2713aSLionel Sambuc 
4989f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
4990f4a2713aSLionel Sambuc 
4991f4a2713aSLionel Sambuc   if (Rt == Rn || Rn == Rt2)
4992f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
4993f4a2713aSLionel Sambuc 
4994f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4995f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4996f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
4997f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
4998f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4999f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5000f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5001f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5002f4a2713aSLionel Sambuc 
5003f4a2713aSLionel Sambuc   return S;
5004f4a2713aSLionel Sambuc }
5005f4a2713aSLionel Sambuc 
DecodeVCVTD(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)5006f4a2713aSLionel Sambuc static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
5007f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder) {
5008f4a2713aSLionel Sambuc   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
5009f4a2713aSLionel Sambuc   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
5010f4a2713aSLionel Sambuc   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
5011f4a2713aSLionel Sambuc   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
5012f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 16, 6);
5013f4a2713aSLionel Sambuc   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
5014f4a2713aSLionel Sambuc   unsigned op = fieldFromInstruction(Insn, 5, 1);
5015f4a2713aSLionel Sambuc 
5016f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
5017f4a2713aSLionel Sambuc 
5018f4a2713aSLionel Sambuc   // VMOVv2f32 is ambiguous with these decodings.
5019f4a2713aSLionel Sambuc   if (!(imm & 0x38) && cmode == 0xF) {
5020f4a2713aSLionel Sambuc     if (op == 1) return MCDisassembler::Fail;
5021f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::VMOVv2f32);
5022f4a2713aSLionel Sambuc     return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
5023f4a2713aSLionel Sambuc   }
5024f4a2713aSLionel Sambuc 
5025f4a2713aSLionel Sambuc   if (!(imm & 0x20)) return MCDisassembler::Fail;
5026f4a2713aSLionel Sambuc 
5027f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
5028f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5029f4a2713aSLionel Sambuc   if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
5030f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5031f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(64 - imm));
5032f4a2713aSLionel Sambuc 
5033f4a2713aSLionel Sambuc   return S;
5034f4a2713aSLionel Sambuc }
5035f4a2713aSLionel Sambuc 
DecodeVCVTQ(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)5036f4a2713aSLionel Sambuc static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
5037f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder) {
5038f4a2713aSLionel Sambuc   unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
5039f4a2713aSLionel Sambuc   Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
5040f4a2713aSLionel Sambuc   unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
5041f4a2713aSLionel Sambuc   Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
5042f4a2713aSLionel Sambuc   unsigned imm = fieldFromInstruction(Insn, 16, 6);
5043f4a2713aSLionel Sambuc   unsigned cmode = fieldFromInstruction(Insn, 8, 4);
5044f4a2713aSLionel Sambuc   unsigned op = fieldFromInstruction(Insn, 5, 1);
5045f4a2713aSLionel Sambuc 
5046f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
5047f4a2713aSLionel Sambuc 
5048f4a2713aSLionel Sambuc   // VMOVv4f32 is ambiguous with these decodings.
5049f4a2713aSLionel Sambuc   if (!(imm & 0x38) && cmode == 0xF) {
5050f4a2713aSLionel Sambuc     if (op == 1) return MCDisassembler::Fail;
5051f4a2713aSLionel Sambuc     Inst.setOpcode(ARM::VMOVv4f32);
5052f4a2713aSLionel Sambuc     return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
5053f4a2713aSLionel Sambuc   }
5054f4a2713aSLionel Sambuc 
5055f4a2713aSLionel Sambuc   if (!(imm & 0x20)) return MCDisassembler::Fail;
5056f4a2713aSLionel Sambuc 
5057f4a2713aSLionel Sambuc   if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
5058f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5059f4a2713aSLionel Sambuc   if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
5060f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5061f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(64 - imm));
5062f4a2713aSLionel Sambuc 
5063f4a2713aSLionel Sambuc   return S;
5064f4a2713aSLionel Sambuc }
5065f4a2713aSLionel Sambuc 
DecodeLDR(MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)5066f4a2713aSLionel Sambuc static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
5067f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder) {
5068f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
5069f4a2713aSLionel Sambuc 
5070f4a2713aSLionel Sambuc   unsigned Rn = fieldFromInstruction(Val, 16, 4);
5071f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Val, 12, 4);
5072f4a2713aSLionel Sambuc   unsigned Rm = fieldFromInstruction(Val, 0, 4);
5073f4a2713aSLionel Sambuc   Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
5074f4a2713aSLionel Sambuc   unsigned Cond = fieldFromInstruction(Val, 28, 4);
5075f4a2713aSLionel Sambuc 
5076f4a2713aSLionel Sambuc   if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
5077f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
5078f4a2713aSLionel Sambuc 
5079f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5080f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5081f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
5082f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5083f4a2713aSLionel Sambuc   if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
5084f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5085f4a2713aSLionel Sambuc   if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
5086f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5087f4a2713aSLionel Sambuc   if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
5088f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5089f4a2713aSLionel Sambuc 
5090f4a2713aSLionel Sambuc   return S;
5091f4a2713aSLionel Sambuc }
5092f4a2713aSLionel Sambuc 
DecodeMRRC2(llvm::MCInst & Inst,unsigned Val,uint64_t Address,const void * Decoder)5093f4a2713aSLionel Sambuc static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
5094f4a2713aSLionel Sambuc                                 uint64_t Address, const void *Decoder) {
5095f4a2713aSLionel Sambuc 
5096f4a2713aSLionel Sambuc   DecodeStatus S = MCDisassembler::Success;
5097f4a2713aSLionel Sambuc 
5098f4a2713aSLionel Sambuc   unsigned CRm = fieldFromInstruction(Val, 0, 4);
5099f4a2713aSLionel Sambuc   unsigned opc1 = fieldFromInstruction(Val, 4, 4);
5100f4a2713aSLionel Sambuc   unsigned cop = fieldFromInstruction(Val, 8, 4);
5101f4a2713aSLionel Sambuc   unsigned Rt = fieldFromInstruction(Val, 12, 4);
5102f4a2713aSLionel Sambuc   unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
5103f4a2713aSLionel Sambuc 
5104f4a2713aSLionel Sambuc   if ((cop & ~0x1) == 0xa)
5105f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5106f4a2713aSLionel Sambuc 
5107f4a2713aSLionel Sambuc   if (Rt == Rt2)
5108f4a2713aSLionel Sambuc     S = MCDisassembler::SoftFail;
5109f4a2713aSLionel Sambuc 
5110f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(cop));
5111f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(opc1));
5112f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5113f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5114f4a2713aSLionel Sambuc   if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5115f4a2713aSLionel Sambuc     return MCDisassembler::Fail;
5116f4a2713aSLionel Sambuc   Inst.addOperand(MCOperand::CreateImm(CRm));
5117f4a2713aSLionel Sambuc 
5118f4a2713aSLionel Sambuc   return S;
5119f4a2713aSLionel Sambuc }
5120f4a2713aSLionel Sambuc 
5121