1234353Sdim//===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===//
2206124Srdivacky//
3206124Srdivacky//                     The LLVM Compiler Infrastructure
4206124Srdivacky//
5206124Srdivacky// This file is distributed under the University of Illinois Open Source
6206124Srdivacky// License. See LICENSE.TXT for details.
7206124Srdivacky//
8206124Srdivacky//===----------------------------------------------------------------------===//
9206124Srdivacky
10206124Srdivacky#define DEBUG_TYPE "arm-disassembler"
11206124Srdivacky
12249423Sdim#include "llvm/MC/MCDisassembler.h"
13226633Sdim#include "MCTargetDesc/ARMAddressingModes.h"
14249423Sdim#include "MCTargetDesc/ARMBaseInfo.h"
15226633Sdim#include "MCTargetDesc/ARMMCExpr.h"
16249423Sdim#include "llvm/MC/MCContext.h"
17249423Sdim#include "llvm/MC/MCExpr.h"
18249423Sdim#include "llvm/MC/MCFixedLenDisassembler.h"
19206124Srdivacky#include "llvm/MC/MCInst.h"
20234353Sdim#include "llvm/MC/MCInstrDesc.h"
21234353Sdim#include "llvm/MC/MCSubtargetInfo.h"
22206124Srdivacky#include "llvm/Support/Debug.h"
23206124Srdivacky#include "llvm/Support/ErrorHandling.h"
24239462Sdim#include "llvm/Support/LEB128.h"
25249423Sdim#include "llvm/Support/MemoryObject.h"
26226633Sdim#include "llvm/Support/TargetRegistry.h"
27206124Srdivacky#include "llvm/Support/raw_ostream.h"
28239462Sdim#include <vector>
29206124Srdivacky
30226633Sdimusing namespace llvm;
31212904Sdim
32226633Sdimtypedef MCDisassembler::DecodeStatus DecodeStatus;
33206124Srdivacky
34226633Sdimnamespace {
35239462Sdim  // Handles the condition code status of instructions in IT blocks
36239462Sdim  class ITStatus
37239462Sdim  {
38239462Sdim    public:
39239462Sdim      // Returns the condition code for instruction in IT block
40239462Sdim      unsigned getITCC() {
41239462Sdim        unsigned CC = ARMCC::AL;
42239462Sdim        if (instrInITBlock())
43239462Sdim          CC = ITStates.back();
44239462Sdim        return CC;
45239462Sdim      }
46239462Sdim
47239462Sdim      // Advances the IT block state to the next T or E
48239462Sdim      void advanceITState() {
49239462Sdim        ITStates.pop_back();
50239462Sdim      }
51239462Sdim
52239462Sdim      // Returns true if the current instruction is in an IT block
53239462Sdim      bool instrInITBlock() {
54239462Sdim        return !ITStates.empty();
55239462Sdim      }
56239462Sdim
57239462Sdim      // Returns true if current instruction is the last instruction in an IT block
58239462Sdim      bool instrLastInITBlock() {
59239462Sdim        return ITStates.size() == 1;
60239462Sdim      }
61239462Sdim
62239462Sdim      // Called when decoding an IT instruction. Sets the IT state for the following
63239462Sdim      // instructions that for the IT block. Firstcond and Mask correspond to the
64239462Sdim      // fields in the IT instruction encoding.
65239462Sdim      void setITState(char Firstcond, char Mask) {
66239462Sdim        // (3 - the number of trailing zeros) is the number of then / else.
67239462Sdim        unsigned CondBit0 = Firstcond & 1;
68239462Sdim        unsigned NumTZ = CountTrailingZeros_32(Mask);
69239462Sdim        unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
70239462Sdim        assert(NumTZ <= 3 && "Invalid IT mask!");
71239462Sdim        // push condition codes onto the stack the correct order for the pops
72239462Sdim        for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
73239462Sdim          bool T = ((Mask >> Pos) & 1) == CondBit0;
74239462Sdim          if (T)
75239462Sdim            ITStates.push_back(CCBits);
76239462Sdim          else
77239462Sdim            ITStates.push_back(CCBits ^ 1);
78239462Sdim        }
79239462Sdim        ITStates.push_back(CCBits);
80239462Sdim      }
81239462Sdim
82239462Sdim    private:
83239462Sdim      std::vector<unsigned char> ITStates;
84239462Sdim  };
85239462Sdim}
86239462Sdim
87239462Sdimnamespace {
88226633Sdim/// ARMDisassembler - ARM disassembler for all ARM platforms.
89226633Sdimclass ARMDisassembler : public MCDisassembler {
90226633Sdimpublic:
91226633Sdim  /// Constructor     - Initializes the disassembler.
92226633Sdim  ///
93226633Sdim  ARMDisassembler(const MCSubtargetInfo &STI) :
94226633Sdim    MCDisassembler(STI) {
95226633Sdim  }
96226633Sdim
97226633Sdim  ~ARMDisassembler() {
98226633Sdim  }
99226633Sdim
100226633Sdim  /// getInstruction - See MCDisassembler.
101226633Sdim  DecodeStatus getInstruction(MCInst &instr,
102226633Sdim                              uint64_t &size,
103226633Sdim                              const MemoryObject &region,
104226633Sdim                              uint64_t address,
105226633Sdim                              raw_ostream &vStream,
106226633Sdim                              raw_ostream &cStream) const;
107226633Sdim};
108226633Sdim
109226633Sdim/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.
110226633Sdimclass ThumbDisassembler : public MCDisassembler {
111226633Sdimpublic:
112226633Sdim  /// Constructor     - Initializes the disassembler.
113226633Sdim  ///
114226633Sdim  ThumbDisassembler(const MCSubtargetInfo &STI) :
115226633Sdim    MCDisassembler(STI) {
116226633Sdim  }
117226633Sdim
118226633Sdim  ~ThumbDisassembler() {
119226633Sdim  }
120226633Sdim
121226633Sdim  /// getInstruction - See MCDisassembler.
122226633Sdim  DecodeStatus getInstruction(MCInst &instr,
123226633Sdim                              uint64_t &size,
124226633Sdim                              const MemoryObject &region,
125226633Sdim                              uint64_t address,
126226633Sdim                              raw_ostream &vStream,
127226633Sdim                              raw_ostream &cStream) const;
128226633Sdim
129226633Sdimprivate:
130239462Sdim  mutable ITStatus ITBlock;
131226633Sdim  DecodeStatus AddThumbPredicate(MCInst&) const;
132226633Sdim  void UpdateThumbVFPPredicate(MCInst&) const;
133226633Sdim};
134226633Sdim}
135226633Sdim
136226633Sdimstatic bool Check(DecodeStatus &Out, DecodeStatus In) {
137226633Sdim  switch (In) {
138226633Sdim    case MCDisassembler::Success:
139226633Sdim      // Out stays the same.
140226633Sdim      return true;
141226633Sdim    case MCDisassembler::SoftFail:
142226633Sdim      Out = In;
143226633Sdim      return true;
144226633Sdim    case MCDisassembler::Fail:
145226633Sdim      Out = In;
146226633Sdim      return false;
147226633Sdim  }
148234353Sdim  llvm_unreachable("Invalid DecodeStatus!");
149226633Sdim}
150226633Sdim
151226633Sdim
152226633Sdim// Forward declare these because the autogenerated code will reference them.
153226633Sdim// Definitions are further down.
154234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
155226633Sdim                                   uint64_t Address, const void *Decoder);
156234353Sdimstatic DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst,
157226633Sdim                                               unsigned RegNo, uint64_t Address,
158226633Sdim                                               const void *Decoder);
159234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
160226633Sdim                                   uint64_t Address, const void *Decoder);
161234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
162226633Sdim                                   uint64_t Address, const void *Decoder);
163234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
164226633Sdim                                   uint64_t Address, const void *Decoder);
165234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
166226633Sdim                                   uint64_t Address, const void *Decoder);
167234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
168226633Sdim                                   uint64_t Address, const void *Decoder);
169234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
170226633Sdim                                   uint64_t Address, const void *Decoder);
171234353Sdimstatic DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
172226633Sdim                                                unsigned RegNo,
173226633Sdim                                                uint64_t Address,
174226633Sdim                                                const void *Decoder);
175234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
176226633Sdim                                   uint64_t Address, const void *Decoder);
177234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
178234353Sdim                                   uint64_t Address, const void *Decoder);
179234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
180234353Sdim                               unsigned RegNo, uint64_t Address,
181234353Sdim                               const void *Decoder);
182226633Sdim
183234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
184226633Sdim                               uint64_t Address, const void *Decoder);
185234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
186226633Sdim                               uint64_t Address, const void *Decoder);
187234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val,
188226633Sdim                               uint64_t Address, const void *Decoder);
189234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
190226633Sdim                               uint64_t Address, const void *Decoder);
191234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
192226633Sdim                               uint64_t Address, const void *Decoder);
193234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
194226633Sdim                               uint64_t Address, const void *Decoder);
195226633Sdim
196234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
197226633Sdim                               uint64_t Address, const void *Decoder);
198234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
199226633Sdim                               uint64_t Address, const void *Decoder);
200234353Sdimstatic DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst,
201226633Sdim                                                  unsigned Insn,
202226633Sdim                                                  uint64_t Address,
203226633Sdim                                                  const void *Decoder);
204234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
205226633Sdim                               uint64_t Address, const void *Decoder);
206234353Sdimstatic DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn,
207226633Sdim                               uint64_t Address, const void *Decoder);
208234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
209226633Sdim                               uint64_t Address, const void *Decoder);
210234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
211226633Sdim                               uint64_t Address, const void *Decoder);
212226633Sdim
213234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst,
214226633Sdim                                                  unsigned Insn,
215226633Sdim                                                  uint64_t Adddress,
216226633Sdim                                                  const void *Decoder);
217234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
218226633Sdim                               uint64_t Address, const void *Decoder);
219234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
220226633Sdim                               uint64_t Address, const void *Decoder);
221234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
222226633Sdim                               uint64_t Address, const void *Decoder);
223234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
224226633Sdim                               uint64_t Address, const void *Decoder);
225234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
226226633Sdim                               uint64_t Address, const void *Decoder);
227234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
228226633Sdim                               uint64_t Address, const void *Decoder);
229234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
230226633Sdim                               uint64_t Address, const void *Decoder);
231234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
232226633Sdim                               uint64_t Address, const void *Decoder);
233234353Sdimstatic DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
234226633Sdim                               uint64_t Address, const void *Decoder);
235234353Sdimstatic DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn,
236226633Sdim                               uint64_t Address, const void *Decoder);
237234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
238226633Sdim                               uint64_t Address, const void *Decoder);
239234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
240226633Sdim                               uint64_t Address, const void *Decoder);
241234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
242226633Sdim                               uint64_t Address, const void *Decoder);
243234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
244226633Sdim                               uint64_t Address, const void *Decoder);
245234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
246226633Sdim                               uint64_t Address, const void *Decoder);
247234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
248226633Sdim                               uint64_t Address, const void *Decoder);
249234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
250226633Sdim                               uint64_t Address, const void *Decoder);
251234353Sdimstatic DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val,
252226633Sdim                               uint64_t Address, const void *Decoder);
253234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
254226633Sdim                               uint64_t Address, const void *Decoder);
255234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
256226633Sdim                               uint64_t Address, const void *Decoder);
257234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
258226633Sdim                               uint64_t Address, const void *Decoder);
259234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
260226633Sdim                               uint64_t Address, const void *Decoder);
261234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
262226633Sdim                               uint64_t Address, const void *Decoder);
263234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
264226633Sdim                               uint64_t Address, const void *Decoder);
265234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
266226633Sdim                               uint64_t Address, const void *Decoder);
267234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
268226633Sdim                               uint64_t Address, const void *Decoder);
269234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
270226633Sdim                               uint64_t Address, const void *Decoder);
271234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
272226633Sdim                               uint64_t Address, const void *Decoder);
273234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
274226633Sdim                               uint64_t Address, const void *Decoder);
275234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
276226633Sdim                               uint64_t Address, const void *Decoder);
277234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
278226633Sdim                               uint64_t Address, const void *Decoder);
279234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
280226633Sdim                               uint64_t Address, const void *Decoder);
281234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
282226633Sdim                               uint64_t Address, const void *Decoder);
283234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
284226633Sdim                               uint64_t Address, const void *Decoder);
285234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
286226633Sdim                               uint64_t Address, const void *Decoder);
287234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
288226633Sdim                               uint64_t Address, const void *Decoder);
289234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
290226633Sdim                               uint64_t Address, const void *Decoder);
291234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
292226633Sdim                               uint64_t Address, const void *Decoder);
293234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
294226633Sdim                               uint64_t Address, const void *Decoder);
295234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
296226633Sdim                               uint64_t Address, const void *Decoder);
297234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
298226633Sdim                               uint64_t Address, const void *Decoder);
299234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
300226633Sdim                               uint64_t Address, const void *Decoder);
301234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
302226633Sdim                               uint64_t Address, const void *Decoder);
303234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
304226633Sdim                               uint64_t Address, const void *Decoder);
305234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
306234353Sdim                               uint64_t Address, const void *Decoder);
307234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
308234353Sdim                                uint64_t Address, const void *Decoder);
309234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
310234353Sdim                                uint64_t Address, const void *Decoder);
311251662Sdimstatic DecodeStatus DecodeImm0_4(MCInst &Inst, unsigned Insn, uint64_t Address,
312251662Sdim                                 const void *Decoder);
313226633Sdim
314234353Sdim
315234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
316226633Sdim                               uint64_t Address, const void *Decoder);
317234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
318226633Sdim                               uint64_t Address, const void *Decoder);
319234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
320226633Sdim                               uint64_t Address, const void *Decoder);
321234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
322226633Sdim                               uint64_t Address, const void *Decoder);
323234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
324226633Sdim                               uint64_t Address, const void *Decoder);
325234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
326226633Sdim                               uint64_t Address, const void *Decoder);
327234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
328226633Sdim                               uint64_t Address, const void *Decoder);
329234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
330226633Sdim                               uint64_t Address, const void *Decoder);
331234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
332226633Sdim                               uint64_t Address, const void *Decoder);
333234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
334226633Sdim                               uint64_t Address, const void *Decoder);
335234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
336226633Sdim                               uint64_t Address, const void *Decoder);
337234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
338226633Sdim                               uint64_t Address, const void *Decoder);
339234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
340226633Sdim                               uint64_t Address, const void *Decoder);
341234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
342226633Sdim                               uint64_t Address, const void *Decoder);
343234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
344226633Sdim                               uint64_t Address, const void *Decoder);
345234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
346226633Sdim                               uint64_t Address, const void *Decoder);
347234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
348226633Sdim                                uint64_t Address, const void *Decoder);
349234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
350226633Sdim                                uint64_t Address, const void *Decoder);
351234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
352226633Sdim                                uint64_t Address, const void *Decoder);
353234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
354226633Sdim                                uint64_t Address, const void *Decoder);
355234353Sdimstatic DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
356226633Sdim                                uint64_t Address, const void *Decoder);
357234353Sdimstatic DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
358226633Sdim                                uint64_t Address, const void *Decoder);
359234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
360226633Sdim                                uint64_t Address, const void *Decoder);
361234353Sdimstatic DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val,
362226633Sdim                                uint64_t Address, const void *Decoder);
363234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
364226633Sdim                                uint64_t Address, const void *Decoder);
365234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Val,
366226633Sdim                                uint64_t Address, const void *Decoder);
367234353Sdimstatic DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn,
368226633Sdim                               uint64_t Address, const void *Decoder);
369234353Sdimstatic DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn,
370226633Sdim                               uint64_t Address, const void *Decoder);
371234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val,
372226633Sdim                                uint64_t Address, const void *Decoder);
373234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
374226633Sdim                                uint64_t Address, const void *Decoder);
375234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
376226633Sdim                                uint64_t Address, const void *Decoder);
377226633Sdim
378234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
379234353Sdim                                uint64_t Address, const void *Decoder);
380234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
381234982Sdim                                uint64_t Address, const void *Decoder);
382226633Sdim#include "ARMGenDisassemblerTables.inc"
383206124Srdivacky
384226633Sdimstatic MCDisassembler *createARMDisassembler(const Target &T, const MCSubtargetInfo &STI) {
385226633Sdim  return new ARMDisassembler(STI);
386226633Sdim}
387207618Srdivacky
388226633Sdimstatic MCDisassembler *createThumbDisassembler(const Target &T, const MCSubtargetInfo &STI) {
389226633Sdim  return new ThumbDisassembler(STI);
390226633Sdim}
391226633Sdim
392226633SdimDecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
393226633Sdim                                             const MemoryObject &Region,
394226633Sdim                                             uint64_t Address,
395226633Sdim                                             raw_ostream &os,
396226633Sdim                                             raw_ostream &cs) const {
397226633Sdim  CommentStream = &cs;
398226633Sdim
399226633Sdim  uint8_t bytes[4];
400226633Sdim
401226633Sdim  assert(!(STI.getFeatureBits() & ARM::ModeThumb) &&
402226633Sdim         "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!");
403226633Sdim
404226633Sdim  // We want to read exactly 4 bytes of data.
405226633Sdim  if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
406226633Sdim    Size = 0;
407226633Sdim    return MCDisassembler::Fail;
408206124Srdivacky  }
409226633Sdim
410226633Sdim  // Encoded as a small-endian 32-bit word in the stream.
411226633Sdim  uint32_t insn = (bytes[3] << 24) |
412226633Sdim                  (bytes[2] << 16) |
413226633Sdim                  (bytes[1] <<  8) |
414226633Sdim                  (bytes[0] <<  0);
415226633Sdim
416226633Sdim  // Calling the auto-generated decoder function.
417239462Sdim  DecodeStatus result = decodeInstruction(DecoderTableARM32, MI, insn,
418239462Sdim                                          Address, this, STI);
419226633Sdim  if (result != MCDisassembler::Fail) {
420226633Sdim    Size = 4;
421226633Sdim    return result;
422226633Sdim  }
423226633Sdim
424226633Sdim  // VFP and NEON instructions, similarly, are shared between ARM
425226633Sdim  // and Thumb modes.
426226633Sdim  MI.clear();
427239462Sdim  result = decodeInstruction(DecoderTableVFP32, MI, insn, Address, this, STI);
428226633Sdim  if (result != MCDisassembler::Fail) {
429226633Sdim    Size = 4;
430226633Sdim    return result;
431226633Sdim  }
432226633Sdim
433226633Sdim  MI.clear();
434239462Sdim  result = decodeInstruction(DecoderTableNEONData32, MI, insn, Address,
435239462Sdim                             this, STI);
436226633Sdim  if (result != MCDisassembler::Fail) {
437226633Sdim    Size = 4;
438226633Sdim    // Add a fake predicate operand, because we share these instruction
439226633Sdim    // definitions with Thumb2 where these instructions are predicable.
440226633Sdim    if (!DecodePredicateOperand(MI, 0xE, Address, this))
441226633Sdim      return MCDisassembler::Fail;
442226633Sdim    return result;
443226633Sdim  }
444226633Sdim
445226633Sdim  MI.clear();
446239462Sdim  result = decodeInstruction(DecoderTableNEONLoadStore32, MI, insn, Address,
447239462Sdim                             this, STI);
448226633Sdim  if (result != MCDisassembler::Fail) {
449226633Sdim    Size = 4;
450226633Sdim    // Add a fake predicate operand, because we share these instruction
451226633Sdim    // definitions with Thumb2 where these instructions are predicable.
452226633Sdim    if (!DecodePredicateOperand(MI, 0xE, Address, this))
453226633Sdim      return MCDisassembler::Fail;
454226633Sdim    return result;
455226633Sdim  }
456226633Sdim
457226633Sdim  MI.clear();
458239462Sdim  result = decodeInstruction(DecoderTableNEONDup32, MI, insn, Address,
459239462Sdim                             this, STI);
460226633Sdim  if (result != MCDisassembler::Fail) {
461226633Sdim    Size = 4;
462226633Sdim    // Add a fake predicate operand, because we share these instruction
463226633Sdim    // definitions with Thumb2 where these instructions are predicable.
464226633Sdim    if (!DecodePredicateOperand(MI, 0xE, Address, this))
465226633Sdim      return MCDisassembler::Fail;
466226633Sdim    return result;
467226633Sdim  }
468226633Sdim
469226633Sdim  MI.clear();
470226633Sdim
471226633Sdim  Size = 0;
472226633Sdim  return MCDisassembler::Fail;
473206124Srdivacky}
474206124Srdivacky
475226633Sdimnamespace llvm {
476234353Sdimextern const MCInstrDesc ARMInsts[];
477226633Sdim}
478206124Srdivacky
479226633Sdim/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
480226633Sdim/// immediate Value in the MCInst.  The immediate Value has had any PC
481226633Sdim/// adjustment made by the caller.  If the instruction is a branch instruction
482226633Sdim/// then isBranch is true, else false.  If the getOpInfo() function was set as
483226633Sdim/// part of the setupForSymbolicDisassembly() call then that function is called
484226633Sdim/// to get any symbolic information at the Address for this instruction.  If
485226633Sdim/// that returns non-zero then the symbolic information it returns is used to
486226633Sdim/// create an MCExpr and that is added as an operand to the MCInst.  If
487226633Sdim/// getOpInfo() returns zero and isBranch is true then a symbol look up for
488226633Sdim/// Value is done and if a symbol is found an MCExpr is created with that, else
489226633Sdim/// an MCExpr with Value is created.  This function returns true if it adds an
490226633Sdim/// operand to the MCInst and false otherwise.
491226633Sdimstatic bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
492226633Sdim                                     bool isBranch, uint64_t InstSize,
493226633Sdim                                     MCInst &MI, const void *Decoder) {
494226633Sdim  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
495226633Sdim  LLVMOpInfoCallback getOpInfo = Dis->getLLVMOpInfoCallback();
496226633Sdim  struct LLVMOpInfo1 SymbolicOp;
497234353Sdim  memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1));
498226633Sdim  SymbolicOp.Value = Value;
499226633Sdim  void *DisInfo = Dis->getDisInfoBlock();
500234353Sdim
501234353Sdim  if (!getOpInfo ||
502234353Sdim      !getOpInfo(DisInfo, Address, 0 /* Offset */, InstSize, 1, &SymbolicOp)) {
503234353Sdim    // Clear SymbolicOp.Value from above and also all other fields.
504234353Sdim    memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1));
505234353Sdim    LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback();
506234353Sdim    if (!SymbolLookUp)
507234353Sdim      return false;
508234353Sdim    uint64_t ReferenceType;
509234353Sdim    if (isBranch)
510234353Sdim       ReferenceType = LLVMDisassembler_ReferenceType_In_Branch;
511234353Sdim    else
512234353Sdim       ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
513234353Sdim    const char *ReferenceName;
514243830Sdim    uint64_t SymbolValue = 0x00000000ffffffffULL & Value;
515243830Sdim    const char *Name = SymbolLookUp(DisInfo, SymbolValue, &ReferenceType,
516243830Sdim                                    Address, &ReferenceName);
517234353Sdim    if (Name) {
518234353Sdim      SymbolicOp.AddSymbol.Name = Name;
519234353Sdim      SymbolicOp.AddSymbol.Present = true;
520226633Sdim    }
521234353Sdim    // For branches always create an MCExpr so it gets printed as hex address.
522234353Sdim    else if (isBranch) {
523234353Sdim      SymbolicOp.Value = Value;
524234353Sdim    }
525234353Sdim    if(ReferenceType == LLVMDisassembler_ReferenceType_Out_SymbolStub)
526234353Sdim      (*Dis->CommentStream) << "symbol stub for: " << ReferenceName;
527234353Sdim    if (!Name && !isBranch)
528226633Sdim      return false;
529226633Sdim  }
530226633Sdim
531226633Sdim  MCContext *Ctx = Dis->getMCContext();
532226633Sdim  const MCExpr *Add = NULL;
533226633Sdim  if (SymbolicOp.AddSymbol.Present) {
534226633Sdim    if (SymbolicOp.AddSymbol.Name) {
535226633Sdim      StringRef Name(SymbolicOp.AddSymbol.Name);
536226633Sdim      MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name);
537226633Sdim      Add = MCSymbolRefExpr::Create(Sym, *Ctx);
538226633Sdim    } else {
539226633Sdim      Add = MCConstantExpr::Create(SymbolicOp.AddSymbol.Value, *Ctx);
540226633Sdim    }
541226633Sdim  }
542226633Sdim
543226633Sdim  const MCExpr *Sub = NULL;
544226633Sdim  if (SymbolicOp.SubtractSymbol.Present) {
545226633Sdim    if (SymbolicOp.SubtractSymbol.Name) {
546226633Sdim      StringRef Name(SymbolicOp.SubtractSymbol.Name);
547226633Sdim      MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name);
548226633Sdim      Sub = MCSymbolRefExpr::Create(Sym, *Ctx);
549226633Sdim    } else {
550226633Sdim      Sub = MCConstantExpr::Create(SymbolicOp.SubtractSymbol.Value, *Ctx);
551226633Sdim    }
552226633Sdim  }
553226633Sdim
554226633Sdim  const MCExpr *Off = NULL;
555226633Sdim  if (SymbolicOp.Value != 0)
556226633Sdim    Off = MCConstantExpr::Create(SymbolicOp.Value, *Ctx);
557226633Sdim
558226633Sdim  const MCExpr *Expr;
559226633Sdim  if (Sub) {
560226633Sdim    const MCExpr *LHS;
561226633Sdim    if (Add)
562226633Sdim      LHS = MCBinaryExpr::CreateSub(Add, Sub, *Ctx);
563206124Srdivacky    else
564226633Sdim      LHS = MCUnaryExpr::CreateMinus(Sub, *Ctx);
565226633Sdim    if (Off != 0)
566226633Sdim      Expr = MCBinaryExpr::CreateAdd(LHS, Off, *Ctx);
567226633Sdim    else
568226633Sdim      Expr = LHS;
569226633Sdim  } else if (Add) {
570226633Sdim    if (Off != 0)
571226633Sdim      Expr = MCBinaryExpr::CreateAdd(Add, Off, *Ctx);
572226633Sdim    else
573226633Sdim      Expr = Add;
574226633Sdim  } else {
575226633Sdim    if (Off != 0)
576226633Sdim      Expr = Off;
577226633Sdim    else
578226633Sdim      Expr = MCConstantExpr::Create(0, *Ctx);
579206124Srdivacky  }
580206124Srdivacky
581226633Sdim  if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_HI16)
582226633Sdim    MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateUpper16(Expr, *Ctx)));
583226633Sdim  else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_LO16)
584226633Sdim    MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateLower16(Expr, *Ctx)));
585226633Sdim  else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_None)
586226633Sdim    MI.addOperand(MCOperand::CreateExpr(Expr));
587234353Sdim  else
588234353Sdim    llvm_unreachable("bad SymbolicOp.VariantKind");
589212904Sdim
590226633Sdim  return true;
591226633Sdim}
592226633Sdim
593226633Sdim/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
594226633Sdim/// referenced by a load instruction with the base register that is the Pc.
595226633Sdim/// These can often be values in a literal pool near the Address of the
596226633Sdim/// instruction.  The Address of the instruction and its immediate Value are
597226633Sdim/// used as a possible literal pool entry.  The SymbolLookUp call back will
598239462Sdim/// return the name of a symbol referenced by the literal pool's entry if
599226633Sdim/// the referenced address is that of a symbol.  Or it will return a pointer to
600226633Sdim/// a literal 'C' string if the referenced address of the literal pool's entry
601226633Sdim/// is an address into a section with 'C' string literals.
602226633Sdimstatic void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
603234353Sdim                                            const void *Decoder) {
604226633Sdim  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
605226633Sdim  LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback();
606226633Sdim  if (SymbolLookUp) {
607226633Sdim    void *DisInfo = Dis->getDisInfoBlock();
608226633Sdim    uint64_t ReferenceType;
609226633Sdim    ReferenceType = LLVMDisassembler_ReferenceType_In_PCrel_Load;
610226633Sdim    const char *ReferenceName;
611226633Sdim    (void)SymbolLookUp(DisInfo, Value, &ReferenceType, Address, &ReferenceName);
612226633Sdim    if(ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr ||
613226633Sdim       ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr)
614226633Sdim      (*Dis->CommentStream) << "literal pool for: " << ReferenceName;
615206124Srdivacky  }
616226633Sdim}
617206124Srdivacky
618226633Sdim// Thumb1 instructions don't have explicit S bits.  Rather, they
619226633Sdim// implicitly set CPSR.  Since it's not represented in the encoding, the
620226633Sdim// auto-generated decoder won't inject the CPSR operand.  We need to fix
621226633Sdim// that as a post-pass.
622226633Sdimstatic void AddThumb1SBit(MCInst &MI, bool InITBlock) {
623226633Sdim  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
624226633Sdim  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
625226633Sdim  MCInst::iterator I = MI.begin();
626226633Sdim  for (unsigned i = 0; i < NumOps; ++i, ++I) {
627226633Sdim    if (I == MI.end()) break;
628226633Sdim    if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
629226633Sdim      if (i > 0 && OpInfo[i-1].isPredicate()) continue;
630226633Sdim      MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
631226633Sdim      return;
632226633Sdim    }
633226633Sdim  }
634206124Srdivacky
635226633Sdim  MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
636226633Sdim}
637206124Srdivacky
638226633Sdim// Most Thumb instructions don't have explicit predicates in the
639226633Sdim// encoding, but rather get their predicates from IT context.  We need
640226633Sdim// to fix up the predicate operands using this context information as a
641226633Sdim// post-pass.
642226633SdimMCDisassembler::DecodeStatus
643226633SdimThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
644226633Sdim  MCDisassembler::DecodeStatus S = Success;
645206124Srdivacky
646226633Sdim  // A few instructions actually have predicates encoded in them.  Don't
647226633Sdim  // try to overwrite it if we're seeing one of those.
648226633Sdim  switch (MI.getOpcode()) {
649226633Sdim    case ARM::tBcc:
650226633Sdim    case ARM::t2Bcc:
651226633Sdim    case ARM::tCBZ:
652226633Sdim    case ARM::tCBNZ:
653226633Sdim    case ARM::tCPS:
654226633Sdim    case ARM::t2CPS3p:
655226633Sdim    case ARM::t2CPS2p:
656226633Sdim    case ARM::t2CPS1p:
657226633Sdim    case ARM::tMOVSr:
658226633Sdim    case ARM::tSETEND:
659226633Sdim      // Some instructions (mostly conditional branches) are not
660226633Sdim      // allowed in IT blocks.
661239462Sdim      if (ITBlock.instrInITBlock())
662226633Sdim        S = SoftFail;
663226633Sdim      else
664226633Sdim        return Success;
665226633Sdim      break;
666226633Sdim    case ARM::tB:
667226633Sdim    case ARM::t2B:
668226633Sdim    case ARM::t2TBB:
669226633Sdim    case ARM::t2TBH:
670226633Sdim      // Some instructions (mostly unconditional branches) can
671226633Sdim      // only appears at the end of, or outside of, an IT.
672239462Sdim      if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
673226633Sdim        S = SoftFail;
674226633Sdim      break;
675226633Sdim    default:
676226633Sdim      break;
677226633Sdim  }
678226633Sdim
679226633Sdim  // If we're in an IT block, base the predicate on that.  Otherwise,
680226633Sdim  // assume a predicate of AL.
681226633Sdim  unsigned CC;
682239462Sdim  CC = ITBlock.getITCC();
683239462Sdim  if (CC == 0xF)
684226633Sdim    CC = ARMCC::AL;
685239462Sdim  if (ITBlock.instrInITBlock())
686239462Sdim    ITBlock.advanceITState();
687226633Sdim
688226633Sdim  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
689226633Sdim  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
690226633Sdim  MCInst::iterator I = MI.begin();
691226633Sdim  for (unsigned i = 0; i < NumOps; ++i, ++I) {
692226633Sdim    if (I == MI.end()) break;
693226633Sdim    if (OpInfo[i].isPredicate()) {
694226633Sdim      I = MI.insert(I, MCOperand::CreateImm(CC));
695226633Sdim      ++I;
696226633Sdim      if (CC == ARMCC::AL)
697226633Sdim        MI.insert(I, MCOperand::CreateReg(0));
698226633Sdim      else
699226633Sdim        MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
700226633Sdim      return S;
701226633Sdim    }
702226633Sdim  }
703226633Sdim
704226633Sdim  I = MI.insert(I, MCOperand::CreateImm(CC));
705226633Sdim  ++I;
706226633Sdim  if (CC == ARMCC::AL)
707226633Sdim    MI.insert(I, MCOperand::CreateReg(0));
708226633Sdim  else
709226633Sdim    MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
710226633Sdim
711226633Sdim  return S;
712226633Sdim}
713226633Sdim
714226633Sdim// Thumb VFP instructions are a special case.  Because we share their
715226633Sdim// encodings between ARM and Thumb modes, and they are predicable in ARM
716226633Sdim// mode, the auto-generated decoder will give them an (incorrect)
717226633Sdim// predicate operand.  We need to rewrite these operands based on the IT
718226633Sdim// context as a post-pass.
719226633Sdimvoid ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const {
720226633Sdim  unsigned CC;
721239462Sdim  CC = ITBlock.getITCC();
722239462Sdim  if (ITBlock.instrInITBlock())
723239462Sdim    ITBlock.advanceITState();
724226633Sdim
725226633Sdim  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
726226633Sdim  MCInst::iterator I = MI.begin();
727226633Sdim  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
728226633Sdim  for (unsigned i = 0; i < NumOps; ++i, ++I) {
729226633Sdim    if (OpInfo[i].isPredicate() ) {
730226633Sdim      I->setImm(CC);
731226633Sdim      ++I;
732226633Sdim      if (CC == ARMCC::AL)
733226633Sdim        I->setReg(0);
734226633Sdim      else
735226633Sdim        I->setReg(ARM::CPSR);
736226633Sdim      return;
737226633Sdim    }
738226633Sdim  }
739226633Sdim}
740226633Sdim
741226633SdimDecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
742226633Sdim                                               const MemoryObject &Region,
743226633Sdim                                               uint64_t Address,
744226633Sdim                                               raw_ostream &os,
745226633Sdim                                               raw_ostream &cs) const {
746226633Sdim  CommentStream = &cs;
747226633Sdim
748226633Sdim  uint8_t bytes[4];
749226633Sdim
750226633Sdim  assert((STI.getFeatureBits() & ARM::ModeThumb) &&
751226633Sdim         "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
752226633Sdim
753226633Sdim  // We want to read exactly 2 bytes of data.
754226633Sdim  if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1) {
755226633Sdim    Size = 0;
756226633Sdim    return MCDisassembler::Fail;
757226633Sdim  }
758226633Sdim
759226633Sdim  uint16_t insn16 = (bytes[1] << 8) | bytes[0];
760239462Sdim  DecodeStatus result = decodeInstruction(DecoderTableThumb16, MI, insn16,
761239462Sdim                                          Address, this, STI);
762226633Sdim  if (result != MCDisassembler::Fail) {
763226633Sdim    Size = 2;
764226633Sdim    Check(result, AddThumbPredicate(MI));
765226633Sdim    return result;
766226633Sdim  }
767226633Sdim
768226633Sdim  MI.clear();
769239462Sdim  result = decodeInstruction(DecoderTableThumbSBit16, MI, insn16,
770239462Sdim                             Address, this, STI);
771226633Sdim  if (result) {
772226633Sdim    Size = 2;
773239462Sdim    bool InITBlock = ITBlock.instrInITBlock();
774226633Sdim    Check(result, AddThumbPredicate(MI));
775226633Sdim    AddThumb1SBit(MI, InITBlock);
776226633Sdim    return result;
777226633Sdim  }
778226633Sdim
779226633Sdim  MI.clear();
780239462Sdim  result = decodeInstruction(DecoderTableThumb216, MI, insn16,
781239462Sdim                             Address, this, STI);
782226633Sdim  if (result != MCDisassembler::Fail) {
783226633Sdim    Size = 2;
784226633Sdim
785226633Sdim    // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
786226633Sdim    // the Thumb predicate.
787239462Sdim    if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
788226633Sdim      result = MCDisassembler::SoftFail;
789226633Sdim
790226633Sdim    Check(result, AddThumbPredicate(MI));
791226633Sdim
792226633Sdim    // If we find an IT instruction, we need to parse its condition
793226633Sdim    // code and mask operands so that we can apply them correctly
794226633Sdim    // to the subsequent instructions.
795226633Sdim    if (MI.getOpcode() == ARM::t2IT) {
796226633Sdim
797239462Sdim      unsigned Firstcond = MI.getOperand(0).getImm();
798226633Sdim      unsigned Mask = MI.getOperand(1).getImm();
799239462Sdim      ITBlock.setITState(Firstcond, Mask);
800226633Sdim    }
801226633Sdim
802226633Sdim    return result;
803226633Sdim  }
804226633Sdim
805226633Sdim  // We want to read exactly 4 bytes of data.
806226633Sdim  if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
807226633Sdim    Size = 0;
808226633Sdim    return MCDisassembler::Fail;
809226633Sdim  }
810226633Sdim
811226633Sdim  uint32_t insn32 = (bytes[3] <<  8) |
812226633Sdim                    (bytes[2] <<  0) |
813226633Sdim                    (bytes[1] << 24) |
814226633Sdim                    (bytes[0] << 16);
815226633Sdim  MI.clear();
816239462Sdim  result = decodeInstruction(DecoderTableThumb32, MI, insn32, Address,
817239462Sdim                             this, STI);
818226633Sdim  if (result != MCDisassembler::Fail) {
819226633Sdim    Size = 4;
820239462Sdim    bool InITBlock = ITBlock.instrInITBlock();
821226633Sdim    Check(result, AddThumbPredicate(MI));
822226633Sdim    AddThumb1SBit(MI, InITBlock);
823226633Sdim    return result;
824226633Sdim  }
825226633Sdim
826226633Sdim  MI.clear();
827239462Sdim  result = decodeInstruction(DecoderTableThumb232, MI, insn32, Address,
828239462Sdim                             this, STI);
829226633Sdim  if (result != MCDisassembler::Fail) {
830226633Sdim    Size = 4;
831226633Sdim    Check(result, AddThumbPredicate(MI));
832226633Sdim    return result;
833226633Sdim  }
834226633Sdim
835226633Sdim  MI.clear();
836239462Sdim  result = decodeInstruction(DecoderTableVFP32, MI, insn32, Address, this, STI);
837226633Sdim  if (result != MCDisassembler::Fail) {
838226633Sdim    Size = 4;
839226633Sdim    UpdateThumbVFPPredicate(MI);
840226633Sdim    return result;
841226633Sdim  }
842226633Sdim
843226633Sdim  MI.clear();
844239462Sdim  result = decodeInstruction(DecoderTableNEONDup32, MI, insn32, Address,
845239462Sdim                             this, STI);
846226633Sdim  if (result != MCDisassembler::Fail) {
847226633Sdim    Size = 4;
848226633Sdim    Check(result, AddThumbPredicate(MI));
849226633Sdim    return result;
850226633Sdim  }
851226633Sdim
852239462Sdim  if (fieldFromInstruction(insn32, 24, 8) == 0xF9) {
853226633Sdim    MI.clear();
854226633Sdim    uint32_t NEONLdStInsn = insn32;
855226633Sdim    NEONLdStInsn &= 0xF0FFFFFF;
856226633Sdim    NEONLdStInsn |= 0x04000000;
857239462Sdim    result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
858239462Sdim                               Address, this, STI);
859226633Sdim    if (result != MCDisassembler::Fail) {
860226633Sdim      Size = 4;
861226633Sdim      Check(result, AddThumbPredicate(MI));
862226633Sdim      return result;
863226633Sdim    }
864226633Sdim  }
865226633Sdim
866239462Sdim  if (fieldFromInstruction(insn32, 24, 4) == 0xF) {
867226633Sdim    MI.clear();
868226633Sdim    uint32_t NEONDataInsn = insn32;
869226633Sdim    NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
870226633Sdim    NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
871226633Sdim    NEONDataInsn |= 0x12000000; // Set bits 28 and 25
872239462Sdim    result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
873239462Sdim                               Address, this, STI);
874226633Sdim    if (result != MCDisassembler::Fail) {
875226633Sdim      Size = 4;
876226633Sdim      Check(result, AddThumbPredicate(MI));
877226633Sdim      return result;
878226633Sdim    }
879226633Sdim  }
880226633Sdim
881226633Sdim  Size = 0;
882226633Sdim  return MCDisassembler::Fail;
883226633Sdim}
884226633Sdim
885226633Sdim
886226633Sdimextern "C" void LLVMInitializeARMDisassembler() {
887226633Sdim  TargetRegistry::RegisterMCDisassembler(TheARMTarget,
888226633Sdim                                         createARMDisassembler);
889226633Sdim  TargetRegistry::RegisterMCDisassembler(TheThumbTarget,
890226633Sdim                                         createThumbDisassembler);
891226633Sdim}
892226633Sdim
893234353Sdimstatic const uint16_t GPRDecoderTable[] = {
894226633Sdim  ARM::R0, ARM::R1, ARM::R2, ARM::R3,
895226633Sdim  ARM::R4, ARM::R5, ARM::R6, ARM::R7,
896226633Sdim  ARM::R8, ARM::R9, ARM::R10, ARM::R11,
897226633Sdim  ARM::R12, ARM::SP, ARM::LR, ARM::PC
898226633Sdim};
899226633Sdim
900234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
901226633Sdim                                   uint64_t Address, const void *Decoder) {
902226633Sdim  if (RegNo > 15)
903226633Sdim    return MCDisassembler::Fail;
904226633Sdim
905226633Sdim  unsigned Register = GPRDecoderTable[RegNo];
906226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
907226633Sdim  return MCDisassembler::Success;
908226633Sdim}
909226633Sdim
910226633Sdimstatic DecodeStatus
911234353SdimDecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
912226633Sdim                           uint64_t Address, const void *Decoder) {
913234353Sdim  DecodeStatus S = MCDisassembler::Success;
914234353Sdim
915234353Sdim  if (RegNo == 15)
916234353Sdim    S = MCDisassembler::SoftFail;
917234353Sdim
918234353Sdim  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
919234353Sdim
920234353Sdim  return S;
921226633Sdim}
922226633Sdim
923234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
924226633Sdim                                   uint64_t Address, const void *Decoder) {
925226633Sdim  if (RegNo > 7)
926226633Sdim    return MCDisassembler::Fail;
927226633Sdim  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
928226633Sdim}
929226633Sdim
930234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
931226633Sdim                                   uint64_t Address, const void *Decoder) {
932226633Sdim  unsigned Register = 0;
933226633Sdim  switch (RegNo) {
934226633Sdim    case 0:
935226633Sdim      Register = ARM::R0;
936206124Srdivacky      break;
937226633Sdim    case 1:
938226633Sdim      Register = ARM::R1;
939226633Sdim      break;
940226633Sdim    case 2:
941226633Sdim      Register = ARM::R2;
942226633Sdim      break;
943206124Srdivacky    case 3:
944226633Sdim      Register = ARM::R3;
945206124Srdivacky      break;
946226633Sdim    case 9:
947226633Sdim      Register = ARM::R9;
948226633Sdim      break;
949226633Sdim    case 12:
950226633Sdim      Register = ARM::R12;
951226633Sdim      break;
952206124Srdivacky    default:
953226633Sdim      return MCDisassembler::Fail;
954206124Srdivacky    }
955226633Sdim
956226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
957226633Sdim  return MCDisassembler::Success;
958226633Sdim}
959226633Sdim
960234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
961226633Sdim                                   uint64_t Address, const void *Decoder) {
962226633Sdim  if (RegNo == 13 || RegNo == 15) return MCDisassembler::Fail;
963226633Sdim  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
964226633Sdim}
965226633Sdim
966234353Sdimstatic const uint16_t SPRDecoderTable[] = {
967226633Sdim     ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
968226633Sdim     ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
969226633Sdim     ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
970226633Sdim    ARM::S12, ARM::S13, ARM::S14, ARM::S15,
971226633Sdim    ARM::S16, ARM::S17, ARM::S18, ARM::S19,
972226633Sdim    ARM::S20, ARM::S21, ARM::S22, ARM::S23,
973226633Sdim    ARM::S24, ARM::S25, ARM::S26, ARM::S27,
974226633Sdim    ARM::S28, ARM::S29, ARM::S30, ARM::S31
975226633Sdim};
976226633Sdim
977234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
978226633Sdim                                   uint64_t Address, const void *Decoder) {
979226633Sdim  if (RegNo > 31)
980226633Sdim    return MCDisassembler::Fail;
981226633Sdim
982226633Sdim  unsigned Register = SPRDecoderTable[RegNo];
983226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
984226633Sdim  return MCDisassembler::Success;
985226633Sdim}
986226633Sdim
987234353Sdimstatic const uint16_t DPRDecoderTable[] = {
988226633Sdim     ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
989226633Sdim     ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
990226633Sdim     ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
991226633Sdim    ARM::D12, ARM::D13, ARM::D14, ARM::D15,
992226633Sdim    ARM::D16, ARM::D17, ARM::D18, ARM::D19,
993226633Sdim    ARM::D20, ARM::D21, ARM::D22, ARM::D23,
994226633Sdim    ARM::D24, ARM::D25, ARM::D26, ARM::D27,
995226633Sdim    ARM::D28, ARM::D29, ARM::D30, ARM::D31
996226633Sdim};
997226633Sdim
998234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
999226633Sdim                                   uint64_t Address, const void *Decoder) {
1000226633Sdim  if (RegNo > 31)
1001226633Sdim    return MCDisassembler::Fail;
1002226633Sdim
1003226633Sdim  unsigned Register = DPRDecoderTable[RegNo];
1004226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
1005226633Sdim  return MCDisassembler::Success;
1006226633Sdim}
1007226633Sdim
1008234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1009226633Sdim                                   uint64_t Address, const void *Decoder) {
1010226633Sdim  if (RegNo > 7)
1011226633Sdim    return MCDisassembler::Fail;
1012226633Sdim  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
1013226633Sdim}
1014226633Sdim
1015226633Sdimstatic DecodeStatus
1016234353SdimDecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
1017226633Sdim                            uint64_t Address, const void *Decoder) {
1018226633Sdim  if (RegNo > 15)
1019226633Sdim    return MCDisassembler::Fail;
1020226633Sdim  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
1021226633Sdim}
1022226633Sdim
1023234353Sdimstatic const uint16_t QPRDecoderTable[] = {
1024226633Sdim     ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
1025226633Sdim     ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
1026226633Sdim     ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
1027226633Sdim    ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
1028226633Sdim};
1029226633Sdim
1030226633Sdim
1031234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
1032226633Sdim                                   uint64_t Address, const void *Decoder) {
1033226633Sdim  if (RegNo > 31)
1034226633Sdim    return MCDisassembler::Fail;
1035226633Sdim  RegNo >>= 1;
1036226633Sdim
1037226633Sdim  unsigned Register = QPRDecoderTable[RegNo];
1038226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
1039226633Sdim  return MCDisassembler::Success;
1040226633Sdim}
1041226633Sdim
1042234353Sdimstatic const uint16_t DPairDecoderTable[] = {
1043234353Sdim  ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
1044234353Sdim  ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
1045234353Sdim  ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
1046234353Sdim  ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
1047234353Sdim  ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
1048234353Sdim  ARM::Q15
1049234353Sdim};
1050234353Sdim
1051234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
1052234353Sdim                                   uint64_t Address, const void *Decoder) {
1053234353Sdim  if (RegNo > 30)
1054234353Sdim    return MCDisassembler::Fail;
1055234353Sdim
1056234353Sdim  unsigned Register = DPairDecoderTable[RegNo];
1057234353Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
1058234353Sdim  return MCDisassembler::Success;
1059234353Sdim}
1060234353Sdim
1061234353Sdimstatic const uint16_t DPairSpacedDecoderTable[] = {
1062234353Sdim  ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
1063234353Sdim  ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
1064234353Sdim  ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
1065234353Sdim  ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
1066234353Sdim  ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
1067234353Sdim  ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
1068234353Sdim  ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
1069234353Sdim  ARM::D28_D30, ARM::D29_D31
1070234353Sdim};
1071234353Sdim
1072234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
1073234353Sdim                                                   unsigned RegNo,
1074234353Sdim                                                   uint64_t Address,
1075234353Sdim                                                   const void *Decoder) {
1076234353Sdim  if (RegNo > 29)
1077234353Sdim    return MCDisassembler::Fail;
1078234353Sdim
1079234353Sdim  unsigned Register = DPairSpacedDecoderTable[RegNo];
1080234353Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
1081234353Sdim  return MCDisassembler::Success;
1082234353Sdim}
1083234353Sdim
1084234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
1085226633Sdim                               uint64_t Address, const void *Decoder) {
1086226633Sdim  if (Val == 0xF) return MCDisassembler::Fail;
1087226633Sdim  // AL predicate is not allowed on Thumb1 branches.
1088226633Sdim  if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
1089226633Sdim    return MCDisassembler::Fail;
1090226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
1091226633Sdim  if (Val == ARMCC::AL) {
1092226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
1093226633Sdim  } else
1094226633Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1095226633Sdim  return MCDisassembler::Success;
1096226633Sdim}
1097226633Sdim
1098234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
1099226633Sdim                               uint64_t Address, const void *Decoder) {
1100226633Sdim  if (Val)
1101226633Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1102226633Sdim  else
1103226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
1104226633Sdim  return MCDisassembler::Success;
1105226633Sdim}
1106226633Sdim
1107234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val,
1108226633Sdim                               uint64_t Address, const void *Decoder) {
1109226633Sdim  uint32_t imm = Val & 0xFF;
1110226633Sdim  uint32_t rot = (Val & 0xF00) >> 7;
1111226633Sdim  uint32_t rot_imm = (imm >> rot) | (imm << ((32-rot) & 0x1F));
1112226633Sdim  Inst.addOperand(MCOperand::CreateImm(rot_imm));
1113226633Sdim  return MCDisassembler::Success;
1114226633Sdim}
1115226633Sdim
1116234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
1117226633Sdim                               uint64_t Address, const void *Decoder) {
1118226633Sdim  DecodeStatus S = MCDisassembler::Success;
1119226633Sdim
1120239462Sdim  unsigned Rm = fieldFromInstruction(Val, 0, 4);
1121239462Sdim  unsigned type = fieldFromInstruction(Val, 5, 2);
1122239462Sdim  unsigned imm = fieldFromInstruction(Val, 7, 5);
1123226633Sdim
1124226633Sdim  // Register-immediate
1125226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1126226633Sdim    return MCDisassembler::Fail;
1127226633Sdim
1128226633Sdim  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1129226633Sdim  switch (type) {
1130226633Sdim    case 0:
1131226633Sdim      Shift = ARM_AM::lsl;
1132226633Sdim      break;
1133226633Sdim    case 1:
1134226633Sdim      Shift = ARM_AM::lsr;
1135226633Sdim      break;
1136226633Sdim    case 2:
1137226633Sdim      Shift = ARM_AM::asr;
1138226633Sdim      break;
1139226633Sdim    case 3:
1140226633Sdim      Shift = ARM_AM::ror;
1141226633Sdim      break;
1142206124Srdivacky  }
1143206124Srdivacky
1144226633Sdim  if (Shift == ARM_AM::ror && imm == 0)
1145226633Sdim    Shift = ARM_AM::rrx;
1146226633Sdim
1147226633Sdim  unsigned Op = Shift | (imm << 3);
1148226633Sdim  Inst.addOperand(MCOperand::CreateImm(Op));
1149226633Sdim
1150226633Sdim  return S;
1151226633Sdim}
1152226633Sdim
1153234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
1154226633Sdim                               uint64_t Address, const void *Decoder) {
1155226633Sdim  DecodeStatus S = MCDisassembler::Success;
1156226633Sdim
1157239462Sdim  unsigned Rm = fieldFromInstruction(Val, 0, 4);
1158239462Sdim  unsigned type = fieldFromInstruction(Val, 5, 2);
1159239462Sdim  unsigned Rs = fieldFromInstruction(Val, 8, 4);
1160226633Sdim
1161226633Sdim  // Register-register
1162226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1163226633Sdim    return MCDisassembler::Fail;
1164226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
1165226633Sdim    return MCDisassembler::Fail;
1166226633Sdim
1167226633Sdim  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1168226633Sdim  switch (type) {
1169226633Sdim    case 0:
1170226633Sdim      Shift = ARM_AM::lsl;
1171206124Srdivacky      break;
1172226633Sdim    case 1:
1173226633Sdim      Shift = ARM_AM::lsr;
1174206124Srdivacky      break;
1175226633Sdim    case 2:
1176226633Sdim      Shift = ARM_AM::asr;
1177206124Srdivacky      break;
1178226633Sdim    case 3:
1179226633Sdim      Shift = ARM_AM::ror;
1180226633Sdim      break;
1181226633Sdim  }
1182226633Sdim
1183226633Sdim  Inst.addOperand(MCOperand::CreateImm(Shift));
1184226633Sdim
1185226633Sdim  return S;
1186226633Sdim}
1187226633Sdim
1188234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
1189226633Sdim                                 uint64_t Address, const void *Decoder) {
1190226633Sdim  DecodeStatus S = MCDisassembler::Success;
1191226633Sdim
1192226633Sdim  bool writebackLoad = false;
1193226633Sdim  unsigned writebackReg = 0;
1194226633Sdim  switch (Inst.getOpcode()) {
1195206124Srdivacky    default:
1196226633Sdim      break;
1197226633Sdim    case ARM::LDMIA_UPD:
1198226633Sdim    case ARM::LDMDB_UPD:
1199226633Sdim    case ARM::LDMIB_UPD:
1200226633Sdim    case ARM::LDMDA_UPD:
1201226633Sdim    case ARM::t2LDMIA_UPD:
1202226633Sdim    case ARM::t2LDMDB_UPD:
1203226633Sdim      writebackLoad = true;
1204226633Sdim      writebackReg = Inst.getOperand(0).getReg();
1205226633Sdim      break;
1206226633Sdim  }
1207226633Sdim
1208226633Sdim  // Empty register lists are not allowed.
1209226633Sdim  if (CountPopulation_32(Val) == 0) return MCDisassembler::Fail;
1210226633Sdim  for (unsigned i = 0; i < 16; ++i) {
1211226633Sdim    if (Val & (1 << i)) {
1212226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
1213226633Sdim        return MCDisassembler::Fail;
1214226633Sdim      // Writeback not allowed if Rn is in the target list.
1215226633Sdim      if (writebackLoad && writebackReg == Inst.end()[-1].getReg())
1216226633Sdim        Check(S, MCDisassembler::SoftFail);
1217206124Srdivacky    }
1218206124Srdivacky  }
1219206124Srdivacky
1220226633Sdim  return S;
1221226633Sdim}
1222226633Sdim
1223234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
1224226633Sdim                                 uint64_t Address, const void *Decoder) {
1225226633Sdim  DecodeStatus S = MCDisassembler::Success;
1226226633Sdim
1227239462Sdim  unsigned Vd = fieldFromInstruction(Val, 8, 5);
1228239462Sdim  unsigned regs = fieldFromInstruction(Val, 0, 8);
1229226633Sdim
1230226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
1231226633Sdim    return MCDisassembler::Fail;
1232226633Sdim  for (unsigned i = 0; i < (regs - 1); ++i) {
1233226633Sdim    if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1234226633Sdim      return MCDisassembler::Fail;
1235226633Sdim  }
1236226633Sdim
1237226633Sdim  return S;
1238226633Sdim}
1239226633Sdim
1240234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
1241226633Sdim                                 uint64_t Address, const void *Decoder) {
1242226633Sdim  DecodeStatus S = MCDisassembler::Success;
1243226633Sdim
1244239462Sdim  unsigned Vd = fieldFromInstruction(Val, 8, 5);
1245239462Sdim  unsigned regs = fieldFromInstruction(Val, 0, 8);
1246226633Sdim
1247239462Sdim  regs = regs >> 1;
1248239462Sdim
1249226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
1250226633Sdim      return MCDisassembler::Fail;
1251226633Sdim  for (unsigned i = 0; i < (regs - 1); ++i) {
1252226633Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1253226633Sdim      return MCDisassembler::Fail;
1254226633Sdim  }
1255226633Sdim
1256226633Sdim  return S;
1257226633Sdim}
1258226633Sdim
1259234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
1260226633Sdim                                      uint64_t Address, const void *Decoder) {
1261226633Sdim  // This operand encodes a mask of contiguous zeros between a specified MSB
1262226633Sdim  // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
1263226633Sdim  // the mask of all bits LSB-and-lower, and then xor them to create
1264226633Sdim  // the mask of that's all ones on [msb, lsb].  Finally we not it to
1265226633Sdim  // create the final mask.
1266239462Sdim  unsigned msb = fieldFromInstruction(Val, 5, 5);
1267239462Sdim  unsigned lsb = fieldFromInstruction(Val, 0, 5);
1268226633Sdim
1269226633Sdim  DecodeStatus S = MCDisassembler::Success;
1270249423Sdim  if (lsb > msb) {
1271249423Sdim    Check(S, MCDisassembler::SoftFail);
1272249423Sdim    // The check above will cause the warning for the "potentially undefined
1273249423Sdim    // instruction encoding" but we can't build a bad MCOperand value here
1274249423Sdim    // with a lsb > msb or else printing the MCInst will cause a crash.
1275249423Sdim    lsb = msb;
1276249423Sdim  }
1277226633Sdim
1278226633Sdim  uint32_t msb_mask = 0xFFFFFFFF;
1279226633Sdim  if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
1280226633Sdim  uint32_t lsb_mask = (1U << lsb) - 1;
1281226633Sdim
1282226633Sdim  Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask)));
1283226633Sdim  return S;
1284226633Sdim}
1285226633Sdim
1286234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
1287226633Sdim                                  uint64_t Address, const void *Decoder) {
1288226633Sdim  DecodeStatus S = MCDisassembler::Success;
1289226633Sdim
1290239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1291239462Sdim  unsigned CRd = fieldFromInstruction(Insn, 12, 4);
1292239462Sdim  unsigned coproc = fieldFromInstruction(Insn, 8, 4);
1293239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 8);
1294239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1295239462Sdim  unsigned U = fieldFromInstruction(Insn, 23, 1);
1296226633Sdim
1297226633Sdim  switch (Inst.getOpcode()) {
1298226633Sdim    case ARM::LDC_OFFSET:
1299226633Sdim    case ARM::LDC_PRE:
1300226633Sdim    case ARM::LDC_POST:
1301226633Sdim    case ARM::LDC_OPTION:
1302226633Sdim    case ARM::LDCL_OFFSET:
1303226633Sdim    case ARM::LDCL_PRE:
1304226633Sdim    case ARM::LDCL_POST:
1305226633Sdim    case ARM::LDCL_OPTION:
1306226633Sdim    case ARM::STC_OFFSET:
1307226633Sdim    case ARM::STC_PRE:
1308226633Sdim    case ARM::STC_POST:
1309226633Sdim    case ARM::STC_OPTION:
1310226633Sdim    case ARM::STCL_OFFSET:
1311226633Sdim    case ARM::STCL_PRE:
1312226633Sdim    case ARM::STCL_POST:
1313226633Sdim    case ARM::STCL_OPTION:
1314226633Sdim    case ARM::t2LDC_OFFSET:
1315226633Sdim    case ARM::t2LDC_PRE:
1316226633Sdim    case ARM::t2LDC_POST:
1317226633Sdim    case ARM::t2LDC_OPTION:
1318226633Sdim    case ARM::t2LDCL_OFFSET:
1319226633Sdim    case ARM::t2LDCL_PRE:
1320226633Sdim    case ARM::t2LDCL_POST:
1321226633Sdim    case ARM::t2LDCL_OPTION:
1322226633Sdim    case ARM::t2STC_OFFSET:
1323226633Sdim    case ARM::t2STC_PRE:
1324226633Sdim    case ARM::t2STC_POST:
1325226633Sdim    case ARM::t2STC_OPTION:
1326226633Sdim    case ARM::t2STCL_OFFSET:
1327226633Sdim    case ARM::t2STCL_PRE:
1328226633Sdim    case ARM::t2STCL_POST:
1329226633Sdim    case ARM::t2STCL_OPTION:
1330226633Sdim      if (coproc == 0xA || coproc == 0xB)
1331226633Sdim        return MCDisassembler::Fail;
1332206124Srdivacky      break;
1333226633Sdim    default:
1334226633Sdim      break;
1335226633Sdim  }
1336226633Sdim
1337226633Sdim  Inst.addOperand(MCOperand::CreateImm(coproc));
1338226633Sdim  Inst.addOperand(MCOperand::CreateImm(CRd));
1339226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1340226633Sdim    return MCDisassembler::Fail;
1341226633Sdim
1342226633Sdim  switch (Inst.getOpcode()) {
1343226633Sdim    case ARM::t2LDC2_OFFSET:
1344226633Sdim    case ARM::t2LDC2L_OFFSET:
1345226633Sdim    case ARM::t2LDC2_PRE:
1346226633Sdim    case ARM::t2LDC2L_PRE:
1347226633Sdim    case ARM::t2STC2_OFFSET:
1348226633Sdim    case ARM::t2STC2L_OFFSET:
1349226633Sdim    case ARM::t2STC2_PRE:
1350226633Sdim    case ARM::t2STC2L_PRE:
1351226633Sdim    case ARM::LDC2_OFFSET:
1352226633Sdim    case ARM::LDC2L_OFFSET:
1353226633Sdim    case ARM::LDC2_PRE:
1354226633Sdim    case ARM::LDC2L_PRE:
1355226633Sdim    case ARM::STC2_OFFSET:
1356226633Sdim    case ARM::STC2L_OFFSET:
1357226633Sdim    case ARM::STC2_PRE:
1358226633Sdim    case ARM::STC2L_PRE:
1359226633Sdim    case ARM::t2LDC_OFFSET:
1360226633Sdim    case ARM::t2LDCL_OFFSET:
1361226633Sdim    case ARM::t2LDC_PRE:
1362226633Sdim    case ARM::t2LDCL_PRE:
1363226633Sdim    case ARM::t2STC_OFFSET:
1364226633Sdim    case ARM::t2STCL_OFFSET:
1365226633Sdim    case ARM::t2STC_PRE:
1366226633Sdim    case ARM::t2STCL_PRE:
1367226633Sdim    case ARM::LDC_OFFSET:
1368226633Sdim    case ARM::LDCL_OFFSET:
1369226633Sdim    case ARM::LDC_PRE:
1370226633Sdim    case ARM::LDCL_PRE:
1371226633Sdim    case ARM::STC_OFFSET:
1372226633Sdim    case ARM::STCL_OFFSET:
1373226633Sdim    case ARM::STC_PRE:
1374226633Sdim    case ARM::STCL_PRE:
1375226633Sdim      imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
1376226633Sdim      Inst.addOperand(MCOperand::CreateImm(imm));
1377226633Sdim      break;
1378226633Sdim    case ARM::t2LDC2_POST:
1379226633Sdim    case ARM::t2LDC2L_POST:
1380226633Sdim    case ARM::t2STC2_POST:
1381226633Sdim    case ARM::t2STC2L_POST:
1382226633Sdim    case ARM::LDC2_POST:
1383226633Sdim    case ARM::LDC2L_POST:
1384226633Sdim    case ARM::STC2_POST:
1385226633Sdim    case ARM::STC2L_POST:
1386226633Sdim    case ARM::t2LDC_POST:
1387226633Sdim    case ARM::t2LDCL_POST:
1388226633Sdim    case ARM::t2STC_POST:
1389226633Sdim    case ARM::t2STCL_POST:
1390226633Sdim    case ARM::LDC_POST:
1391226633Sdim    case ARM::LDCL_POST:
1392226633Sdim    case ARM::STC_POST:
1393226633Sdim    case ARM::STCL_POST:
1394226633Sdim      imm |= U << 8;
1395226633Sdim      // fall through.
1396226633Sdim    default:
1397226633Sdim      // The 'option' variant doesn't encode 'U' in the immediate since
1398226633Sdim      // the immediate is unsigned [0,255].
1399226633Sdim      Inst.addOperand(MCOperand::CreateImm(imm));
1400226633Sdim      break;
1401226633Sdim  }
1402226633Sdim
1403226633Sdim  switch (Inst.getOpcode()) {
1404226633Sdim    case ARM::LDC_OFFSET:
1405226633Sdim    case ARM::LDC_PRE:
1406226633Sdim    case ARM::LDC_POST:
1407226633Sdim    case ARM::LDC_OPTION:
1408226633Sdim    case ARM::LDCL_OFFSET:
1409226633Sdim    case ARM::LDCL_PRE:
1410226633Sdim    case ARM::LDCL_POST:
1411226633Sdim    case ARM::LDCL_OPTION:
1412226633Sdim    case ARM::STC_OFFSET:
1413226633Sdim    case ARM::STC_PRE:
1414226633Sdim    case ARM::STC_POST:
1415226633Sdim    case ARM::STC_OPTION:
1416226633Sdim    case ARM::STCL_OFFSET:
1417226633Sdim    case ARM::STCL_PRE:
1418226633Sdim    case ARM::STCL_POST:
1419226633Sdim    case ARM::STCL_OPTION:
1420226633Sdim      if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1421226633Sdim        return MCDisassembler::Fail;
1422226633Sdim      break;
1423226633Sdim    default:
1424226633Sdim      break;
1425226633Sdim  }
1426226633Sdim
1427226633Sdim  return S;
1428226633Sdim}
1429226633Sdim
1430226633Sdimstatic DecodeStatus
1431234353SdimDecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn,
1432226633Sdim                              uint64_t Address, const void *Decoder) {
1433226633Sdim  DecodeStatus S = MCDisassembler::Success;
1434226633Sdim
1435239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1436239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1437239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1438239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
1439239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1440239462Sdim  unsigned reg = fieldFromInstruction(Insn, 25, 1);
1441239462Sdim  unsigned P = fieldFromInstruction(Insn, 24, 1);
1442239462Sdim  unsigned W = fieldFromInstruction(Insn, 21, 1);
1443226633Sdim
1444226633Sdim  // On stores, the writeback operand precedes Rt.
1445226633Sdim  switch (Inst.getOpcode()) {
1446226633Sdim    case ARM::STR_POST_IMM:
1447226633Sdim    case ARM::STR_POST_REG:
1448226633Sdim    case ARM::STRB_POST_IMM:
1449226633Sdim    case ARM::STRB_POST_REG:
1450226633Sdim    case ARM::STRT_POST_REG:
1451226633Sdim    case ARM::STRT_POST_IMM:
1452226633Sdim    case ARM::STRBT_POST_REG:
1453226633Sdim    case ARM::STRBT_POST_IMM:
1454226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1455226633Sdim        return MCDisassembler::Fail;
1456226633Sdim      break;
1457226633Sdim    default:
1458226633Sdim      break;
1459226633Sdim  }
1460226633Sdim
1461226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1462226633Sdim    return MCDisassembler::Fail;
1463226633Sdim
1464226633Sdim  // On loads, the writeback operand comes after Rt.
1465226633Sdim  switch (Inst.getOpcode()) {
1466226633Sdim    case ARM::LDR_POST_IMM:
1467226633Sdim    case ARM::LDR_POST_REG:
1468226633Sdim    case ARM::LDRB_POST_IMM:
1469226633Sdim    case ARM::LDRB_POST_REG:
1470226633Sdim    case ARM::LDRBT_POST_REG:
1471226633Sdim    case ARM::LDRBT_POST_IMM:
1472226633Sdim    case ARM::LDRT_POST_REG:
1473226633Sdim    case ARM::LDRT_POST_IMM:
1474226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1475226633Sdim        return MCDisassembler::Fail;
1476226633Sdim      break;
1477226633Sdim    default:
1478226633Sdim      break;
1479226633Sdim  }
1480226633Sdim
1481226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1482226633Sdim    return MCDisassembler::Fail;
1483226633Sdim
1484226633Sdim  ARM_AM::AddrOpc Op = ARM_AM::add;
1485239462Sdim  if (!fieldFromInstruction(Insn, 23, 1))
1486226633Sdim    Op = ARM_AM::sub;
1487226633Sdim
1488226633Sdim  bool writeback = (P == 0) || (W == 1);
1489226633Sdim  unsigned idx_mode = 0;
1490226633Sdim  if (P && writeback)
1491226633Sdim    idx_mode = ARMII::IndexModePre;
1492226633Sdim  else if (!P && writeback)
1493226633Sdim    idx_mode = ARMII::IndexModePost;
1494226633Sdim
1495226633Sdim  if (writeback && (Rn == 15 || Rn == Rt))
1496226633Sdim    S = MCDisassembler::SoftFail; // UNPREDICTABLE
1497226633Sdim
1498226633Sdim  if (reg) {
1499226633Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1500226633Sdim      return MCDisassembler::Fail;
1501226633Sdim    ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
1502239462Sdim    switch( fieldFromInstruction(Insn, 5, 2)) {
1503226633Sdim      case 0:
1504226633Sdim        Opc = ARM_AM::lsl;
1505226633Sdim        break;
1506226633Sdim      case 1:
1507226633Sdim        Opc = ARM_AM::lsr;
1508226633Sdim        break;
1509226633Sdim      case 2:
1510226633Sdim        Opc = ARM_AM::asr;
1511226633Sdim        break;
1512226633Sdim      case 3:
1513226633Sdim        Opc = ARM_AM::ror;
1514226633Sdim        break;
1515206124Srdivacky      default:
1516226633Sdim        return MCDisassembler::Fail;
1517226633Sdim    }
1518239462Sdim    unsigned amt = fieldFromInstruction(Insn, 7, 5);
1519243830Sdim    if (Opc == ARM_AM::ror && amt == 0)
1520243830Sdim      Opc = ARM_AM::rrx;
1521226633Sdim    unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
1522226633Sdim
1523226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
1524226633Sdim  } else {
1525226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
1526226633Sdim    unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
1527226633Sdim    Inst.addOperand(MCOperand::CreateImm(tmp));
1528226633Sdim  }
1529226633Sdim
1530226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1531226633Sdim    return MCDisassembler::Fail;
1532226633Sdim
1533226633Sdim  return S;
1534226633Sdim}
1535226633Sdim
1536234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
1537226633Sdim                                  uint64_t Address, const void *Decoder) {
1538226633Sdim  DecodeStatus S = MCDisassembler::Success;
1539226633Sdim
1540239462Sdim  unsigned Rn = fieldFromInstruction(Val, 13, 4);
1541239462Sdim  unsigned Rm = fieldFromInstruction(Val,  0, 4);
1542239462Sdim  unsigned type = fieldFromInstruction(Val, 5, 2);
1543239462Sdim  unsigned imm = fieldFromInstruction(Val, 7, 5);
1544239462Sdim  unsigned U = fieldFromInstruction(Val, 12, 1);
1545226633Sdim
1546226633Sdim  ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
1547226633Sdim  switch (type) {
1548226633Sdim    case 0:
1549226633Sdim      ShOp = ARM_AM::lsl;
1550206124Srdivacky      break;
1551226633Sdim    case 1:
1552226633Sdim      ShOp = ARM_AM::lsr;
1553226633Sdim      break;
1554226633Sdim    case 2:
1555226633Sdim      ShOp = ARM_AM::asr;
1556226633Sdim      break;
1557226633Sdim    case 3:
1558226633Sdim      ShOp = ARM_AM::ror;
1559226633Sdim      break;
1560226633Sdim  }
1561226633Sdim
1562243830Sdim  if (ShOp == ARM_AM::ror && imm == 0)
1563243830Sdim    ShOp = ARM_AM::rrx;
1564243830Sdim
1565226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1566226633Sdim    return MCDisassembler::Fail;
1567226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1568226633Sdim    return MCDisassembler::Fail;
1569226633Sdim  unsigned shift;
1570226633Sdim  if (U)
1571226633Sdim    shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
1572226633Sdim  else
1573226633Sdim    shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
1574226633Sdim  Inst.addOperand(MCOperand::CreateImm(shift));
1575226633Sdim
1576226633Sdim  return S;
1577226633Sdim}
1578226633Sdim
1579226633Sdimstatic DecodeStatus
1580234353SdimDecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
1581226633Sdim                           uint64_t Address, const void *Decoder) {
1582226633Sdim  DecodeStatus S = MCDisassembler::Success;
1583226633Sdim
1584239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1585239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1586239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1587239462Sdim  unsigned type = fieldFromInstruction(Insn, 22, 1);
1588239462Sdim  unsigned imm = fieldFromInstruction(Insn, 8, 4);
1589239462Sdim  unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
1590239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1591239462Sdim  unsigned W = fieldFromInstruction(Insn, 21, 1);
1592239462Sdim  unsigned P = fieldFromInstruction(Insn, 24, 1);
1593234353Sdim  unsigned Rt2 = Rt + 1;
1594226633Sdim
1595226633Sdim  bool writeback = (W == 1) | (P == 0);
1596226633Sdim
1597226633Sdim  // For {LD,ST}RD, Rt must be even, else undefined.
1598226633Sdim  switch (Inst.getOpcode()) {
1599226633Sdim    case ARM::STRD:
1600226633Sdim    case ARM::STRD_PRE:
1601226633Sdim    case ARM::STRD_POST:
1602226633Sdim    case ARM::LDRD:
1603226633Sdim    case ARM::LDRD_PRE:
1604226633Sdim    case ARM::LDRD_POST:
1605234353Sdim      if (Rt & 0x1) S = MCDisassembler::SoftFail;
1606226633Sdim      break;
1607226633Sdim    default:
1608226633Sdim      break;
1609226633Sdim  }
1610234353Sdim  switch (Inst.getOpcode()) {
1611234353Sdim    case ARM::STRD:
1612234353Sdim    case ARM::STRD_PRE:
1613234353Sdim    case ARM::STRD_POST:
1614234353Sdim      if (P == 0 && W == 1)
1615234353Sdim        S = MCDisassembler::SoftFail;
1616234353Sdim
1617234353Sdim      if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
1618234353Sdim        S = MCDisassembler::SoftFail;
1619234353Sdim      if (type && Rm == 15)
1620234353Sdim        S = MCDisassembler::SoftFail;
1621234353Sdim      if (Rt2 == 15)
1622234353Sdim        S = MCDisassembler::SoftFail;
1623239462Sdim      if (!type && fieldFromInstruction(Insn, 8, 4))
1624234353Sdim        S = MCDisassembler::SoftFail;
1625234353Sdim      break;
1626234353Sdim    case ARM::STRH:
1627234353Sdim    case ARM::STRH_PRE:
1628234353Sdim    case ARM::STRH_POST:
1629234353Sdim      if (Rt == 15)
1630234353Sdim        S = MCDisassembler::SoftFail;
1631234353Sdim      if (writeback && (Rn == 15 || Rn == Rt))
1632234353Sdim        S = MCDisassembler::SoftFail;
1633234353Sdim      if (!type && Rm == 15)
1634234353Sdim        S = MCDisassembler::SoftFail;
1635234353Sdim      break;
1636234353Sdim    case ARM::LDRD:
1637234353Sdim    case ARM::LDRD_PRE:
1638234353Sdim    case ARM::LDRD_POST:
1639234353Sdim      if (type && Rn == 15){
1640234353Sdim        if (Rt2 == 15)
1641234353Sdim          S = MCDisassembler::SoftFail;
1642234353Sdim        break;
1643234353Sdim      }
1644234353Sdim      if (P == 0 && W == 1)
1645234353Sdim        S = MCDisassembler::SoftFail;
1646234353Sdim      if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
1647234353Sdim        S = MCDisassembler::SoftFail;
1648234353Sdim      if (!type && writeback && Rn == 15)
1649234353Sdim        S = MCDisassembler::SoftFail;
1650234353Sdim      if (writeback && (Rn == Rt || Rn == Rt2))
1651234353Sdim        S = MCDisassembler::SoftFail;
1652234353Sdim      break;
1653234353Sdim    case ARM::LDRH:
1654234353Sdim    case ARM::LDRH_PRE:
1655234353Sdim    case ARM::LDRH_POST:
1656234353Sdim      if (type && Rn == 15){
1657234353Sdim        if (Rt == 15)
1658234353Sdim          S = MCDisassembler::SoftFail;
1659234353Sdim        break;
1660234353Sdim      }
1661234353Sdim      if (Rt == 15)
1662234353Sdim        S = MCDisassembler::SoftFail;
1663234353Sdim      if (!type && Rm == 15)
1664234353Sdim        S = MCDisassembler::SoftFail;
1665234353Sdim      if (!type && writeback && (Rn == 15 || Rn == Rt))
1666234353Sdim        S = MCDisassembler::SoftFail;
1667234353Sdim      break;
1668234353Sdim    case ARM::LDRSH:
1669234353Sdim    case ARM::LDRSH_PRE:
1670234353Sdim    case ARM::LDRSH_POST:
1671234353Sdim    case ARM::LDRSB:
1672234353Sdim    case ARM::LDRSB_PRE:
1673234353Sdim    case ARM::LDRSB_POST:
1674234353Sdim      if (type && Rn == 15){
1675234353Sdim        if (Rt == 15)
1676234353Sdim          S = MCDisassembler::SoftFail;
1677234353Sdim        break;
1678234353Sdim      }
1679234353Sdim      if (type && (Rt == 15 || (writeback && Rn == Rt)))
1680234353Sdim        S = MCDisassembler::SoftFail;
1681234353Sdim      if (!type && (Rt == 15 || Rm == 15))
1682234353Sdim        S = MCDisassembler::SoftFail;
1683234353Sdim      if (!type && writeback && (Rn == 15 || Rn == Rt))
1684234353Sdim        S = MCDisassembler::SoftFail;
1685234353Sdim      break;
1686234353Sdim    default:
1687234353Sdim      break;
1688234353Sdim  }
1689226633Sdim
1690226633Sdim  if (writeback) { // Writeback
1691226633Sdim    if (P)
1692226633Sdim      U |= ARMII::IndexModePre << 9;
1693226633Sdim    else
1694226633Sdim      U |= ARMII::IndexModePost << 9;
1695226633Sdim
1696226633Sdim    // On stores, the writeback operand precedes Rt.
1697226633Sdim    switch (Inst.getOpcode()) {
1698226633Sdim    case ARM::STRD:
1699226633Sdim    case ARM::STRD_PRE:
1700226633Sdim    case ARM::STRD_POST:
1701226633Sdim    case ARM::STRH:
1702226633Sdim    case ARM::STRH_PRE:
1703226633Sdim    case ARM::STRH_POST:
1704226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1705226633Sdim        return MCDisassembler::Fail;
1706226633Sdim      break;
1707226633Sdim    default:
1708226633Sdim      break;
1709226633Sdim    }
1710226633Sdim  }
1711226633Sdim
1712226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1713226633Sdim    return MCDisassembler::Fail;
1714226633Sdim  switch (Inst.getOpcode()) {
1715226633Sdim    case ARM::STRD:
1716226633Sdim    case ARM::STRD_PRE:
1717226633Sdim    case ARM::STRD_POST:
1718226633Sdim    case ARM::LDRD:
1719226633Sdim    case ARM::LDRD_PRE:
1720226633Sdim    case ARM::LDRD_POST:
1721226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
1722226633Sdim        return MCDisassembler::Fail;
1723226633Sdim      break;
1724226633Sdim    default:
1725226633Sdim      break;
1726226633Sdim  }
1727226633Sdim
1728226633Sdim  if (writeback) {
1729226633Sdim    // On loads, the writeback operand comes after Rt.
1730226633Sdim    switch (Inst.getOpcode()) {
1731226633Sdim    case ARM::LDRD:
1732226633Sdim    case ARM::LDRD_PRE:
1733226633Sdim    case ARM::LDRD_POST:
1734226633Sdim    case ARM::LDRH:
1735226633Sdim    case ARM::LDRH_PRE:
1736226633Sdim    case ARM::LDRH_POST:
1737226633Sdim    case ARM::LDRSH:
1738226633Sdim    case ARM::LDRSH_PRE:
1739226633Sdim    case ARM::LDRSH_POST:
1740226633Sdim    case ARM::LDRSB:
1741226633Sdim    case ARM::LDRSB_PRE:
1742226633Sdim    case ARM::LDRSB_POST:
1743226633Sdim    case ARM::LDRHTr:
1744226633Sdim    case ARM::LDRSBTr:
1745226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1746226633Sdim        return MCDisassembler::Fail;
1747226633Sdim      break;
1748226633Sdim    default:
1749226633Sdim      break;
1750226633Sdim    }
1751226633Sdim  }
1752226633Sdim
1753226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1754226633Sdim    return MCDisassembler::Fail;
1755226633Sdim
1756226633Sdim  if (type) {
1757226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
1758226633Sdim    Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm));
1759226633Sdim  } else {
1760226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1761226633Sdim    return MCDisassembler::Fail;
1762226633Sdim    Inst.addOperand(MCOperand::CreateImm(U));
1763226633Sdim  }
1764226633Sdim
1765226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1766226633Sdim    return MCDisassembler::Fail;
1767226633Sdim
1768226633Sdim  return S;
1769226633Sdim}
1770226633Sdim
1771234353Sdimstatic DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
1772226633Sdim                                 uint64_t Address, const void *Decoder) {
1773226633Sdim  DecodeStatus S = MCDisassembler::Success;
1774226633Sdim
1775239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1776239462Sdim  unsigned mode = fieldFromInstruction(Insn, 23, 2);
1777226633Sdim
1778226633Sdim  switch (mode) {
1779226633Sdim    case 0:
1780226633Sdim      mode = ARM_AM::da;
1781226633Sdim      break;
1782226633Sdim    case 1:
1783226633Sdim      mode = ARM_AM::ia;
1784226633Sdim      break;
1785226633Sdim    case 2:
1786226633Sdim      mode = ARM_AM::db;
1787226633Sdim      break;
1788226633Sdim    case 3:
1789226633Sdim      mode = ARM_AM::ib;
1790226633Sdim      break;
1791226633Sdim  }
1792226633Sdim
1793226633Sdim  Inst.addOperand(MCOperand::CreateImm(mode));
1794226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1795226633Sdim    return MCDisassembler::Fail;
1796226633Sdim
1797226633Sdim  return S;
1798226633Sdim}
1799226633Sdim
1800234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst,
1801226633Sdim                                  unsigned Insn,
1802226633Sdim                                  uint64_t Address, const void *Decoder) {
1803226633Sdim  DecodeStatus S = MCDisassembler::Success;
1804226633Sdim
1805239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1806239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1807239462Sdim  unsigned reglist = fieldFromInstruction(Insn, 0, 16);
1808226633Sdim
1809226633Sdim  if (pred == 0xF) {
1810226633Sdim    switch (Inst.getOpcode()) {
1811226633Sdim      case ARM::LDMDA:
1812226633Sdim        Inst.setOpcode(ARM::RFEDA);
1813226633Sdim        break;
1814226633Sdim      case ARM::LDMDA_UPD:
1815226633Sdim        Inst.setOpcode(ARM::RFEDA_UPD);
1816226633Sdim        break;
1817226633Sdim      case ARM::LDMDB:
1818226633Sdim        Inst.setOpcode(ARM::RFEDB);
1819226633Sdim        break;
1820226633Sdim      case ARM::LDMDB_UPD:
1821226633Sdim        Inst.setOpcode(ARM::RFEDB_UPD);
1822226633Sdim        break;
1823226633Sdim      case ARM::LDMIA:
1824226633Sdim        Inst.setOpcode(ARM::RFEIA);
1825226633Sdim        break;
1826226633Sdim      case ARM::LDMIA_UPD:
1827226633Sdim        Inst.setOpcode(ARM::RFEIA_UPD);
1828226633Sdim        break;
1829226633Sdim      case ARM::LDMIB:
1830226633Sdim        Inst.setOpcode(ARM::RFEIB);
1831226633Sdim        break;
1832226633Sdim      case ARM::LDMIB_UPD:
1833226633Sdim        Inst.setOpcode(ARM::RFEIB_UPD);
1834226633Sdim        break;
1835226633Sdim      case ARM::STMDA:
1836226633Sdim        Inst.setOpcode(ARM::SRSDA);
1837226633Sdim        break;
1838226633Sdim      case ARM::STMDA_UPD:
1839226633Sdim        Inst.setOpcode(ARM::SRSDA_UPD);
1840226633Sdim        break;
1841226633Sdim      case ARM::STMDB:
1842226633Sdim        Inst.setOpcode(ARM::SRSDB);
1843226633Sdim        break;
1844226633Sdim      case ARM::STMDB_UPD:
1845226633Sdim        Inst.setOpcode(ARM::SRSDB_UPD);
1846226633Sdim        break;
1847226633Sdim      case ARM::STMIA:
1848226633Sdim        Inst.setOpcode(ARM::SRSIA);
1849226633Sdim        break;
1850226633Sdim      case ARM::STMIA_UPD:
1851226633Sdim        Inst.setOpcode(ARM::SRSIA_UPD);
1852226633Sdim        break;
1853226633Sdim      case ARM::STMIB:
1854226633Sdim        Inst.setOpcode(ARM::SRSIB);
1855226633Sdim        break;
1856226633Sdim      case ARM::STMIB_UPD:
1857226633Sdim        Inst.setOpcode(ARM::SRSIB_UPD);
1858226633Sdim        break;
1859206124Srdivacky      default:
1860226633Sdim        if (!Check(S, MCDisassembler::Fail)) return MCDisassembler::Fail;
1861226633Sdim    }
1862226633Sdim
1863226633Sdim    // For stores (which become SRS's, the only operand is the mode.
1864239462Sdim    if (fieldFromInstruction(Insn, 20, 1) == 0) {
1865226633Sdim      Inst.addOperand(
1866239462Sdim          MCOperand::CreateImm(fieldFromInstruction(Insn, 0, 4)));
1867226633Sdim      return S;
1868226633Sdim    }
1869226633Sdim
1870226633Sdim    return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
1871226633Sdim  }
1872226633Sdim
1873226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1874226633Sdim    return MCDisassembler::Fail;
1875226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1876226633Sdim    return MCDisassembler::Fail; // Tied
1877226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1878226633Sdim    return MCDisassembler::Fail;
1879226633Sdim  if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
1880226633Sdim    return MCDisassembler::Fail;
1881226633Sdim
1882226633Sdim  return S;
1883226633Sdim}
1884226633Sdim
1885234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
1886226633Sdim                                 uint64_t Address, const void *Decoder) {
1887239462Sdim  unsigned imod = fieldFromInstruction(Insn, 18, 2);
1888239462Sdim  unsigned M = fieldFromInstruction(Insn, 17, 1);
1889239462Sdim  unsigned iflags = fieldFromInstruction(Insn, 6, 3);
1890239462Sdim  unsigned mode = fieldFromInstruction(Insn, 0, 5);
1891226633Sdim
1892226633Sdim  DecodeStatus S = MCDisassembler::Success;
1893226633Sdim
1894226633Sdim  // imod == '01' --> UNPREDICTABLE
1895226633Sdim  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
1896226633Sdim  // return failure here.  The '01' imod value is unprintable, so there's
1897226633Sdim  // nothing useful we could do even if we returned UNPREDICTABLE.
1898226633Sdim
1899226633Sdim  if (imod == 1) return MCDisassembler::Fail;
1900226633Sdim
1901226633Sdim  if (imod && M) {
1902226633Sdim    Inst.setOpcode(ARM::CPS3p);
1903226633Sdim    Inst.addOperand(MCOperand::CreateImm(imod));
1904226633Sdim    Inst.addOperand(MCOperand::CreateImm(iflags));
1905226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1906226633Sdim  } else if (imod && !M) {
1907226633Sdim    Inst.setOpcode(ARM::CPS2p);
1908226633Sdim    Inst.addOperand(MCOperand::CreateImm(imod));
1909226633Sdim    Inst.addOperand(MCOperand::CreateImm(iflags));
1910226633Sdim    if (mode) S = MCDisassembler::SoftFail;
1911226633Sdim  } else if (!imod && M) {
1912226633Sdim    Inst.setOpcode(ARM::CPS1p);
1913226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1914226633Sdim    if (iflags) S = MCDisassembler::SoftFail;
1915226633Sdim  } else {
1916226633Sdim    // imod == '00' && M == '0' --> UNPREDICTABLE
1917226633Sdim    Inst.setOpcode(ARM::CPS1p);
1918226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1919226633Sdim    S = MCDisassembler::SoftFail;
1920226633Sdim  }
1921226633Sdim
1922226633Sdim  return S;
1923226633Sdim}
1924226633Sdim
1925234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
1926226633Sdim                                 uint64_t Address, const void *Decoder) {
1927239462Sdim  unsigned imod = fieldFromInstruction(Insn, 9, 2);
1928239462Sdim  unsigned M = fieldFromInstruction(Insn, 8, 1);
1929239462Sdim  unsigned iflags = fieldFromInstruction(Insn, 5, 3);
1930239462Sdim  unsigned mode = fieldFromInstruction(Insn, 0, 5);
1931226633Sdim
1932226633Sdim  DecodeStatus S = MCDisassembler::Success;
1933226633Sdim
1934226633Sdim  // imod == '01' --> UNPREDICTABLE
1935226633Sdim  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
1936226633Sdim  // return failure here.  The '01' imod value is unprintable, so there's
1937226633Sdim  // nothing useful we could do even if we returned UNPREDICTABLE.
1938226633Sdim
1939226633Sdim  if (imod == 1) return MCDisassembler::Fail;
1940226633Sdim
1941226633Sdim  if (imod && M) {
1942226633Sdim    Inst.setOpcode(ARM::t2CPS3p);
1943226633Sdim    Inst.addOperand(MCOperand::CreateImm(imod));
1944226633Sdim    Inst.addOperand(MCOperand::CreateImm(iflags));
1945226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1946226633Sdim  } else if (imod && !M) {
1947226633Sdim    Inst.setOpcode(ARM::t2CPS2p);
1948226633Sdim    Inst.addOperand(MCOperand::CreateImm(imod));
1949226633Sdim    Inst.addOperand(MCOperand::CreateImm(iflags));
1950226633Sdim    if (mode) S = MCDisassembler::SoftFail;
1951226633Sdim  } else if (!imod && M) {
1952226633Sdim    Inst.setOpcode(ARM::t2CPS1p);
1953226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1954226633Sdim    if (iflags) S = MCDisassembler::SoftFail;
1955226633Sdim  } else {
1956251662Sdim    // imod == '00' && M == '0' --> this is a HINT instruction
1957251662Sdim    int imm = fieldFromInstruction(Insn, 0, 8);
1958251662Sdim    // HINT are defined only for immediate in [0..4]
1959251662Sdim    if(imm > 4) return MCDisassembler::Fail;
1960251662Sdim    Inst.setOpcode(ARM::t2HINT);
1961251662Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
1962226633Sdim  }
1963226633Sdim
1964226633Sdim  return S;
1965226633Sdim}
1966226633Sdim
1967234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
1968226633Sdim                                 uint64_t Address, const void *Decoder) {
1969226633Sdim  DecodeStatus S = MCDisassembler::Success;
1970226633Sdim
1971239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 8, 4);
1972226633Sdim  unsigned imm = 0;
1973226633Sdim
1974239462Sdim  imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
1975239462Sdim  imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
1976239462Sdim  imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
1977239462Sdim  imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
1978226633Sdim
1979226633Sdim  if (Inst.getOpcode() == ARM::t2MOVTi16)
1980226633Sdim    if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1981226633Sdim      return MCDisassembler::Fail;
1982226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1983226633Sdim    return MCDisassembler::Fail;
1984226633Sdim
1985226633Sdim  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
1986226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
1987226633Sdim
1988226633Sdim  return S;
1989226633Sdim}
1990226633Sdim
1991234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
1992226633Sdim                                 uint64_t Address, const void *Decoder) {
1993226633Sdim  DecodeStatus S = MCDisassembler::Success;
1994226633Sdim
1995239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
1996239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1997226633Sdim  unsigned imm = 0;
1998226633Sdim
1999239462Sdim  imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
2000239462Sdim  imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
2001226633Sdim
2002226633Sdim  if (Inst.getOpcode() == ARM::MOVTi16)
2003251662Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2004226633Sdim      return MCDisassembler::Fail;
2005251662Sdim
2006251662Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2007226633Sdim    return MCDisassembler::Fail;
2008226633Sdim
2009226633Sdim  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
2010226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
2011226633Sdim
2012226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2013226633Sdim    return MCDisassembler::Fail;
2014226633Sdim
2015226633Sdim  return S;
2016226633Sdim}
2017226633Sdim
2018234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
2019226633Sdim                                 uint64_t Address, const void *Decoder) {
2020226633Sdim  DecodeStatus S = MCDisassembler::Success;
2021226633Sdim
2022239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 16, 4);
2023239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 0, 4);
2024239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 8, 4);
2025239462Sdim  unsigned Ra = fieldFromInstruction(Insn, 12, 4);
2026239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2027226633Sdim
2028226633Sdim  if (pred == 0xF)
2029226633Sdim    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
2030226633Sdim
2031226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2032226633Sdim    return MCDisassembler::Fail;
2033226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2034226633Sdim    return MCDisassembler::Fail;
2035226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
2036226633Sdim    return MCDisassembler::Fail;
2037226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
2038226633Sdim    return MCDisassembler::Fail;
2039226633Sdim
2040226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2041226633Sdim    return MCDisassembler::Fail;
2042226633Sdim
2043226633Sdim  return S;
2044226633Sdim}
2045226633Sdim
2046234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
2047226633Sdim                           uint64_t Address, const void *Decoder) {
2048226633Sdim  DecodeStatus S = MCDisassembler::Success;
2049226633Sdim
2050239462Sdim  unsigned add = fieldFromInstruction(Val, 12, 1);
2051239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 12);
2052239462Sdim  unsigned Rn = fieldFromInstruction(Val, 13, 4);
2053226633Sdim
2054226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2055226633Sdim    return MCDisassembler::Fail;
2056226633Sdim
2057226633Sdim  if (!add) imm *= -1;
2058226633Sdim  if (imm == 0 && !add) imm = INT32_MIN;
2059226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
2060226633Sdim  if (Rn == 15)
2061226633Sdim    tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
2062226633Sdim
2063226633Sdim  return S;
2064226633Sdim}
2065226633Sdim
2066234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
2067226633Sdim                                   uint64_t Address, const void *Decoder) {
2068226633Sdim  DecodeStatus S = MCDisassembler::Success;
2069226633Sdim
2070239462Sdim  unsigned Rn = fieldFromInstruction(Val, 9, 4);
2071239462Sdim  unsigned U = fieldFromInstruction(Val, 8, 1);
2072239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 8);
2073226633Sdim
2074226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2075226633Sdim    return MCDisassembler::Fail;
2076226633Sdim
2077226633Sdim  if (U)
2078226633Sdim    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
2079226633Sdim  else
2080226633Sdim    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
2081226633Sdim
2082226633Sdim  return S;
2083226633Sdim}
2084226633Sdim
2085234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
2086226633Sdim                                   uint64_t Address, const void *Decoder) {
2087226633Sdim  return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
2088226633Sdim}
2089226633Sdim
2090226633Sdimstatic DecodeStatus
2091234353SdimDecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2092234353Sdim                     uint64_t Address, const void *Decoder) {
2093243830Sdim  DecodeStatus Status = MCDisassembler::Success;
2094243830Sdim
2095243830Sdim  // Note the J1 and J2 values are from the encoded instruction.  So here
2096243830Sdim  // change them to I1 and I2 values via as documented:
2097243830Sdim  // I1 = NOT(J1 EOR S);
2098243830Sdim  // I2 = NOT(J2 EOR S);
2099243830Sdim  // and build the imm32 with one trailing zero as documented:
2100243830Sdim  // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
2101243830Sdim  unsigned S = fieldFromInstruction(Insn, 26, 1);
2102243830Sdim  unsigned J1 = fieldFromInstruction(Insn, 13, 1);
2103243830Sdim  unsigned J2 = fieldFromInstruction(Insn, 11, 1);
2104243830Sdim  unsigned I1 = !(J1 ^ S);
2105243830Sdim  unsigned I2 = !(J2 ^ S);
2106243830Sdim  unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
2107243830Sdim  unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
2108243830Sdim  unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
2109243830Sdim  int imm32 = SignExtend32<24>(tmp << 1);
2110243830Sdim  if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
2111234353Sdim                                true, 4, Inst, Decoder))
2112243830Sdim    Inst.addOperand(MCOperand::CreateImm(imm32));
2113243830Sdim
2114243830Sdim  return Status;
2115234353Sdim}
2116234353Sdim
2117234353Sdimstatic DecodeStatus
2118234353SdimDecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
2119226633Sdim                           uint64_t Address, const void *Decoder) {
2120226633Sdim  DecodeStatus S = MCDisassembler::Success;
2121226633Sdim
2122239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2123239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
2124226633Sdim
2125226633Sdim  if (pred == 0xF) {
2126226633Sdim    Inst.setOpcode(ARM::BLXi);
2127239462Sdim    imm |= fieldFromInstruction(Insn, 24, 1) << 1;
2128234353Sdim    if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2129234353Sdim                                  true, 4, Inst, Decoder))
2130226633Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
2131226633Sdim    return S;
2132226633Sdim  }
2133226633Sdim
2134234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2135234353Sdim                                true, 4, Inst, Decoder))
2136226633Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
2137226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2138226633Sdim    return MCDisassembler::Fail;
2139226633Sdim
2140226633Sdim  return S;
2141226633Sdim}
2142226633Sdim
2143226633Sdim
2144234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
2145226633Sdim                                   uint64_t Address, const void *Decoder) {
2146226633Sdim  DecodeStatus S = MCDisassembler::Success;
2147226633Sdim
2148239462Sdim  unsigned Rm = fieldFromInstruction(Val, 0, 4);
2149239462Sdim  unsigned align = fieldFromInstruction(Val, 4, 2);
2150226633Sdim
2151226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2152226633Sdim    return MCDisassembler::Fail;
2153226633Sdim  if (!align)
2154226633Sdim    Inst.addOperand(MCOperand::CreateImm(0));
2155226633Sdim  else
2156226633Sdim    Inst.addOperand(MCOperand::CreateImm(4 << align));
2157226633Sdim
2158226633Sdim  return S;
2159226633Sdim}
2160226633Sdim
2161234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
2162226633Sdim                                   uint64_t Address, const void *Decoder) {
2163226633Sdim  DecodeStatus S = MCDisassembler::Success;
2164226633Sdim
2165239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2166239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2167239462Sdim  unsigned wb = fieldFromInstruction(Insn, 16, 4);
2168239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2169239462Sdim  Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2170239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2171226633Sdim
2172226633Sdim  // First output register
2173234353Sdim  switch (Inst.getOpcode()) {
2174234353Sdim  case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
2175234353Sdim  case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
2176234353Sdim  case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
2177234353Sdim  case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
2178234353Sdim  case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
2179234353Sdim  case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
2180234353Sdim  case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
2181234353Sdim  case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
2182234353Sdim  case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
2183234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2184234353Sdim      return MCDisassembler::Fail;
2185234353Sdim    break;
2186234353Sdim  case ARM::VLD2b16:
2187234353Sdim  case ARM::VLD2b32:
2188234353Sdim  case ARM::VLD2b8:
2189234353Sdim  case ARM::VLD2b16wb_fixed:
2190234353Sdim  case ARM::VLD2b16wb_register:
2191234353Sdim  case ARM::VLD2b32wb_fixed:
2192234353Sdim  case ARM::VLD2b32wb_register:
2193234353Sdim  case ARM::VLD2b8wb_fixed:
2194234353Sdim  case ARM::VLD2b8wb_register:
2195234353Sdim    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2196234353Sdim      return MCDisassembler::Fail;
2197234353Sdim    break;
2198234353Sdim  default:
2199234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2200234353Sdim      return MCDisassembler::Fail;
2201234353Sdim  }
2202226633Sdim
2203226633Sdim  // Second output register
2204226633Sdim  switch (Inst.getOpcode()) {
2205226633Sdim    case ARM::VLD3d8:
2206226633Sdim    case ARM::VLD3d16:
2207226633Sdim    case ARM::VLD3d32:
2208226633Sdim    case ARM::VLD3d8_UPD:
2209226633Sdim    case ARM::VLD3d16_UPD:
2210226633Sdim    case ARM::VLD3d32_UPD:
2211226633Sdim    case ARM::VLD4d8:
2212226633Sdim    case ARM::VLD4d16:
2213226633Sdim    case ARM::VLD4d32:
2214226633Sdim    case ARM::VLD4d8_UPD:
2215226633Sdim    case ARM::VLD4d16_UPD:
2216226633Sdim    case ARM::VLD4d32_UPD:
2217226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2218226633Sdim        return MCDisassembler::Fail;
2219206124Srdivacky      break;
2220226633Sdim    case ARM::VLD3q8:
2221226633Sdim    case ARM::VLD3q16:
2222226633Sdim    case ARM::VLD3q32:
2223226633Sdim    case ARM::VLD3q8_UPD:
2224226633Sdim    case ARM::VLD3q16_UPD:
2225226633Sdim    case ARM::VLD3q32_UPD:
2226226633Sdim    case ARM::VLD4q8:
2227226633Sdim    case ARM::VLD4q16:
2228226633Sdim    case ARM::VLD4q32:
2229226633Sdim    case ARM::VLD4q8_UPD:
2230226633Sdim    case ARM::VLD4q16_UPD:
2231226633Sdim    case ARM::VLD4q32_UPD:
2232226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2233226633Sdim        return MCDisassembler::Fail;
2234206124Srdivacky    default:
2235226633Sdim      break;
2236226633Sdim  }
2237226633Sdim
2238226633Sdim  // Third output register
2239226633Sdim  switch(Inst.getOpcode()) {
2240226633Sdim    case ARM::VLD3d8:
2241226633Sdim    case ARM::VLD3d16:
2242226633Sdim    case ARM::VLD3d32:
2243226633Sdim    case ARM::VLD3d8_UPD:
2244226633Sdim    case ARM::VLD3d16_UPD:
2245226633Sdim    case ARM::VLD3d32_UPD:
2246226633Sdim    case ARM::VLD4d8:
2247226633Sdim    case ARM::VLD4d16:
2248226633Sdim    case ARM::VLD4d32:
2249226633Sdim    case ARM::VLD4d8_UPD:
2250226633Sdim    case ARM::VLD4d16_UPD:
2251226633Sdim    case ARM::VLD4d32_UPD:
2252226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2253226633Sdim        return MCDisassembler::Fail;
2254226633Sdim      break;
2255226633Sdim    case ARM::VLD3q8:
2256226633Sdim    case ARM::VLD3q16:
2257226633Sdim    case ARM::VLD3q32:
2258226633Sdim    case ARM::VLD3q8_UPD:
2259226633Sdim    case ARM::VLD3q16_UPD:
2260226633Sdim    case ARM::VLD3q32_UPD:
2261226633Sdim    case ARM::VLD4q8:
2262226633Sdim    case ARM::VLD4q16:
2263226633Sdim    case ARM::VLD4q32:
2264226633Sdim    case ARM::VLD4q8_UPD:
2265226633Sdim    case ARM::VLD4q16_UPD:
2266226633Sdim    case ARM::VLD4q32_UPD:
2267226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2268226633Sdim        return MCDisassembler::Fail;
2269226633Sdim      break;
2270226633Sdim    default:
2271226633Sdim      break;
2272226633Sdim  }
2273226633Sdim
2274226633Sdim  // Fourth output register
2275226633Sdim  switch (Inst.getOpcode()) {
2276226633Sdim    case ARM::VLD4d8:
2277226633Sdim    case ARM::VLD4d16:
2278226633Sdim    case ARM::VLD4d32:
2279226633Sdim    case ARM::VLD4d8_UPD:
2280226633Sdim    case ARM::VLD4d16_UPD:
2281226633Sdim    case ARM::VLD4d32_UPD:
2282226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2283226633Sdim        return MCDisassembler::Fail;
2284226633Sdim      break;
2285226633Sdim    case ARM::VLD4q8:
2286226633Sdim    case ARM::VLD4q16:
2287226633Sdim    case ARM::VLD4q32:
2288226633Sdim    case ARM::VLD4q8_UPD:
2289226633Sdim    case ARM::VLD4q16_UPD:
2290226633Sdim    case ARM::VLD4q32_UPD:
2291226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2292226633Sdim        return MCDisassembler::Fail;
2293226633Sdim      break;
2294226633Sdim    default:
2295226633Sdim      break;
2296226633Sdim  }
2297226633Sdim
2298226633Sdim  // Writeback operand
2299226633Sdim  switch (Inst.getOpcode()) {
2300234353Sdim    case ARM::VLD1d8wb_fixed:
2301234353Sdim    case ARM::VLD1d16wb_fixed:
2302234353Sdim    case ARM::VLD1d32wb_fixed:
2303234353Sdim    case ARM::VLD1d64wb_fixed:
2304234353Sdim    case ARM::VLD1d8wb_register:
2305234353Sdim    case ARM::VLD1d16wb_register:
2306234353Sdim    case ARM::VLD1d32wb_register:
2307234353Sdim    case ARM::VLD1d64wb_register:
2308234353Sdim    case ARM::VLD1q8wb_fixed:
2309234353Sdim    case ARM::VLD1q16wb_fixed:
2310234353Sdim    case ARM::VLD1q32wb_fixed:
2311234353Sdim    case ARM::VLD1q64wb_fixed:
2312234353Sdim    case ARM::VLD1q8wb_register:
2313234353Sdim    case ARM::VLD1q16wb_register:
2314234353Sdim    case ARM::VLD1q32wb_register:
2315234353Sdim    case ARM::VLD1q64wb_register:
2316234353Sdim    case ARM::VLD1d8Twb_fixed:
2317234353Sdim    case ARM::VLD1d8Twb_register:
2318234353Sdim    case ARM::VLD1d16Twb_fixed:
2319234353Sdim    case ARM::VLD1d16Twb_register:
2320234353Sdim    case ARM::VLD1d32Twb_fixed:
2321234353Sdim    case ARM::VLD1d32Twb_register:
2322234353Sdim    case ARM::VLD1d64Twb_fixed:
2323234353Sdim    case ARM::VLD1d64Twb_register:
2324234353Sdim    case ARM::VLD1d8Qwb_fixed:
2325234353Sdim    case ARM::VLD1d8Qwb_register:
2326234353Sdim    case ARM::VLD1d16Qwb_fixed:
2327234353Sdim    case ARM::VLD1d16Qwb_register:
2328234353Sdim    case ARM::VLD1d32Qwb_fixed:
2329234353Sdim    case ARM::VLD1d32Qwb_register:
2330234353Sdim    case ARM::VLD1d64Qwb_fixed:
2331234353Sdim    case ARM::VLD1d64Qwb_register:
2332234353Sdim    case ARM::VLD2d8wb_fixed:
2333234353Sdim    case ARM::VLD2d16wb_fixed:
2334234353Sdim    case ARM::VLD2d32wb_fixed:
2335234353Sdim    case ARM::VLD2q8wb_fixed:
2336234353Sdim    case ARM::VLD2q16wb_fixed:
2337234353Sdim    case ARM::VLD2q32wb_fixed:
2338234353Sdim    case ARM::VLD2d8wb_register:
2339234353Sdim    case ARM::VLD2d16wb_register:
2340234353Sdim    case ARM::VLD2d32wb_register:
2341234353Sdim    case ARM::VLD2q8wb_register:
2342234353Sdim    case ARM::VLD2q16wb_register:
2343234353Sdim    case ARM::VLD2q32wb_register:
2344234353Sdim    case ARM::VLD2b8wb_fixed:
2345234353Sdim    case ARM::VLD2b16wb_fixed:
2346234353Sdim    case ARM::VLD2b32wb_fixed:
2347234353Sdim    case ARM::VLD2b8wb_register:
2348234353Sdim    case ARM::VLD2b16wb_register:
2349234353Sdim    case ARM::VLD2b32wb_register:
2350234353Sdim      Inst.addOperand(MCOperand::CreateImm(0));
2351234353Sdim      break;
2352226633Sdim    case ARM::VLD3d8_UPD:
2353226633Sdim    case ARM::VLD3d16_UPD:
2354226633Sdim    case ARM::VLD3d32_UPD:
2355226633Sdim    case ARM::VLD3q8_UPD:
2356226633Sdim    case ARM::VLD3q16_UPD:
2357226633Sdim    case ARM::VLD3q32_UPD:
2358226633Sdim    case ARM::VLD4d8_UPD:
2359226633Sdim    case ARM::VLD4d16_UPD:
2360226633Sdim    case ARM::VLD4d32_UPD:
2361226633Sdim    case ARM::VLD4q8_UPD:
2362226633Sdim    case ARM::VLD4q16_UPD:
2363226633Sdim    case ARM::VLD4q32_UPD:
2364226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2365226633Sdim        return MCDisassembler::Fail;
2366226633Sdim      break;
2367226633Sdim    default:
2368226633Sdim      break;
2369226633Sdim  }
2370226633Sdim
2371226633Sdim  // AddrMode6 Base (register+alignment)
2372226633Sdim  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2373226633Sdim    return MCDisassembler::Fail;
2374226633Sdim
2375226633Sdim  // AddrMode6 Offset (register)
2376234353Sdim  switch (Inst.getOpcode()) {
2377234353Sdim  default:
2378234353Sdim    // The below have been updated to have explicit am6offset split
2379234353Sdim    // between fixed and register offset. For those instructions not
2380234353Sdim    // yet updated, we need to add an additional reg0 operand for the
2381234353Sdim    // fixed variant.
2382234353Sdim    //
2383234353Sdim    // The fixed offset encodes as Rm == 0xd, so we check for that.
2384234353Sdim    if (Rm == 0xd) {
2385234353Sdim      Inst.addOperand(MCOperand::CreateReg(0));
2386234353Sdim      break;
2387234353Sdim    }
2388234353Sdim    // Fall through to handle the register offset variant.
2389234353Sdim  case ARM::VLD1d8wb_fixed:
2390234353Sdim  case ARM::VLD1d16wb_fixed:
2391234353Sdim  case ARM::VLD1d32wb_fixed:
2392234353Sdim  case ARM::VLD1d64wb_fixed:
2393234353Sdim  case ARM::VLD1d8Twb_fixed:
2394234353Sdim  case ARM::VLD1d16Twb_fixed:
2395234353Sdim  case ARM::VLD1d32Twb_fixed:
2396234353Sdim  case ARM::VLD1d64Twb_fixed:
2397234353Sdim  case ARM::VLD1d8Qwb_fixed:
2398234353Sdim  case ARM::VLD1d16Qwb_fixed:
2399234353Sdim  case ARM::VLD1d32Qwb_fixed:
2400234353Sdim  case ARM::VLD1d64Qwb_fixed:
2401234353Sdim  case ARM::VLD1d8wb_register:
2402234353Sdim  case ARM::VLD1d16wb_register:
2403234353Sdim  case ARM::VLD1d32wb_register:
2404234353Sdim  case ARM::VLD1d64wb_register:
2405234353Sdim  case ARM::VLD1q8wb_fixed:
2406234353Sdim  case ARM::VLD1q16wb_fixed:
2407234353Sdim  case ARM::VLD1q32wb_fixed:
2408234353Sdim  case ARM::VLD1q64wb_fixed:
2409234353Sdim  case ARM::VLD1q8wb_register:
2410234353Sdim  case ARM::VLD1q16wb_register:
2411234353Sdim  case ARM::VLD1q32wb_register:
2412234353Sdim  case ARM::VLD1q64wb_register:
2413234353Sdim    // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2414234353Sdim    // variant encodes Rm == 0xf. Anything else is a register offset post-
2415234353Sdim    // increment and we need to add the register operand to the instruction.
2416234353Sdim    if (Rm != 0xD && Rm != 0xF &&
2417234353Sdim        !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2418226633Sdim      return MCDisassembler::Fail;
2419234353Sdim    break;
2420234353Sdim  case ARM::VLD2d8wb_fixed:
2421234353Sdim  case ARM::VLD2d16wb_fixed:
2422234353Sdim  case ARM::VLD2d32wb_fixed:
2423234353Sdim  case ARM::VLD2b8wb_fixed:
2424234353Sdim  case ARM::VLD2b16wb_fixed:
2425234353Sdim  case ARM::VLD2b32wb_fixed:
2426234353Sdim  case ARM::VLD2q8wb_fixed:
2427234353Sdim  case ARM::VLD2q16wb_fixed:
2428234353Sdim  case ARM::VLD2q32wb_fixed:
2429234353Sdim    break;
2430226633Sdim  }
2431226633Sdim
2432226633Sdim  return S;
2433226633Sdim}
2434226633Sdim
2435234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
2436226633Sdim                                 uint64_t Address, const void *Decoder) {
2437226633Sdim  DecodeStatus S = MCDisassembler::Success;
2438226633Sdim
2439239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2440239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2441239462Sdim  unsigned wb = fieldFromInstruction(Insn, 16, 4);
2442239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2443239462Sdim  Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2444239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2445226633Sdim
2446226633Sdim  // Writeback Operand
2447226633Sdim  switch (Inst.getOpcode()) {
2448234353Sdim    case ARM::VST1d8wb_fixed:
2449234353Sdim    case ARM::VST1d16wb_fixed:
2450234353Sdim    case ARM::VST1d32wb_fixed:
2451234353Sdim    case ARM::VST1d64wb_fixed:
2452234353Sdim    case ARM::VST1d8wb_register:
2453234353Sdim    case ARM::VST1d16wb_register:
2454234353Sdim    case ARM::VST1d32wb_register:
2455234353Sdim    case ARM::VST1d64wb_register:
2456234353Sdim    case ARM::VST1q8wb_fixed:
2457234353Sdim    case ARM::VST1q16wb_fixed:
2458234353Sdim    case ARM::VST1q32wb_fixed:
2459234353Sdim    case ARM::VST1q64wb_fixed:
2460234353Sdim    case ARM::VST1q8wb_register:
2461234353Sdim    case ARM::VST1q16wb_register:
2462234353Sdim    case ARM::VST1q32wb_register:
2463234353Sdim    case ARM::VST1q64wb_register:
2464234353Sdim    case ARM::VST1d8Twb_fixed:
2465234353Sdim    case ARM::VST1d16Twb_fixed:
2466234353Sdim    case ARM::VST1d32Twb_fixed:
2467234353Sdim    case ARM::VST1d64Twb_fixed:
2468234353Sdim    case ARM::VST1d8Twb_register:
2469234353Sdim    case ARM::VST1d16Twb_register:
2470234353Sdim    case ARM::VST1d32Twb_register:
2471234353Sdim    case ARM::VST1d64Twb_register:
2472234353Sdim    case ARM::VST1d8Qwb_fixed:
2473234353Sdim    case ARM::VST1d16Qwb_fixed:
2474234353Sdim    case ARM::VST1d32Qwb_fixed:
2475234353Sdim    case ARM::VST1d64Qwb_fixed:
2476234353Sdim    case ARM::VST1d8Qwb_register:
2477234353Sdim    case ARM::VST1d16Qwb_register:
2478234353Sdim    case ARM::VST1d32Qwb_register:
2479234353Sdim    case ARM::VST1d64Qwb_register:
2480234353Sdim    case ARM::VST2d8wb_fixed:
2481234353Sdim    case ARM::VST2d16wb_fixed:
2482234353Sdim    case ARM::VST2d32wb_fixed:
2483234353Sdim    case ARM::VST2d8wb_register:
2484234353Sdim    case ARM::VST2d16wb_register:
2485234353Sdim    case ARM::VST2d32wb_register:
2486234353Sdim    case ARM::VST2q8wb_fixed:
2487234353Sdim    case ARM::VST2q16wb_fixed:
2488234353Sdim    case ARM::VST2q32wb_fixed:
2489234353Sdim    case ARM::VST2q8wb_register:
2490234353Sdim    case ARM::VST2q16wb_register:
2491234353Sdim    case ARM::VST2q32wb_register:
2492234353Sdim    case ARM::VST2b8wb_fixed:
2493234353Sdim    case ARM::VST2b16wb_fixed:
2494234353Sdim    case ARM::VST2b32wb_fixed:
2495234353Sdim    case ARM::VST2b8wb_register:
2496234353Sdim    case ARM::VST2b16wb_register:
2497234353Sdim    case ARM::VST2b32wb_register:
2498234353Sdim      if (Rm == 0xF)
2499234353Sdim        return MCDisassembler::Fail;
2500234353Sdim      Inst.addOperand(MCOperand::CreateImm(0));
2501234353Sdim      break;
2502226633Sdim    case ARM::VST3d8_UPD:
2503226633Sdim    case ARM::VST3d16_UPD:
2504226633Sdim    case ARM::VST3d32_UPD:
2505226633Sdim    case ARM::VST3q8_UPD:
2506226633Sdim    case ARM::VST3q16_UPD:
2507226633Sdim    case ARM::VST3q32_UPD:
2508226633Sdim    case ARM::VST4d8_UPD:
2509226633Sdim    case ARM::VST4d16_UPD:
2510226633Sdim    case ARM::VST4d32_UPD:
2511226633Sdim    case ARM::VST4q8_UPD:
2512226633Sdim    case ARM::VST4q16_UPD:
2513226633Sdim    case ARM::VST4q32_UPD:
2514226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2515226633Sdim        return MCDisassembler::Fail;
2516226633Sdim      break;
2517226633Sdim    default:
2518226633Sdim      break;
2519226633Sdim  }
2520226633Sdim
2521226633Sdim  // AddrMode6 Base (register+alignment)
2522226633Sdim  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2523226633Sdim    return MCDisassembler::Fail;
2524226633Sdim
2525226633Sdim  // AddrMode6 Offset (register)
2526234353Sdim  switch (Inst.getOpcode()) {
2527234353Sdim    default:
2528234353Sdim      if (Rm == 0xD)
2529234353Sdim        Inst.addOperand(MCOperand::CreateReg(0));
2530234353Sdim      else if (Rm != 0xF) {
2531234353Sdim        if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2532234353Sdim          return MCDisassembler::Fail;
2533234353Sdim      }
2534234353Sdim      break;
2535234353Sdim    case ARM::VST1d8wb_fixed:
2536234353Sdim    case ARM::VST1d16wb_fixed:
2537234353Sdim    case ARM::VST1d32wb_fixed:
2538234353Sdim    case ARM::VST1d64wb_fixed:
2539234353Sdim    case ARM::VST1q8wb_fixed:
2540234353Sdim    case ARM::VST1q16wb_fixed:
2541234353Sdim    case ARM::VST1q32wb_fixed:
2542234353Sdim    case ARM::VST1q64wb_fixed:
2543234353Sdim    case ARM::VST1d8Twb_fixed:
2544234353Sdim    case ARM::VST1d16Twb_fixed:
2545234353Sdim    case ARM::VST1d32Twb_fixed:
2546234353Sdim    case ARM::VST1d64Twb_fixed:
2547234353Sdim    case ARM::VST1d8Qwb_fixed:
2548234353Sdim    case ARM::VST1d16Qwb_fixed:
2549234353Sdim    case ARM::VST1d32Qwb_fixed:
2550234353Sdim    case ARM::VST1d64Qwb_fixed:
2551234353Sdim    case ARM::VST2d8wb_fixed:
2552234353Sdim    case ARM::VST2d16wb_fixed:
2553234353Sdim    case ARM::VST2d32wb_fixed:
2554234353Sdim    case ARM::VST2q8wb_fixed:
2555234353Sdim    case ARM::VST2q16wb_fixed:
2556234353Sdim    case ARM::VST2q32wb_fixed:
2557234353Sdim    case ARM::VST2b8wb_fixed:
2558234353Sdim    case ARM::VST2b16wb_fixed:
2559234353Sdim    case ARM::VST2b32wb_fixed:
2560234353Sdim      break;
2561226633Sdim  }
2562226633Sdim
2563234353Sdim
2564226633Sdim  // First input register
2565234353Sdim  switch (Inst.getOpcode()) {
2566234353Sdim  case ARM::VST1q16:
2567234353Sdim  case ARM::VST1q32:
2568234353Sdim  case ARM::VST1q64:
2569234353Sdim  case ARM::VST1q8:
2570234353Sdim  case ARM::VST1q16wb_fixed:
2571234353Sdim  case ARM::VST1q16wb_register:
2572234353Sdim  case ARM::VST1q32wb_fixed:
2573234353Sdim  case ARM::VST1q32wb_register:
2574234353Sdim  case ARM::VST1q64wb_fixed:
2575234353Sdim  case ARM::VST1q64wb_register:
2576234353Sdim  case ARM::VST1q8wb_fixed:
2577234353Sdim  case ARM::VST1q8wb_register:
2578234353Sdim  case ARM::VST2d16:
2579234353Sdim  case ARM::VST2d32:
2580234353Sdim  case ARM::VST2d8:
2581234353Sdim  case ARM::VST2d16wb_fixed:
2582234353Sdim  case ARM::VST2d16wb_register:
2583234353Sdim  case ARM::VST2d32wb_fixed:
2584234353Sdim  case ARM::VST2d32wb_register:
2585234353Sdim  case ARM::VST2d8wb_fixed:
2586234353Sdim  case ARM::VST2d8wb_register:
2587234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2588234353Sdim      return MCDisassembler::Fail;
2589234353Sdim    break;
2590234353Sdim  case ARM::VST2b16:
2591234353Sdim  case ARM::VST2b32:
2592234353Sdim  case ARM::VST2b8:
2593234353Sdim  case ARM::VST2b16wb_fixed:
2594234353Sdim  case ARM::VST2b16wb_register:
2595234353Sdim  case ARM::VST2b32wb_fixed:
2596234353Sdim  case ARM::VST2b32wb_register:
2597234353Sdim  case ARM::VST2b8wb_fixed:
2598234353Sdim  case ARM::VST2b8wb_register:
2599234353Sdim    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2600234353Sdim      return MCDisassembler::Fail;
2601234353Sdim    break;
2602234353Sdim  default:
2603234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2604234353Sdim      return MCDisassembler::Fail;
2605234353Sdim  }
2606226633Sdim
2607226633Sdim  // Second input register
2608226633Sdim  switch (Inst.getOpcode()) {
2609226633Sdim    case ARM::VST3d8:
2610226633Sdim    case ARM::VST3d16:
2611226633Sdim    case ARM::VST3d32:
2612226633Sdim    case ARM::VST3d8_UPD:
2613226633Sdim    case ARM::VST3d16_UPD:
2614226633Sdim    case ARM::VST3d32_UPD:
2615226633Sdim    case ARM::VST4d8:
2616226633Sdim    case ARM::VST4d16:
2617226633Sdim    case ARM::VST4d32:
2618226633Sdim    case ARM::VST4d8_UPD:
2619226633Sdim    case ARM::VST4d16_UPD:
2620226633Sdim    case ARM::VST4d32_UPD:
2621226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2622226633Sdim        return MCDisassembler::Fail;
2623226633Sdim      break;
2624226633Sdim    case ARM::VST3q8:
2625226633Sdim    case ARM::VST3q16:
2626226633Sdim    case ARM::VST3q32:
2627226633Sdim    case ARM::VST3q8_UPD:
2628226633Sdim    case ARM::VST3q16_UPD:
2629226633Sdim    case ARM::VST3q32_UPD:
2630226633Sdim    case ARM::VST4q8:
2631226633Sdim    case ARM::VST4q16:
2632226633Sdim    case ARM::VST4q32:
2633226633Sdim    case ARM::VST4q8_UPD:
2634226633Sdim    case ARM::VST4q16_UPD:
2635226633Sdim    case ARM::VST4q32_UPD:
2636226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2637226633Sdim        return MCDisassembler::Fail;
2638226633Sdim      break;
2639226633Sdim    default:
2640226633Sdim      break;
2641226633Sdim  }
2642226633Sdim
2643226633Sdim  // Third input register
2644226633Sdim  switch (Inst.getOpcode()) {
2645226633Sdim    case ARM::VST3d8:
2646226633Sdim    case ARM::VST3d16:
2647226633Sdim    case ARM::VST3d32:
2648226633Sdim    case ARM::VST3d8_UPD:
2649226633Sdim    case ARM::VST3d16_UPD:
2650226633Sdim    case ARM::VST3d32_UPD:
2651226633Sdim    case ARM::VST4d8:
2652226633Sdim    case ARM::VST4d16:
2653226633Sdim    case ARM::VST4d32:
2654226633Sdim    case ARM::VST4d8_UPD:
2655226633Sdim    case ARM::VST4d16_UPD:
2656226633Sdim    case ARM::VST4d32_UPD:
2657226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2658226633Sdim        return MCDisassembler::Fail;
2659226633Sdim      break;
2660226633Sdim    case ARM::VST3q8:
2661226633Sdim    case ARM::VST3q16:
2662226633Sdim    case ARM::VST3q32:
2663226633Sdim    case ARM::VST3q8_UPD:
2664226633Sdim    case ARM::VST3q16_UPD:
2665226633Sdim    case ARM::VST3q32_UPD:
2666226633Sdim    case ARM::VST4q8:
2667226633Sdim    case ARM::VST4q16:
2668226633Sdim    case ARM::VST4q32:
2669226633Sdim    case ARM::VST4q8_UPD:
2670226633Sdim    case ARM::VST4q16_UPD:
2671226633Sdim    case ARM::VST4q32_UPD:
2672226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2673226633Sdim        return MCDisassembler::Fail;
2674226633Sdim      break;
2675226633Sdim    default:
2676226633Sdim      break;
2677226633Sdim  }
2678226633Sdim
2679226633Sdim  // Fourth input register
2680226633Sdim  switch (Inst.getOpcode()) {
2681226633Sdim    case ARM::VST4d8:
2682226633Sdim    case ARM::VST4d16:
2683226633Sdim    case ARM::VST4d32:
2684226633Sdim    case ARM::VST4d8_UPD:
2685226633Sdim    case ARM::VST4d16_UPD:
2686226633Sdim    case ARM::VST4d32_UPD:
2687226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2688226633Sdim        return MCDisassembler::Fail;
2689226633Sdim      break;
2690226633Sdim    case ARM::VST4q8:
2691226633Sdim    case ARM::VST4q16:
2692226633Sdim    case ARM::VST4q32:
2693226633Sdim    case ARM::VST4q8_UPD:
2694226633Sdim    case ARM::VST4q16_UPD:
2695226633Sdim    case ARM::VST4q32_UPD:
2696226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2697226633Sdim        return MCDisassembler::Fail;
2698226633Sdim      break;
2699226633Sdim    default:
2700226633Sdim      break;
2701226633Sdim  }
2702226633Sdim
2703226633Sdim  return S;
2704226633Sdim}
2705226633Sdim
2706234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
2707226633Sdim                                    uint64_t Address, const void *Decoder) {
2708226633Sdim  DecodeStatus S = MCDisassembler::Success;
2709226633Sdim
2710239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2711239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2712239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2713239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2714239462Sdim  unsigned align = fieldFromInstruction(Insn, 4, 1);
2715239462Sdim  unsigned size = fieldFromInstruction(Insn, 6, 2);
2716226633Sdim
2717243830Sdim  if (size == 0 && align == 1)
2718243830Sdim    return MCDisassembler::Fail;
2719226633Sdim  align *= (1 << size);
2720226633Sdim
2721234353Sdim  switch (Inst.getOpcode()) {
2722234353Sdim  case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
2723234353Sdim  case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
2724234353Sdim  case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
2725234353Sdim  case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
2726234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2727226633Sdim      return MCDisassembler::Fail;
2728234353Sdim    break;
2729234353Sdim  default:
2730234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2731234353Sdim      return MCDisassembler::Fail;
2732234353Sdim    break;
2733226633Sdim  }
2734226633Sdim  if (Rm != 0xF) {
2735226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2736226633Sdim      return MCDisassembler::Fail;
2737226633Sdim  }
2738226633Sdim
2739226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2740226633Sdim    return MCDisassembler::Fail;
2741226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
2742226633Sdim
2743234353Sdim  // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2744234353Sdim  // variant encodes Rm == 0xf. Anything else is a register offset post-
2745234353Sdim  // increment and we need to add the register operand to the instruction.
2746234353Sdim  if (Rm != 0xD && Rm != 0xF &&
2747234353Sdim      !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2748234353Sdim    return MCDisassembler::Fail;
2749226633Sdim
2750226633Sdim  return S;
2751226633Sdim}
2752226633Sdim
2753234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
2754226633Sdim                                    uint64_t Address, const void *Decoder) {
2755226633Sdim  DecodeStatus S = MCDisassembler::Success;
2756226633Sdim
2757239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2758239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2759239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2760239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2761239462Sdim  unsigned align = fieldFromInstruction(Insn, 4, 1);
2762239462Sdim  unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
2763226633Sdim  align *= 2*size;
2764226633Sdim
2765234353Sdim  switch (Inst.getOpcode()) {
2766234353Sdim  case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
2767234353Sdim  case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
2768234353Sdim  case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
2769234353Sdim  case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
2770234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2771226633Sdim      return MCDisassembler::Fail;
2772234353Sdim    break;
2773234353Sdim  case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
2774234353Sdim  case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
2775234353Sdim  case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
2776234353Sdim  case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
2777234353Sdim    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2778234353Sdim      return MCDisassembler::Fail;
2779234353Sdim    break;
2780234353Sdim  default:
2781234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2782234353Sdim      return MCDisassembler::Fail;
2783234353Sdim    break;
2784226633Sdim  }
2785226633Sdim
2786234353Sdim  if (Rm != 0xF)
2787234353Sdim    Inst.addOperand(MCOperand::CreateImm(0));
2788234353Sdim
2789226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2790226633Sdim    return MCDisassembler::Fail;
2791226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
2792226633Sdim
2793234982Sdim  if (Rm != 0xD && Rm != 0xF) {
2794226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2795226633Sdim      return MCDisassembler::Fail;
2796226633Sdim  }
2797226633Sdim
2798226633Sdim  return S;
2799226633Sdim}
2800226633Sdim
2801234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
2802226633Sdim                                    uint64_t Address, const void *Decoder) {
2803226633Sdim  DecodeStatus S = MCDisassembler::Success;
2804226633Sdim
2805239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2806239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2807239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2808239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2809239462Sdim  unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
2810226633Sdim
2811226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2812226633Sdim    return MCDisassembler::Fail;
2813226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2814226633Sdim    return MCDisassembler::Fail;
2815226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2816226633Sdim    return MCDisassembler::Fail;
2817226633Sdim  if (Rm != 0xF) {
2818226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2819226633Sdim      return MCDisassembler::Fail;
2820226633Sdim  }
2821226633Sdim
2822226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2823226633Sdim    return MCDisassembler::Fail;
2824226633Sdim  Inst.addOperand(MCOperand::CreateImm(0));
2825226633Sdim
2826226633Sdim  if (Rm == 0xD)
2827226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
2828226633Sdim  else if (Rm != 0xF) {
2829226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2830226633Sdim      return MCDisassembler::Fail;
2831226633Sdim  }
2832226633Sdim
2833226633Sdim  return S;
2834226633Sdim}
2835226633Sdim
2836234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
2837226633Sdim                                    uint64_t Address, const void *Decoder) {
2838226633Sdim  DecodeStatus S = MCDisassembler::Success;
2839226633Sdim
2840239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2841239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2842239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2843239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2844239462Sdim  unsigned size = fieldFromInstruction(Insn, 6, 2);
2845239462Sdim  unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
2846239462Sdim  unsigned align = fieldFromInstruction(Insn, 4, 1);
2847226633Sdim
2848226633Sdim  if (size == 0x3) {
2849243830Sdim    if (align == 0)
2850243830Sdim      return MCDisassembler::Fail;
2851226633Sdim    size = 4;
2852226633Sdim    align = 16;
2853226633Sdim  } else {
2854226633Sdim    if (size == 2) {
2855226633Sdim      size = 1 << size;
2856226633Sdim      align *= 8;
2857226633Sdim    } else {
2858226633Sdim      size = 1 << size;
2859226633Sdim      align *= 4*size;
2860206124Srdivacky    }
2861206124Srdivacky  }
2862206124Srdivacky
2863226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2864226633Sdim    return MCDisassembler::Fail;
2865226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2866226633Sdim    return MCDisassembler::Fail;
2867226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2868226633Sdim    return MCDisassembler::Fail;
2869226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
2870226633Sdim    return MCDisassembler::Fail;
2871226633Sdim  if (Rm != 0xF) {
2872226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2873226633Sdim      return MCDisassembler::Fail;
2874226633Sdim  }
2875226633Sdim
2876226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2877226633Sdim    return MCDisassembler::Fail;
2878226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
2879226633Sdim
2880226633Sdim  if (Rm == 0xD)
2881226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
2882226633Sdim  else if (Rm != 0xF) {
2883226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2884226633Sdim      return MCDisassembler::Fail;
2885226633Sdim  }
2886226633Sdim
2887226633Sdim  return S;
2888206124Srdivacky}
2889206124Srdivacky
2890226633Sdimstatic DecodeStatus
2891234353SdimDecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn,
2892226633Sdim                            uint64_t Address, const void *Decoder) {
2893226633Sdim  DecodeStatus S = MCDisassembler::Success;
2894206124Srdivacky
2895239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2896239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2897239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 4);
2898239462Sdim  imm |= fieldFromInstruction(Insn, 16, 3) << 4;
2899239462Sdim  imm |= fieldFromInstruction(Insn, 24, 1) << 7;
2900239462Sdim  imm |= fieldFromInstruction(Insn, 8, 4) << 8;
2901239462Sdim  imm |= fieldFromInstruction(Insn, 5, 1) << 12;
2902239462Sdim  unsigned Q = fieldFromInstruction(Insn, 6, 1);
2903206124Srdivacky
2904226633Sdim  if (Q) {
2905226633Sdim    if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
2906226633Sdim    return MCDisassembler::Fail;
2907226633Sdim  } else {
2908226633Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2909226633Sdim    return MCDisassembler::Fail;
2910226633Sdim  }
2911206124Srdivacky
2912226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
2913206124Srdivacky
2914226633Sdim  switch (Inst.getOpcode()) {
2915226633Sdim    case ARM::VORRiv4i16:
2916226633Sdim    case ARM::VORRiv2i32:
2917226633Sdim    case ARM::VBICiv4i16:
2918226633Sdim    case ARM::VBICiv2i32:
2919226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2920226633Sdim        return MCDisassembler::Fail;
2921226633Sdim      break;
2922226633Sdim    case ARM::VORRiv8i16:
2923226633Sdim    case ARM::VORRiv4i32:
2924226633Sdim    case ARM::VBICiv8i16:
2925226633Sdim    case ARM::VBICiv4i32:
2926226633Sdim      if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
2927226633Sdim        return MCDisassembler::Fail;
2928226633Sdim      break;
2929226633Sdim    default:
2930226633Sdim      break;
2931226633Sdim  }
2932206124Srdivacky
2933226633Sdim  return S;
2934226633Sdim}
2935226633Sdim
2936234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
2937226633Sdim                                        uint64_t Address, const void *Decoder) {
2938226633Sdim  DecodeStatus S = MCDisassembler::Success;
2939226633Sdim
2940239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2941239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2942239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2943239462Sdim  Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
2944239462Sdim  unsigned size = fieldFromInstruction(Insn, 18, 2);
2945226633Sdim
2946226633Sdim  if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
2947226633Sdim    return MCDisassembler::Fail;
2948226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
2949226633Sdim    return MCDisassembler::Fail;
2950226633Sdim  Inst.addOperand(MCOperand::CreateImm(8 << size));
2951226633Sdim
2952226633Sdim  return S;
2953226633Sdim}
2954226633Sdim
2955234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
2956226633Sdim                               uint64_t Address, const void *Decoder) {
2957226633Sdim  Inst.addOperand(MCOperand::CreateImm(8 - Val));
2958226633Sdim  return MCDisassembler::Success;
2959226633Sdim}
2960226633Sdim
2961234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
2962226633Sdim                               uint64_t Address, const void *Decoder) {
2963226633Sdim  Inst.addOperand(MCOperand::CreateImm(16 - Val));
2964226633Sdim  return MCDisassembler::Success;
2965226633Sdim}
2966226633Sdim
2967234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
2968226633Sdim                               uint64_t Address, const void *Decoder) {
2969226633Sdim  Inst.addOperand(MCOperand::CreateImm(32 - Val));
2970226633Sdim  return MCDisassembler::Success;
2971226633Sdim}
2972226633Sdim
2973234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
2974226633Sdim                               uint64_t Address, const void *Decoder) {
2975226633Sdim  Inst.addOperand(MCOperand::CreateImm(64 - Val));
2976226633Sdim  return MCDisassembler::Success;
2977226633Sdim}
2978226633Sdim
2979234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
2980226633Sdim                               uint64_t Address, const void *Decoder) {
2981226633Sdim  DecodeStatus S = MCDisassembler::Success;
2982226633Sdim
2983239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2984239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2985239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2986239462Sdim  Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
2987239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2988239462Sdim  Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
2989239462Sdim  unsigned op = fieldFromInstruction(Insn, 6, 1);
2990226633Sdim
2991226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2992226633Sdim    return MCDisassembler::Fail;
2993226633Sdim  if (op) {
2994226633Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2995226633Sdim    return MCDisassembler::Fail; // Writeback
2996206124Srdivacky  }
2997226633Sdim
2998234353Sdim  switch (Inst.getOpcode()) {
2999234353Sdim  case ARM::VTBL2:
3000234353Sdim  case ARM::VTBX2:
3001234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
3002234353Sdim      return MCDisassembler::Fail;
3003234353Sdim    break;
3004234353Sdim  default:
3005234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
3006234353Sdim      return MCDisassembler::Fail;
3007226633Sdim  }
3008226633Sdim
3009226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3010226633Sdim    return MCDisassembler::Fail;
3011226633Sdim
3012226633Sdim  return S;
3013206124Srdivacky}
3014206124Srdivacky
3015234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
3016226633Sdim                                     uint64_t Address, const void *Decoder) {
3017226633Sdim  DecodeStatus S = MCDisassembler::Success;
3018221345Sdim
3019239462Sdim  unsigned dst = fieldFromInstruction(Insn, 8, 3);
3020239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 8);
3021221345Sdim
3022226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
3023226633Sdim    return MCDisassembler::Fail;
3024226633Sdim
3025226633Sdim  switch(Inst.getOpcode()) {
3026226633Sdim    default:
3027226633Sdim      return MCDisassembler::Fail;
3028226633Sdim    case ARM::tADR:
3029226633Sdim      break; // tADR does not explicitly represent the PC as an operand.
3030226633Sdim    case ARM::tADDrSPi:
3031226633Sdim      Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3032226633Sdim      break;
3033221345Sdim  }
3034226633Sdim
3035226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3036226633Sdim  return S;
3037221345Sdim}
3038221345Sdim
3039234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
3040226633Sdim                                 uint64_t Address, const void *Decoder) {
3041234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
3042234353Sdim                                true, 2, Inst, Decoder))
3043234353Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
3044226633Sdim  return MCDisassembler::Success;
3045226633Sdim}
3046206124Srdivacky
3047234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
3048226633Sdim                                 uint64_t Address, const void *Decoder) {
3049239462Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
3050234353Sdim                                true, 4, Inst, Decoder))
3051234353Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
3052226633Sdim  return MCDisassembler::Success;
3053226633Sdim}
3054206124Srdivacky
3055234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
3056226633Sdim                                 uint64_t Address, const void *Decoder) {
3057249423Sdim  if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
3058234353Sdim                                true, 2, Inst, Decoder))
3059249423Sdim    Inst.addOperand(MCOperand::CreateImm(Val << 1));
3060226633Sdim  return MCDisassembler::Success;
3061226633Sdim}
3062206124Srdivacky
3063234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
3064226633Sdim                                 uint64_t Address, const void *Decoder) {
3065226633Sdim  DecodeStatus S = MCDisassembler::Success;
3066206124Srdivacky
3067239462Sdim  unsigned Rn = fieldFromInstruction(Val, 0, 3);
3068239462Sdim  unsigned Rm = fieldFromInstruction(Val, 3, 3);
3069226633Sdim
3070226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3071226633Sdim    return MCDisassembler::Fail;
3072226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
3073226633Sdim    return MCDisassembler::Fail;
3074226633Sdim
3075226633Sdim  return S;
3076226633Sdim}
3077226633Sdim
3078234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
3079226633Sdim                                  uint64_t Address, const void *Decoder) {
3080226633Sdim  DecodeStatus S = MCDisassembler::Success;
3081226633Sdim
3082239462Sdim  unsigned Rn = fieldFromInstruction(Val, 0, 3);
3083239462Sdim  unsigned imm = fieldFromInstruction(Val, 3, 5);
3084226633Sdim
3085226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3086226633Sdim    return MCDisassembler::Fail;
3087226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3088226633Sdim
3089226633Sdim  return S;
3090226633Sdim}
3091226633Sdim
3092234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
3093226633Sdim                                  uint64_t Address, const void *Decoder) {
3094226633Sdim  unsigned imm = Val << 2;
3095226633Sdim
3096226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3097226633Sdim  tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
3098226633Sdim
3099226633Sdim  return MCDisassembler::Success;
3100226633Sdim}
3101226633Sdim
3102234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
3103226633Sdim                                  uint64_t Address, const void *Decoder) {
3104226633Sdim  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3105226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
3106226633Sdim
3107226633Sdim  return MCDisassembler::Success;
3108226633Sdim}
3109226633Sdim
3110234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
3111226633Sdim                                  uint64_t Address, const void *Decoder) {
3112226633Sdim  DecodeStatus S = MCDisassembler::Success;
3113226633Sdim
3114239462Sdim  unsigned Rn = fieldFromInstruction(Val, 6, 4);
3115239462Sdim  unsigned Rm = fieldFromInstruction(Val, 2, 4);
3116239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 2);
3117226633Sdim
3118226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3119226633Sdim    return MCDisassembler::Fail;
3120226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3121226633Sdim    return MCDisassembler::Fail;
3122226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3123226633Sdim
3124226633Sdim  return S;
3125226633Sdim}
3126226633Sdim
3127234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
3128226633Sdim                              uint64_t Address, const void *Decoder) {
3129226633Sdim  DecodeStatus S = MCDisassembler::Success;
3130226633Sdim
3131226633Sdim  switch (Inst.getOpcode()) {
3132226633Sdim    case ARM::t2PLDs:
3133226633Sdim    case ARM::t2PLDWs:
3134226633Sdim    case ARM::t2PLIs:
3135226633Sdim      break;
3136226633Sdim    default: {
3137239462Sdim      unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3138226633Sdim      if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3139226633Sdim    return MCDisassembler::Fail;
3140206124Srdivacky    }
3141226633Sdim  }
3142206124Srdivacky
3143239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3144226633Sdim  if (Rn == 0xF) {
3145226633Sdim    switch (Inst.getOpcode()) {
3146226633Sdim      case ARM::t2LDRBs:
3147226633Sdim        Inst.setOpcode(ARM::t2LDRBpci);
3148226633Sdim        break;
3149226633Sdim      case ARM::t2LDRHs:
3150226633Sdim        Inst.setOpcode(ARM::t2LDRHpci);
3151226633Sdim        break;
3152226633Sdim      case ARM::t2LDRSHs:
3153226633Sdim        Inst.setOpcode(ARM::t2LDRSHpci);
3154226633Sdim        break;
3155226633Sdim      case ARM::t2LDRSBs:
3156226633Sdim        Inst.setOpcode(ARM::t2LDRSBpci);
3157226633Sdim        break;
3158226633Sdim      case ARM::t2PLDs:
3159226633Sdim        Inst.setOpcode(ARM::t2PLDi12);
3160226633Sdim        Inst.addOperand(MCOperand::CreateReg(ARM::PC));
3161226633Sdim        break;
3162226633Sdim      default:
3163226633Sdim        return MCDisassembler::Fail;
3164206124Srdivacky    }
3165206124Srdivacky
3166239462Sdim    int imm = fieldFromInstruction(Insn, 0, 12);
3167239462Sdim    if (!fieldFromInstruction(Insn, 23, 1)) imm *= -1;
3168226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
3169221345Sdim
3170226633Sdim    return S;
3171226633Sdim  }
3172226633Sdim
3173239462Sdim  unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
3174239462Sdim  addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
3175239462Sdim  addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
3176226633Sdim  if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
3177226633Sdim    return MCDisassembler::Fail;
3178226633Sdim
3179226633Sdim  return S;
3180226633Sdim}
3181226633Sdim
3182234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
3183226633Sdim                           uint64_t Address, const void *Decoder) {
3184239462Sdim  if (Val == 0)
3185239462Sdim    Inst.addOperand(MCOperand::CreateImm(INT32_MIN));
3186239462Sdim  else {
3187239462Sdim    int imm = Val & 0xFF;
3188226633Sdim
3189239462Sdim    if (!(Val & 0x100)) imm *= -1;
3190243830Sdim    Inst.addOperand(MCOperand::CreateImm(imm * 4));
3191239462Sdim  }
3192239462Sdim
3193226633Sdim  return MCDisassembler::Success;
3194226633Sdim}
3195226633Sdim
3196234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
3197226633Sdim                                   uint64_t Address, const void *Decoder) {
3198226633Sdim  DecodeStatus S = MCDisassembler::Success;
3199226633Sdim
3200239462Sdim  unsigned Rn = fieldFromInstruction(Val, 9, 4);
3201239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 9);
3202226633Sdim
3203226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3204226633Sdim    return MCDisassembler::Fail;
3205226633Sdim  if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
3206226633Sdim    return MCDisassembler::Fail;
3207226633Sdim
3208226633Sdim  return S;
3209226633Sdim}
3210226633Sdim
3211234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
3212226633Sdim                                   uint64_t Address, const void *Decoder) {
3213226633Sdim  DecodeStatus S = MCDisassembler::Success;
3214226633Sdim
3215239462Sdim  unsigned Rn = fieldFromInstruction(Val, 8, 4);
3216239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 8);
3217226633Sdim
3218226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
3219226633Sdim    return MCDisassembler::Fail;
3220226633Sdim
3221226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3222226633Sdim
3223226633Sdim  return S;
3224226633Sdim}
3225226633Sdim
3226234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
3227226633Sdim                         uint64_t Address, const void *Decoder) {
3228226633Sdim  int imm = Val & 0xFF;
3229226633Sdim  if (Val == 0)
3230226633Sdim    imm = INT32_MIN;
3231226633Sdim  else if (!(Val & 0x100))
3232226633Sdim    imm *= -1;
3233226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3234226633Sdim
3235226633Sdim  return MCDisassembler::Success;
3236226633Sdim}
3237226633Sdim
3238226633Sdim
3239234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
3240226633Sdim                                 uint64_t Address, const void *Decoder) {
3241226633Sdim  DecodeStatus S = MCDisassembler::Success;
3242226633Sdim
3243239462Sdim  unsigned Rn = fieldFromInstruction(Val, 9, 4);
3244239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 9);
3245226633Sdim
3246226633Sdim  // Some instructions always use an additive offset.
3247226633Sdim  switch (Inst.getOpcode()) {
3248226633Sdim    case ARM::t2LDRT:
3249226633Sdim    case ARM::t2LDRBT:
3250226633Sdim    case ARM::t2LDRHT:
3251226633Sdim    case ARM::t2LDRSBT:
3252226633Sdim    case ARM::t2LDRSHT:
3253226633Sdim    case ARM::t2STRT:
3254226633Sdim    case ARM::t2STRBT:
3255226633Sdim    case ARM::t2STRHT:
3256226633Sdim      imm |= 0x100;
3257226633Sdim      break;
3258226633Sdim    default:
3259226633Sdim      break;
3260226633Sdim  }
3261226633Sdim
3262226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3263226633Sdim    return MCDisassembler::Fail;
3264226633Sdim  if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
3265226633Sdim    return MCDisassembler::Fail;
3266226633Sdim
3267226633Sdim  return S;
3268226633Sdim}
3269226633Sdim
3270234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
3271226633Sdim                                    uint64_t Address, const void *Decoder) {
3272226633Sdim  DecodeStatus S = MCDisassembler::Success;
3273226633Sdim
3274239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3275239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3276239462Sdim  unsigned addr = fieldFromInstruction(Insn, 0, 8);
3277239462Sdim  addr |= fieldFromInstruction(Insn, 9, 1) << 8;
3278226633Sdim  addr |= Rn << 9;
3279239462Sdim  unsigned load = fieldFromInstruction(Insn, 20, 1);
3280226633Sdim
3281226633Sdim  if (!load) {
3282226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3283226633Sdim      return MCDisassembler::Fail;
3284226633Sdim  }
3285226633Sdim
3286249423Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3287226633Sdim    return MCDisassembler::Fail;
3288226633Sdim
3289226633Sdim  if (load) {
3290226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3291226633Sdim      return MCDisassembler::Fail;
3292226633Sdim  }
3293226633Sdim
3294226633Sdim  if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
3295226633Sdim    return MCDisassembler::Fail;
3296226633Sdim
3297226633Sdim  return S;
3298226633Sdim}
3299226633Sdim
3300234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
3301226633Sdim                                  uint64_t Address, const void *Decoder) {
3302226633Sdim  DecodeStatus S = MCDisassembler::Success;
3303226633Sdim
3304239462Sdim  unsigned Rn = fieldFromInstruction(Val, 13, 4);
3305239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 12);
3306226633Sdim
3307226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3308226633Sdim    return MCDisassembler::Fail;
3309226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3310226633Sdim
3311226633Sdim  return S;
3312226633Sdim}
3313226633Sdim
3314226633Sdim
3315234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
3316226633Sdim                                uint64_t Address, const void *Decoder) {
3317239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 7);
3318226633Sdim
3319226633Sdim  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3320226633Sdim  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3321226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3322226633Sdim
3323226633Sdim  return MCDisassembler::Success;
3324226633Sdim}
3325226633Sdim
3326234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
3327226633Sdim                                uint64_t Address, const void *Decoder) {
3328226633Sdim  DecodeStatus S = MCDisassembler::Success;
3329226633Sdim
3330226633Sdim  if (Inst.getOpcode() == ARM::tADDrSP) {
3331239462Sdim    unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
3332239462Sdim    Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
3333226633Sdim
3334226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3335226633Sdim    return MCDisassembler::Fail;
3336239462Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3337226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3338226633Sdim    return MCDisassembler::Fail;
3339226633Sdim  } else if (Inst.getOpcode() == ARM::tADDspr) {
3340239462Sdim    unsigned Rm = fieldFromInstruction(Insn, 3, 4);
3341226633Sdim
3342226633Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3343226633Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3344226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3345226633Sdim    return MCDisassembler::Fail;
3346226633Sdim  }
3347226633Sdim
3348226633Sdim  return S;
3349226633Sdim}
3350226633Sdim
3351234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
3352226633Sdim                           uint64_t Address, const void *Decoder) {
3353239462Sdim  unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
3354239462Sdim  unsigned flags = fieldFromInstruction(Insn, 0, 3);
3355226633Sdim
3356226633Sdim  Inst.addOperand(MCOperand::CreateImm(imod));
3357226633Sdim  Inst.addOperand(MCOperand::CreateImm(flags));
3358226633Sdim
3359226633Sdim  return MCDisassembler::Success;
3360226633Sdim}
3361226633Sdim
3362234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
3363226633Sdim                             uint64_t Address, const void *Decoder) {
3364226633Sdim  DecodeStatus S = MCDisassembler::Success;
3365239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3366239462Sdim  unsigned add = fieldFromInstruction(Insn, 4, 1);
3367226633Sdim
3368234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
3369226633Sdim    return MCDisassembler::Fail;
3370226633Sdim  Inst.addOperand(MCOperand::CreateImm(add));
3371226633Sdim
3372226633Sdim  return S;
3373226633Sdim}
3374226633Sdim
3375234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
3376226633Sdim                                 uint64_t Address, const void *Decoder) {
3377239462Sdim  // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
3378239462Sdim  // Note only one trailing zero not two.  Also the J1 and J2 values are from
3379239462Sdim  // the encoded instruction.  So here change to I1 and I2 values via:
3380239462Sdim  // I1 = NOT(J1 EOR S);
3381239462Sdim  // I2 = NOT(J2 EOR S);
3382239462Sdim  // and build the imm32 with two trailing zeros as documented:
3383239462Sdim  // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
3384239462Sdim  unsigned S = (Val >> 23) & 1;
3385239462Sdim  unsigned J1 = (Val >> 22) & 1;
3386239462Sdim  unsigned J2 = (Val >> 21) & 1;
3387239462Sdim  unsigned I1 = !(J1 ^ S);
3388239462Sdim  unsigned I2 = !(J2 ^ S);
3389239462Sdim  unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
3390239462Sdim  int imm32 = SignExtend32<25>(tmp << 1);
3391239462Sdim
3392234353Sdim  if (!tryAddingSymbolicOperand(Address,
3393239462Sdim                                (Address & ~2u) + imm32 + 4,
3394226633Sdim                                true, 4, Inst, Decoder))
3395239462Sdim    Inst.addOperand(MCOperand::CreateImm(imm32));
3396226633Sdim  return MCDisassembler::Success;
3397226633Sdim}
3398226633Sdim
3399234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
3400226633Sdim                              uint64_t Address, const void *Decoder) {
3401226633Sdim  if (Val == 0xA || Val == 0xB)
3402226633Sdim    return MCDisassembler::Fail;
3403226633Sdim
3404226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
3405226633Sdim  return MCDisassembler::Success;
3406226633Sdim}
3407226633Sdim
3408226633Sdimstatic DecodeStatus
3409234353SdimDecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
3410226633Sdim                       uint64_t Address, const void *Decoder) {
3411226633Sdim  DecodeStatus S = MCDisassembler::Success;
3412226633Sdim
3413239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3414239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3415226633Sdim
3416226633Sdim  if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
3417226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3418226633Sdim    return MCDisassembler::Fail;
3419226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3420226633Sdim    return MCDisassembler::Fail;
3421226633Sdim  return S;
3422226633Sdim}
3423226633Sdim
3424226633Sdimstatic DecodeStatus
3425234353SdimDecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
3426226633Sdim                           uint64_t Address, const void *Decoder) {
3427226633Sdim  DecodeStatus S = MCDisassembler::Success;
3428226633Sdim
3429239462Sdim  unsigned pred = fieldFromInstruction(Insn, 22, 4);
3430226633Sdim  if (pred == 0xE || pred == 0xF) {
3431239462Sdim    unsigned opc = fieldFromInstruction(Insn, 4, 28);
3432226633Sdim    switch (opc) {
3433226633Sdim      default:
3434226633Sdim        return MCDisassembler::Fail;
3435226633Sdim      case 0xf3bf8f4:
3436226633Sdim        Inst.setOpcode(ARM::t2DSB);
3437226633Sdim        break;
3438226633Sdim      case 0xf3bf8f5:
3439226633Sdim        Inst.setOpcode(ARM::t2DMB);
3440226633Sdim        break;
3441226633Sdim      case 0xf3bf8f6:
3442226633Sdim        Inst.setOpcode(ARM::t2ISB);
3443226633Sdim        break;
3444221345Sdim    }
3445206124Srdivacky
3446239462Sdim    unsigned imm = fieldFromInstruction(Insn, 0, 4);
3447226633Sdim    return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
3448226633Sdim  }
3449226633Sdim
3450239462Sdim  unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
3451239462Sdim  brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
3452239462Sdim  brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
3453239462Sdim  brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
3454239462Sdim  brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
3455226633Sdim
3456226633Sdim  if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
3457226633Sdim    return MCDisassembler::Fail;
3458226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3459226633Sdim    return MCDisassembler::Fail;
3460226633Sdim
3461226633Sdim  return S;
3462226633Sdim}
3463226633Sdim
3464226633Sdim// Decode a shifted immediate operand.  These basically consist
3465226633Sdim// of an 8-bit value, and a 4-bit directive that specifies either
3466226633Sdim// a splat operation or a rotation.
3467234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
3468226633Sdim                          uint64_t Address, const void *Decoder) {
3469239462Sdim  unsigned ctrl = fieldFromInstruction(Val, 10, 2);
3470226633Sdim  if (ctrl == 0) {
3471239462Sdim    unsigned byte = fieldFromInstruction(Val, 8, 2);
3472239462Sdim    unsigned imm = fieldFromInstruction(Val, 0, 8);
3473226633Sdim    switch (byte) {
3474226633Sdim      case 0:
3475226633Sdim        Inst.addOperand(MCOperand::CreateImm(imm));
3476226633Sdim        break;
3477226633Sdim      case 1:
3478226633Sdim        Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm));
3479226633Sdim        break;
3480226633Sdim      case 2:
3481226633Sdim        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8)));
3482226633Sdim        break;
3483226633Sdim      case 3:
3484226633Sdim        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) |
3485226633Sdim                                             (imm << 8)  |  imm));
3486226633Sdim        break;
3487221345Sdim    }
3488226633Sdim  } else {
3489239462Sdim    unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
3490239462Sdim    unsigned rot = fieldFromInstruction(Val, 7, 5);
3491226633Sdim    unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
3492226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
3493226633Sdim  }
3494221345Sdim
3495226633Sdim  return MCDisassembler::Success;
3496226633Sdim}
3497206124Srdivacky
3498226633Sdimstatic DecodeStatus
3499234353SdimDecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
3500226633Sdim                            uint64_t Address, const void *Decoder){
3501239462Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
3502234353Sdim                                true, 2, Inst, Decoder))
3503239462Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<9>(Val << 1)));
3504226633Sdim  return MCDisassembler::Success;
3505226633Sdim}
3506226633Sdim
3507234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
3508226633Sdim                                       uint64_t Address, const void *Decoder){
3509239462Sdim  // Val is passed in as S:J1:J2:imm10:imm11
3510239462Sdim  // Note no trailing zero after imm11.  Also the J1 and J2 values are from
3511239462Sdim  // the encoded instruction.  So here change to I1 and I2 values via:
3512239462Sdim  // I1 = NOT(J1 EOR S);
3513239462Sdim  // I2 = NOT(J2 EOR S);
3514239462Sdim  // and build the imm32 with one trailing zero as documented:
3515239462Sdim  // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
3516239462Sdim  unsigned S = (Val >> 23) & 1;
3517239462Sdim  unsigned J1 = (Val >> 22) & 1;
3518239462Sdim  unsigned J2 = (Val >> 21) & 1;
3519239462Sdim  unsigned I1 = !(J1 ^ S);
3520239462Sdim  unsigned I2 = !(J2 ^ S);
3521239462Sdim  unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
3522239462Sdim  int imm32 = SignExtend32<25>(tmp << 1);
3523239462Sdim
3524239462Sdim  if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
3525234353Sdim                                true, 4, Inst, Decoder))
3526239462Sdim    Inst.addOperand(MCOperand::CreateImm(imm32));
3527226633Sdim  return MCDisassembler::Success;
3528226633Sdim}
3529226633Sdim
3530234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
3531226633Sdim                                   uint64_t Address, const void *Decoder) {
3532239462Sdim  if (Val & ~0xf)
3533226633Sdim    return MCDisassembler::Fail;
3534206124Srdivacky
3535226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
3536226633Sdim  return MCDisassembler::Success;
3537206124Srdivacky}
3538206124Srdivacky
3539234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
3540226633Sdim                          uint64_t Address, const void *Decoder) {
3541226633Sdim  if (!Val) return MCDisassembler::Fail;
3542226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
3543226633Sdim  return MCDisassembler::Success;
3544226633Sdim}
3545206124Srdivacky
3546234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
3547226633Sdim                                        uint64_t Address, const void *Decoder) {
3548226633Sdim  DecodeStatus S = MCDisassembler::Success;
3549206124Srdivacky
3550239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3551239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3552239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
3553206124Srdivacky
3554226633Sdim  if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail;
3555206274Srdivacky
3556226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3557226633Sdim    return MCDisassembler::Fail;
3558226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
3559226633Sdim    return MCDisassembler::Fail;
3560226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3561226633Sdim    return MCDisassembler::Fail;
3562226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3563226633Sdim    return MCDisassembler::Fail;
3564206124Srdivacky
3565226633Sdim  return S;
3566226633Sdim}
3567206124Srdivacky
3568206124Srdivacky
3569234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
3570226633Sdim                                         uint64_t Address, const void *Decoder){
3571226633Sdim  DecodeStatus S = MCDisassembler::Success;
3572221345Sdim
3573239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3574239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 0, 4);
3575239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3576239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
3577206124Srdivacky
3578251662Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
3579226633Sdim    return MCDisassembler::Fail;
3580226633Sdim
3581226633Sdim  if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail;
3582226633Sdim  if (Rd == Rn || Rd == Rt || Rd == Rt+1) return MCDisassembler::Fail;
3583226633Sdim
3584226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3585226633Sdim    return MCDisassembler::Fail;
3586226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
3587226633Sdim    return MCDisassembler::Fail;
3588226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3589226633Sdim    return MCDisassembler::Fail;
3590226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3591226633Sdim    return MCDisassembler::Fail;
3592226633Sdim
3593226633Sdim  return S;
3594206124Srdivacky}
3595206124Srdivacky
3596234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
3597226633Sdim                            uint64_t Address, const void *Decoder) {
3598226633Sdim  DecodeStatus S = MCDisassembler::Success;
3599206274Srdivacky
3600239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3601239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3602239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
3603239462Sdim  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
3604239462Sdim  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
3605239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
3606206124Srdivacky
3607226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
3608206124Srdivacky
3609226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3610226633Sdim    return MCDisassembler::Fail;
3611226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3612226633Sdim    return MCDisassembler::Fail;
3613226633Sdim  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
3614226633Sdim    return MCDisassembler::Fail;
3615226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3616226633Sdim    return MCDisassembler::Fail;
3617206124Srdivacky
3618226633Sdim  return S;
3619226633Sdim}
3620206124Srdivacky
3621234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
3622226633Sdim                            uint64_t Address, const void *Decoder) {
3623226633Sdim  DecodeStatus S = MCDisassembler::Success;
3624226633Sdim
3625239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3626239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3627239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
3628239462Sdim  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
3629239462Sdim  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
3630239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
3631239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3632226633Sdim
3633226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
3634226633Sdim  if (Rm == 0xF) S = MCDisassembler::SoftFail;
3635226633Sdim
3636226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3637226633Sdim    return MCDisassembler::Fail;
3638226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3639226633Sdim    return MCDisassembler::Fail;
3640226633Sdim  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
3641226633Sdim    return MCDisassembler::Fail;
3642226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3643226633Sdim    return MCDisassembler::Fail;
3644226633Sdim
3645226633Sdim  return S;
3646226633Sdim}
3647226633Sdim
3648226633Sdim
3649234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
3650226633Sdim                            uint64_t Address, const void *Decoder) {
3651226633Sdim  DecodeStatus S = MCDisassembler::Success;
3652226633Sdim
3653239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3654239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3655239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
3656239462Sdim  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
3657239462Sdim  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
3658239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
3659226633Sdim
3660226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
3661226633Sdim
3662226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3663226633Sdim    return MCDisassembler::Fail;
3664226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3665226633Sdim    return MCDisassembler::Fail;
3666226633Sdim  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
3667226633Sdim    return MCDisassembler::Fail;
3668226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3669226633Sdim    return MCDisassembler::Fail;
3670226633Sdim
3671226633Sdim  return S;
3672226633Sdim}
3673226633Sdim
3674234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
3675226633Sdim                            uint64_t Address, const void *Decoder) {
3676226633Sdim  DecodeStatus S = MCDisassembler::Success;
3677226633Sdim
3678239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3679239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3680239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
3681239462Sdim  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
3682239462Sdim  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
3683239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
3684226633Sdim
3685226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
3686226633Sdim
3687226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3688226633Sdim    return MCDisassembler::Fail;
3689226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3690226633Sdim    return MCDisassembler::Fail;
3691226633Sdim  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
3692226633Sdim    return MCDisassembler::Fail;
3693226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3694226633Sdim    return MCDisassembler::Fail;
3695226633Sdim
3696226633Sdim  return S;
3697226633Sdim}
3698226633Sdim
3699234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
3700226633Sdim                         uint64_t Address, const void *Decoder) {
3701226633Sdim  DecodeStatus S = MCDisassembler::Success;
3702226633Sdim
3703239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3704239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3705239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3706239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3707239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
3708226633Sdim
3709226633Sdim  unsigned align = 0;
3710226633Sdim  unsigned index = 0;
3711226633Sdim  switch (size) {
3712226633Sdim    default:
3713226633Sdim      return MCDisassembler::Fail;
3714226633Sdim    case 0:
3715239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3716226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3717239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
3718226633Sdim      break;
3719226633Sdim    case 1:
3720239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
3721226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3722239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
3723239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3724226633Sdim        align = 2;
3725226633Sdim      break;
3726226633Sdim    case 2:
3727239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
3728226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3729239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
3730243830Sdim
3731243830Sdim      switch (fieldFromInstruction(Insn, 4, 2)) {
3732243830Sdim        case 0 :
3733243830Sdim          align = 0; break;
3734243830Sdim        case 3:
3735243830Sdim          align = 4; break;
3736243830Sdim        default:
3737243830Sdim          return MCDisassembler::Fail;
3738243830Sdim      }
3739243830Sdim      break;
3740206124Srdivacky  }
3741206124Srdivacky
3742226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3743226633Sdim    return MCDisassembler::Fail;
3744226633Sdim  if (Rm != 0xF) { // Writeback
3745226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3746226633Sdim      return MCDisassembler::Fail;
3747226633Sdim  }
3748226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3749226633Sdim    return MCDisassembler::Fail;
3750226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3751226633Sdim  if (Rm != 0xF) {
3752226633Sdim    if (Rm != 0xD) {
3753226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3754226633Sdim        return MCDisassembler::Fail;
3755226633Sdim    } else
3756226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3757226633Sdim  }
3758206124Srdivacky
3759226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3760226633Sdim    return MCDisassembler::Fail;
3761226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3762206124Srdivacky
3763226633Sdim  return S;
3764226633Sdim}
3765206124Srdivacky
3766234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
3767226633Sdim                         uint64_t Address, const void *Decoder) {
3768226633Sdim  DecodeStatus S = MCDisassembler::Success;
3769206124Srdivacky
3770239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3771239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3772239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3773239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3774239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
3775207618Srdivacky
3776226633Sdim  unsigned align = 0;
3777226633Sdim  unsigned index = 0;
3778226633Sdim  switch (size) {
3779226633Sdim    default:
3780226633Sdim      return MCDisassembler::Fail;
3781226633Sdim    case 0:
3782239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3783226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3784239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
3785226633Sdim      break;
3786226633Sdim    case 1:
3787239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
3788226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3789239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
3790239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3791226633Sdim        align = 2;
3792226633Sdim      break;
3793226633Sdim    case 2:
3794239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
3795226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3796239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
3797243830Sdim
3798243830Sdim      switch (fieldFromInstruction(Insn, 4, 2)) {
3799243830Sdim        case 0:
3800243830Sdim          align = 0; break;
3801243830Sdim        case 3:
3802243830Sdim          align = 4; break;
3803243830Sdim        default:
3804243830Sdim          return MCDisassembler::Fail;
3805243830Sdim      }
3806243830Sdim      break;
3807226633Sdim  }
3808221345Sdim
3809226633Sdim  if (Rm != 0xF) { // Writeback
3810226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3811226633Sdim    return MCDisassembler::Fail;
3812226633Sdim  }
3813226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3814226633Sdim    return MCDisassembler::Fail;
3815226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3816226633Sdim  if (Rm != 0xF) {
3817226633Sdim    if (Rm != 0xD) {
3818226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3819226633Sdim    return MCDisassembler::Fail;
3820226633Sdim    } else
3821226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3822226633Sdim  }
3823206124Srdivacky
3824226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3825226633Sdim    return MCDisassembler::Fail;
3826226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3827226633Sdim
3828226633Sdim  return S;
3829206124Srdivacky}
3830206124Srdivacky
3831226633Sdim
3832234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
3833226633Sdim                         uint64_t Address, const void *Decoder) {
3834226633Sdim  DecodeStatus S = MCDisassembler::Success;
3835226633Sdim
3836239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3837239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3838239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3839239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3840239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
3841226633Sdim
3842226633Sdim  unsigned align = 0;
3843226633Sdim  unsigned index = 0;
3844226633Sdim  unsigned inc = 1;
3845226633Sdim  switch (size) {
3846226633Sdim    default:
3847226633Sdim      return MCDisassembler::Fail;
3848226633Sdim    case 0:
3849239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
3850239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3851226633Sdim        align = 2;
3852226633Sdim      break;
3853226633Sdim    case 1:
3854239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
3855239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3856226633Sdim        align = 4;
3857239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
3858226633Sdim        inc = 2;
3859226633Sdim      break;
3860226633Sdim    case 2:
3861239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
3862226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3863239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
3864239462Sdim      if (fieldFromInstruction(Insn, 4, 1) != 0)
3865226633Sdim        align = 8;
3866239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
3867226633Sdim        inc = 2;
3868226633Sdim      break;
3869207618Srdivacky  }
3870226633Sdim
3871226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3872226633Sdim    return MCDisassembler::Fail;
3873226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3874226633Sdim    return MCDisassembler::Fail;
3875226633Sdim  if (Rm != 0xF) { // Writeback
3876226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3877226633Sdim      return MCDisassembler::Fail;
3878226633Sdim  }
3879226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3880226633Sdim    return MCDisassembler::Fail;
3881226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3882226633Sdim  if (Rm != 0xF) {
3883226633Sdim    if (Rm != 0xD) {
3884226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3885226633Sdim        return MCDisassembler::Fail;
3886226633Sdim    } else
3887226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3888226633Sdim  }
3889226633Sdim
3890226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3891226633Sdim    return MCDisassembler::Fail;
3892226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3893226633Sdim    return MCDisassembler::Fail;
3894226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3895226633Sdim
3896226633Sdim  return S;
3897206124Srdivacky}
3898206124Srdivacky
3899234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
3900226633Sdim                         uint64_t Address, const void *Decoder) {
3901226633Sdim  DecodeStatus S = MCDisassembler::Success;
3902207618Srdivacky
3903239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3904239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3905239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3906239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3907239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
3908226633Sdim
3909226633Sdim  unsigned align = 0;
3910226633Sdim  unsigned index = 0;
3911226633Sdim  unsigned inc = 1;
3912226633Sdim  switch (size) {
3913226633Sdim    default:
3914226633Sdim      return MCDisassembler::Fail;
3915226633Sdim    case 0:
3916239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
3917239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3918226633Sdim        align = 2;
3919226633Sdim      break;
3920226633Sdim    case 1:
3921239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
3922239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3923226633Sdim        align = 4;
3924239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
3925226633Sdim        inc = 2;
3926226633Sdim      break;
3927226633Sdim    case 2:
3928239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
3929226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3930239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
3931239462Sdim      if (fieldFromInstruction(Insn, 4, 1) != 0)
3932226633Sdim        align = 8;
3933239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
3934226633Sdim        inc = 2;
3935226633Sdim      break;
3936207618Srdivacky  }
3937226633Sdim
3938226633Sdim  if (Rm != 0xF) { // Writeback
3939226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3940226633Sdim      return MCDisassembler::Fail;
3941207618Srdivacky  }
3942226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3943226633Sdim    return MCDisassembler::Fail;
3944226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3945226633Sdim  if (Rm != 0xF) {
3946226633Sdim    if (Rm != 0xD) {
3947226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3948226633Sdim        return MCDisassembler::Fail;
3949226633Sdim    } else
3950226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3951226633Sdim  }
3952207618Srdivacky
3953226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3954226633Sdim    return MCDisassembler::Fail;
3955226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3956226633Sdim    return MCDisassembler::Fail;
3957226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3958207618Srdivacky
3959226633Sdim  return S;
3960206124Srdivacky}
3961206124Srdivacky
3962226633Sdim
3963234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
3964226633Sdim                         uint64_t Address, const void *Decoder) {
3965226633Sdim  DecodeStatus S = MCDisassembler::Success;
3966226633Sdim
3967239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3968239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3969239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3970239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3971239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
3972226633Sdim
3973226633Sdim  unsigned align = 0;
3974226633Sdim  unsigned index = 0;
3975226633Sdim  unsigned inc = 1;
3976226633Sdim  switch (size) {
3977226633Sdim    default:
3978226633Sdim      return MCDisassembler::Fail;
3979226633Sdim    case 0:
3980239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3981226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3982239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
3983226633Sdim      break;
3984226633Sdim    case 1:
3985239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
3986226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3987239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
3988239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
3989226633Sdim        inc = 2;
3990226633Sdim      break;
3991226633Sdim    case 2:
3992239462Sdim      if (fieldFromInstruction(Insn, 4, 2))
3993226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3994239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
3995239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
3996226633Sdim        inc = 2;
3997226633Sdim      break;
3998206124Srdivacky  }
3999226633Sdim
4000226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4001226633Sdim    return MCDisassembler::Fail;
4002226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4003226633Sdim    return MCDisassembler::Fail;
4004226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4005226633Sdim    return MCDisassembler::Fail;
4006226633Sdim
4007226633Sdim  if (Rm != 0xF) { // Writeback
4008226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4009226633Sdim    return MCDisassembler::Fail;
4010226633Sdim  }
4011226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4012226633Sdim    return MCDisassembler::Fail;
4013226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
4014226633Sdim  if (Rm != 0xF) {
4015226633Sdim    if (Rm != 0xD) {
4016226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4017226633Sdim    return MCDisassembler::Fail;
4018226633Sdim    } else
4019226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
4020226633Sdim  }
4021226633Sdim
4022226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4023226633Sdim    return MCDisassembler::Fail;
4024226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4025226633Sdim    return MCDisassembler::Fail;
4026226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4027226633Sdim    return MCDisassembler::Fail;
4028226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
4029226633Sdim
4030226633Sdim  return S;
4031206124Srdivacky}
4032206124Srdivacky
4033234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
4034226633Sdim                         uint64_t Address, const void *Decoder) {
4035226633Sdim  DecodeStatus S = MCDisassembler::Success;
4036226633Sdim
4037239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4038239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4039239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4040239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4041239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
4042226633Sdim
4043226633Sdim  unsigned align = 0;
4044226633Sdim  unsigned index = 0;
4045226633Sdim  unsigned inc = 1;
4046226633Sdim  switch (size) {
4047226633Sdim    default:
4048226633Sdim      return MCDisassembler::Fail;
4049226633Sdim    case 0:
4050239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4051226633Sdim        return MCDisassembler::Fail; // UNDEFINED
4052239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
4053226633Sdim      break;
4054226633Sdim    case 1:
4055239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4056226633Sdim        return MCDisassembler::Fail; // UNDEFINED
4057239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
4058239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
4059226633Sdim        inc = 2;
4060226633Sdim      break;
4061226633Sdim    case 2:
4062239462Sdim      if (fieldFromInstruction(Insn, 4, 2))
4063226633Sdim        return MCDisassembler::Fail; // UNDEFINED
4064239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
4065239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
4066226633Sdim        inc = 2;
4067226633Sdim      break;
4068226633Sdim  }
4069226633Sdim
4070226633Sdim  if (Rm != 0xF) { // Writeback
4071226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4072226633Sdim    return MCDisassembler::Fail;
4073226633Sdim  }
4074226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4075226633Sdim    return MCDisassembler::Fail;
4076226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
4077226633Sdim  if (Rm != 0xF) {
4078226633Sdim    if (Rm != 0xD) {
4079226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4080226633Sdim    return MCDisassembler::Fail;
4081226633Sdim    } else
4082226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
4083226633Sdim  }
4084226633Sdim
4085226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4086226633Sdim    return MCDisassembler::Fail;
4087226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4088226633Sdim    return MCDisassembler::Fail;
4089226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4090226633Sdim    return MCDisassembler::Fail;
4091226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
4092226633Sdim
4093226633Sdim  return S;
4094206124Srdivacky}
4095206124Srdivacky
4096226633Sdim
4097234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
4098226633Sdim                         uint64_t Address, const void *Decoder) {
4099226633Sdim  DecodeStatus S = MCDisassembler::Success;
4100226633Sdim
4101239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4102239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4103239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4104239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4105239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
4106226633Sdim
4107226633Sdim  unsigned align = 0;
4108226633Sdim  unsigned index = 0;
4109226633Sdim  unsigned inc = 1;
4110226633Sdim  switch (size) {
4111226633Sdim    default:
4112226633Sdim      return MCDisassembler::Fail;
4113226633Sdim    case 0:
4114239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4115226633Sdim        align = 4;
4116239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
4117226633Sdim      break;
4118226633Sdim    case 1:
4119239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4120226633Sdim        align = 8;
4121239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
4122239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
4123226633Sdim        inc = 2;
4124226633Sdim      break;
4125226633Sdim    case 2:
4126243830Sdim      switch (fieldFromInstruction(Insn, 4, 2)) {
4127243830Sdim        case 0:
4128243830Sdim          align = 0; break;
4129243830Sdim        case 3:
4130243830Sdim          return MCDisassembler::Fail;
4131243830Sdim        default:
4132243830Sdim          align = 4 << fieldFromInstruction(Insn, 4, 2); break;
4133243830Sdim      }
4134243830Sdim
4135239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
4136239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
4137226633Sdim        inc = 2;
4138226633Sdim      break;
4139226633Sdim  }
4140226633Sdim
4141226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4142226633Sdim    return MCDisassembler::Fail;
4143226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4144226633Sdim    return MCDisassembler::Fail;
4145226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4146226633Sdim    return MCDisassembler::Fail;
4147226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4148226633Sdim    return MCDisassembler::Fail;
4149226633Sdim
4150226633Sdim  if (Rm != 0xF) { // Writeback
4151226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4152226633Sdim      return MCDisassembler::Fail;
4153226633Sdim  }
4154226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4155226633Sdim    return MCDisassembler::Fail;
4156226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
4157226633Sdim  if (Rm != 0xF) {
4158226633Sdim    if (Rm != 0xD) {
4159226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4160226633Sdim        return MCDisassembler::Fail;
4161226633Sdim    } else
4162226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
4163226633Sdim  }
4164226633Sdim
4165226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4166226633Sdim    return MCDisassembler::Fail;
4167226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4168226633Sdim    return MCDisassembler::Fail;
4169226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4170226633Sdim    return MCDisassembler::Fail;
4171226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4172226633Sdim    return MCDisassembler::Fail;
4173226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
4174226633Sdim
4175226633Sdim  return S;
4176206124Srdivacky}
4177206124Srdivacky
4178234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
4179226633Sdim                         uint64_t Address, const void *Decoder) {
4180226633Sdim  DecodeStatus S = MCDisassembler::Success;
4181226633Sdim
4182239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4183239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4184239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4185239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4186239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
4187226633Sdim
4188226633Sdim  unsigned align = 0;
4189226633Sdim  unsigned index = 0;
4190226633Sdim  unsigned inc = 1;
4191226633Sdim  switch (size) {
4192226633Sdim    default:
4193226633Sdim      return MCDisassembler::Fail;
4194226633Sdim    case 0:
4195239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4196226633Sdim        align = 4;
4197239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
4198226633Sdim      break;
4199226633Sdim    case 1:
4200239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4201226633Sdim        align = 8;
4202239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
4203239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
4204226633Sdim        inc = 2;
4205226633Sdim      break;
4206226633Sdim    case 2:
4207243830Sdim      switch (fieldFromInstruction(Insn, 4, 2)) {
4208243830Sdim        case 0:
4209243830Sdim          align = 0; break;
4210243830Sdim        case 3:
4211243830Sdim          return MCDisassembler::Fail;
4212243830Sdim        default:
4213243830Sdim          align = 4 << fieldFromInstruction(Insn, 4, 2); break;
4214243830Sdim      }
4215243830Sdim
4216239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
4217239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
4218226633Sdim        inc = 2;
4219226633Sdim      break;
4220226633Sdim  }
4221226633Sdim
4222226633Sdim  if (Rm != 0xF) { // Writeback
4223226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4224226633Sdim    return MCDisassembler::Fail;
4225226633Sdim  }
4226226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4227226633Sdim    return MCDisassembler::Fail;
4228226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
4229226633Sdim  if (Rm != 0xF) {
4230226633Sdim    if (Rm != 0xD) {
4231226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4232226633Sdim    return MCDisassembler::Fail;
4233226633Sdim    } else
4234226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
4235226633Sdim  }
4236226633Sdim
4237226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4238226633Sdim    return MCDisassembler::Fail;
4239226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4240226633Sdim    return MCDisassembler::Fail;
4241226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4242226633Sdim    return MCDisassembler::Fail;
4243226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4244226633Sdim    return MCDisassembler::Fail;
4245226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
4246226633Sdim
4247226633Sdim  return S;
4248206124Srdivacky}
4249206124Srdivacky
4250234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
4251226633Sdim                                  uint64_t Address, const void *Decoder) {
4252226633Sdim  DecodeStatus S = MCDisassembler::Success;
4253239462Sdim  unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
4254239462Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
4255239462Sdim  unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
4256239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4257239462Sdim  Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
4258226633Sdim
4259226633Sdim  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4260226633Sdim    S = MCDisassembler::SoftFail;
4261226633Sdim
4262226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4263226633Sdim    return MCDisassembler::Fail;
4264226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4265226633Sdim    return MCDisassembler::Fail;
4266226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4267226633Sdim    return MCDisassembler::Fail;
4268226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4269226633Sdim    return MCDisassembler::Fail;
4270226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4271226633Sdim    return MCDisassembler::Fail;
4272226633Sdim
4273226633Sdim  return S;
4274207618Srdivacky}
4275207618Srdivacky
4276234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
4277226633Sdim                                  uint64_t Address, const void *Decoder) {
4278226633Sdim  DecodeStatus S = MCDisassembler::Success;
4279239462Sdim  unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
4280239462Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
4281239462Sdim  unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
4282239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4283239462Sdim  Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
4284226633Sdim
4285226633Sdim  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4286226633Sdim    S = MCDisassembler::SoftFail;
4287226633Sdim
4288226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4289226633Sdim    return MCDisassembler::Fail;
4290226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4291226633Sdim    return MCDisassembler::Fail;
4292226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4293226633Sdim    return MCDisassembler::Fail;
4294226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4295226633Sdim    return MCDisassembler::Fail;
4296226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4297226633Sdim    return MCDisassembler::Fail;
4298226633Sdim
4299226633Sdim  return S;
4300207618Srdivacky}
4301226633Sdim
4302234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn,
4303226633Sdim                             uint64_t Address, const void *Decoder) {
4304226633Sdim  DecodeStatus S = MCDisassembler::Success;
4305239462Sdim  unsigned pred = fieldFromInstruction(Insn, 4, 4);
4306239462Sdim  unsigned mask = fieldFromInstruction(Insn, 0, 4);
4307226633Sdim
4308226633Sdim  if (pred == 0xF) {
4309226633Sdim    pred = 0xE;
4310226633Sdim    S = MCDisassembler::SoftFail;
4311226633Sdim  }
4312226633Sdim
4313239462Sdim  if (mask == 0x0) {
4314226633Sdim    mask |= 0x8;
4315226633Sdim    S = MCDisassembler::SoftFail;
4316226633Sdim  }
4317226633Sdim
4318226633Sdim  Inst.addOperand(MCOperand::CreateImm(pred));
4319226633Sdim  Inst.addOperand(MCOperand::CreateImm(mask));
4320226633Sdim  return S;
4321226633Sdim}
4322226633Sdim
4323226633Sdimstatic DecodeStatus
4324234353SdimDecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
4325226633Sdim                           uint64_t Address, const void *Decoder) {
4326226633Sdim  DecodeStatus S = MCDisassembler::Success;
4327226633Sdim
4328239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4329239462Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
4330239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4331239462Sdim  unsigned addr = fieldFromInstruction(Insn, 0, 8);
4332239462Sdim  unsigned W = fieldFromInstruction(Insn, 21, 1);
4333239462Sdim  unsigned U = fieldFromInstruction(Insn, 23, 1);
4334239462Sdim  unsigned P = fieldFromInstruction(Insn, 24, 1);
4335226633Sdim  bool writeback = (W == 1) | (P == 0);
4336226633Sdim
4337226633Sdim  addr |= (U << 8) | (Rn << 9);
4338226633Sdim
4339226633Sdim  if (writeback && (Rn == Rt || Rn == Rt2))
4340226633Sdim    Check(S, MCDisassembler::SoftFail);
4341226633Sdim  if (Rt == Rt2)
4342226633Sdim    Check(S, MCDisassembler::SoftFail);
4343226633Sdim
4344226633Sdim  // Rt
4345226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4346226633Sdim    return MCDisassembler::Fail;
4347226633Sdim  // Rt2
4348226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4349226633Sdim    return MCDisassembler::Fail;
4350226633Sdim  // Writeback operand
4351226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4352226633Sdim    return MCDisassembler::Fail;
4353226633Sdim  // addr
4354226633Sdim  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4355226633Sdim    return MCDisassembler::Fail;
4356226633Sdim
4357226633Sdim  return S;
4358226633Sdim}
4359226633Sdim
4360226633Sdimstatic DecodeStatus
4361234353SdimDecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
4362226633Sdim                           uint64_t Address, const void *Decoder) {
4363226633Sdim  DecodeStatus S = MCDisassembler::Success;
4364226633Sdim
4365239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4366239462Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
4367239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4368239462Sdim  unsigned addr = fieldFromInstruction(Insn, 0, 8);
4369239462Sdim  unsigned W = fieldFromInstruction(Insn, 21, 1);
4370239462Sdim  unsigned U = fieldFromInstruction(Insn, 23, 1);
4371239462Sdim  unsigned P = fieldFromInstruction(Insn, 24, 1);
4372226633Sdim  bool writeback = (W == 1) | (P == 0);
4373226633Sdim
4374226633Sdim  addr |= (U << 8) | (Rn << 9);
4375226633Sdim
4376226633Sdim  if (writeback && (Rn == Rt || Rn == Rt2))
4377226633Sdim    Check(S, MCDisassembler::SoftFail);
4378226633Sdim
4379226633Sdim  // Writeback operand
4380226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4381226633Sdim    return MCDisassembler::Fail;
4382226633Sdim  // Rt
4383226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4384226633Sdim    return MCDisassembler::Fail;
4385226633Sdim  // Rt2
4386226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4387226633Sdim    return MCDisassembler::Fail;
4388226633Sdim  // addr
4389226633Sdim  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4390226633Sdim    return MCDisassembler::Fail;
4391226633Sdim
4392226633Sdim  return S;
4393226633Sdim}
4394226633Sdim
4395234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn,
4396226633Sdim                                uint64_t Address, const void *Decoder) {
4397239462Sdim  unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
4398239462Sdim  unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
4399226633Sdim  if (sign1 != sign2) return MCDisassembler::Fail;
4400226633Sdim
4401239462Sdim  unsigned Val = fieldFromInstruction(Insn, 0, 8);
4402239462Sdim  Val |= fieldFromInstruction(Insn, 12, 3) << 8;
4403239462Sdim  Val |= fieldFromInstruction(Insn, 26, 1) << 11;
4404226633Sdim  Val |= sign1 << 12;
4405226633Sdim  Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val)));
4406226633Sdim
4407226633Sdim  return MCDisassembler::Success;
4408226633Sdim}
4409226633Sdim
4410234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
4411226633Sdim                                              uint64_t Address,
4412226633Sdim                                              const void *Decoder) {
4413226633Sdim  DecodeStatus S = MCDisassembler::Success;
4414226633Sdim
4415226633Sdim  // Shift of "asr #32" is not allowed in Thumb2 mode.
4416226633Sdim  if (Val == 0x20) S = MCDisassembler::SoftFail;
4417226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
4418226633Sdim  return S;
4419226633Sdim}
4420226633Sdim
4421234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
4422234353Sdim                               uint64_t Address, const void *Decoder) {
4423239462Sdim  unsigned Rt   = fieldFromInstruction(Insn, 12, 4);
4424239462Sdim  unsigned Rt2  = fieldFromInstruction(Insn, 0,  4);
4425239462Sdim  unsigned Rn   = fieldFromInstruction(Insn, 16, 4);
4426239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4427234353Sdim
4428234353Sdim  if (pred == 0xF)
4429234353Sdim    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
4430234353Sdim
4431234353Sdim  DecodeStatus S = MCDisassembler::Success;
4432234982Sdim
4433234982Sdim  if (Rt == Rn || Rn == Rt2)
4434234982Sdim    S = MCDisassembler::SoftFail;
4435234982Sdim
4436234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4437234353Sdim    return MCDisassembler::Fail;
4438234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
4439234353Sdim    return MCDisassembler::Fail;
4440234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4441234353Sdim    return MCDisassembler::Fail;
4442234353Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4443234353Sdim    return MCDisassembler::Fail;
4444234353Sdim
4445234353Sdim  return S;
4446234353Sdim}
4447234353Sdim
4448234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
4449234353Sdim                                uint64_t Address, const void *Decoder) {
4450239462Sdim  unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
4451239462Sdim  Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
4452239462Sdim  unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
4453239462Sdim  Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
4454239462Sdim  unsigned imm = fieldFromInstruction(Insn, 16, 6);
4455239462Sdim  unsigned cmode = fieldFromInstruction(Insn, 8, 4);
4456234353Sdim
4457234353Sdim  DecodeStatus S = MCDisassembler::Success;
4458234353Sdim
4459234353Sdim  // VMOVv2f32 is ambiguous with these decodings.
4460234353Sdim  if (!(imm & 0x38) && cmode == 0xF) {
4461234353Sdim    Inst.setOpcode(ARM::VMOVv2f32);
4462234353Sdim    return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
4463234353Sdim  }
4464234353Sdim
4465234353Sdim  if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail);
4466234353Sdim
4467234353Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
4468234353Sdim    return MCDisassembler::Fail;
4469234353Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
4470234353Sdim    return MCDisassembler::Fail;
4471234353Sdim  Inst.addOperand(MCOperand::CreateImm(64 - imm));
4472234353Sdim
4473234353Sdim  return S;
4474234353Sdim}
4475234353Sdim
4476234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
4477234353Sdim                                uint64_t Address, const void *Decoder) {
4478239462Sdim  unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
4479239462Sdim  Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
4480239462Sdim  unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
4481239462Sdim  Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
4482239462Sdim  unsigned imm = fieldFromInstruction(Insn, 16, 6);
4483239462Sdim  unsigned cmode = fieldFromInstruction(Insn, 8, 4);
4484234353Sdim
4485234353Sdim  DecodeStatus S = MCDisassembler::Success;
4486234353Sdim
4487234353Sdim  // VMOVv4f32 is ambiguous with these decodings.
4488234353Sdim  if (!(imm & 0x38) && cmode == 0xF) {
4489234353Sdim    Inst.setOpcode(ARM::VMOVv4f32);
4490234353Sdim    return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
4491234353Sdim  }
4492234353Sdim
4493234353Sdim  if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail);
4494234353Sdim
4495234353Sdim  if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
4496234353Sdim    return MCDisassembler::Fail;
4497234353Sdim  if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
4498234353Sdim    return MCDisassembler::Fail;
4499234353Sdim  Inst.addOperand(MCOperand::CreateImm(64 - imm));
4500234353Sdim
4501234353Sdim  return S;
4502234353Sdim}
4503234353Sdim
4504251662Sdimstatic DecodeStatus DecodeImm0_4(MCInst &Inst, unsigned Insn, uint64_t Address,
4505251662Sdim                                 const void *Decoder)
4506251662Sdim{
4507251662Sdim  unsigned Imm = fieldFromInstruction(Insn, 0, 3);
4508251662Sdim  if (Imm > 4) return MCDisassembler::Fail;
4509251662Sdim  Inst.addOperand(MCOperand::CreateImm(Imm));
4510251662Sdim  return MCDisassembler::Success;
4511251662Sdim}
4512251662Sdim
4513234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
4514234353Sdim                                uint64_t Address, const void *Decoder) {
4515234353Sdim  DecodeStatus S = MCDisassembler::Success;
4516234353Sdim
4517239462Sdim  unsigned Rn = fieldFromInstruction(Val, 16, 4);
4518239462Sdim  unsigned Rt = fieldFromInstruction(Val, 12, 4);
4519239462Sdim  unsigned Rm = fieldFromInstruction(Val, 0, 4);
4520239462Sdim  Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
4521239462Sdim  unsigned Cond = fieldFromInstruction(Val, 28, 4);
4522234353Sdim
4523239462Sdim  if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
4524234353Sdim    S = MCDisassembler::SoftFail;
4525234353Sdim
4526234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4527234353Sdim    return MCDisassembler::Fail;
4528234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4529234353Sdim    return MCDisassembler::Fail;
4530234353Sdim  if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
4531234353Sdim    return MCDisassembler::Fail;
4532234353Sdim  if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
4533234353Sdim    return MCDisassembler::Fail;
4534234353Sdim  if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
4535234353Sdim    return MCDisassembler::Fail;
4536234353Sdim
4537234353Sdim  return S;
4538234353Sdim}
4539234353Sdim
4540234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
4541234982Sdim                                uint64_t Address, const void *Decoder) {
4542234982Sdim
4543234982Sdim  DecodeStatus S = MCDisassembler::Success;
4544234982Sdim
4545239462Sdim  unsigned CRm = fieldFromInstruction(Val, 0, 4);
4546239462Sdim  unsigned opc1 = fieldFromInstruction(Val, 4, 4);
4547239462Sdim  unsigned cop = fieldFromInstruction(Val, 8, 4);
4548239462Sdim  unsigned Rt = fieldFromInstruction(Val, 12, 4);
4549239462Sdim  unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
4550234982Sdim
4551234982Sdim  if ((cop & ~0x1) == 0xa)
4552234982Sdim    return MCDisassembler::Fail;
4553234982Sdim
4554234982Sdim  if (Rt == Rt2)
4555234982Sdim    S = MCDisassembler::SoftFail;
4556234982Sdim
4557234982Sdim  Inst.addOperand(MCOperand::CreateImm(cop));
4558234982Sdim  Inst.addOperand(MCOperand::CreateImm(opc1));
4559234982Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4560234982Sdim    return MCDisassembler::Fail;
4561234982Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
4562234982Sdim    return MCDisassembler::Fail;
4563234982Sdim  Inst.addOperand(MCOperand::CreateImm(CRm));
4564234982Sdim
4565234982Sdim  return S;
4566234982Sdim}
4567234982Sdim
4568