ARMDisassembler.cpp revision 234982
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
12226633Sdim#include "MCTargetDesc/ARMAddressingModes.h"
13226633Sdim#include "MCTargetDesc/ARMMCExpr.h"
14226633Sdim#include "MCTargetDesc/ARMBaseInfo.h"
15207618Srdivacky#include "llvm/MC/EDInstInfo.h"
16206124Srdivacky#include "llvm/MC/MCInst.h"
17234353Sdim#include "llvm/MC/MCInstrDesc.h"
18226633Sdim#include "llvm/MC/MCExpr.h"
19226633Sdim#include "llvm/MC/MCContext.h"
20226633Sdim#include "llvm/MC/MCDisassembler.h"
21234353Sdim#include "llvm/MC/MCSubtargetInfo.h"
22206124Srdivacky#include "llvm/Support/Debug.h"
23206124Srdivacky#include "llvm/Support/MemoryObject.h"
24206124Srdivacky#include "llvm/Support/ErrorHandling.h"
25226633Sdim#include "llvm/Support/TargetRegistry.h"
26206124Srdivacky#include "llvm/Support/raw_ostream.h"
27206124Srdivacky
28226633Sdimusing namespace llvm;
29212904Sdim
30226633Sdimtypedef MCDisassembler::DecodeStatus DecodeStatus;
31206124Srdivacky
32226633Sdimnamespace {
33226633Sdim/// ARMDisassembler - ARM disassembler for all ARM platforms.
34226633Sdimclass ARMDisassembler : public MCDisassembler {
35226633Sdimpublic:
36226633Sdim  /// Constructor     - Initializes the disassembler.
37226633Sdim  ///
38226633Sdim  ARMDisassembler(const MCSubtargetInfo &STI) :
39226633Sdim    MCDisassembler(STI) {
40226633Sdim  }
41226633Sdim
42226633Sdim  ~ARMDisassembler() {
43226633Sdim  }
44226633Sdim
45226633Sdim  /// getInstruction - See MCDisassembler.
46226633Sdim  DecodeStatus getInstruction(MCInst &instr,
47226633Sdim                              uint64_t &size,
48226633Sdim                              const MemoryObject &region,
49226633Sdim                              uint64_t address,
50226633Sdim                              raw_ostream &vStream,
51226633Sdim                              raw_ostream &cStream) const;
52226633Sdim
53226633Sdim  /// getEDInfo - See MCDisassembler.
54234353Sdim  const EDInstInfo *getEDInfo() const;
55226633Sdimprivate:
56226633Sdim};
57226633Sdim
58226633Sdim/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.
59226633Sdimclass ThumbDisassembler : public MCDisassembler {
60226633Sdimpublic:
61226633Sdim  /// Constructor     - Initializes the disassembler.
62226633Sdim  ///
63226633Sdim  ThumbDisassembler(const MCSubtargetInfo &STI) :
64226633Sdim    MCDisassembler(STI) {
65226633Sdim  }
66226633Sdim
67226633Sdim  ~ThumbDisassembler() {
68226633Sdim  }
69226633Sdim
70226633Sdim  /// getInstruction - See MCDisassembler.
71226633Sdim  DecodeStatus getInstruction(MCInst &instr,
72226633Sdim                              uint64_t &size,
73226633Sdim                              const MemoryObject &region,
74226633Sdim                              uint64_t address,
75226633Sdim                              raw_ostream &vStream,
76226633Sdim                              raw_ostream &cStream) const;
77226633Sdim
78226633Sdim  /// getEDInfo - See MCDisassembler.
79234353Sdim  const EDInstInfo *getEDInfo() const;
80226633Sdimprivate:
81226633Sdim  mutable std::vector<unsigned> ITBlock;
82226633Sdim  DecodeStatus AddThumbPredicate(MCInst&) const;
83226633Sdim  void UpdateThumbVFPPredicate(MCInst&) const;
84226633Sdim};
85226633Sdim}
86226633Sdim
87226633Sdimstatic bool Check(DecodeStatus &Out, DecodeStatus In) {
88226633Sdim  switch (In) {
89226633Sdim    case MCDisassembler::Success:
90226633Sdim      // Out stays the same.
91226633Sdim      return true;
92226633Sdim    case MCDisassembler::SoftFail:
93226633Sdim      Out = In;
94226633Sdim      return true;
95226633Sdim    case MCDisassembler::Fail:
96226633Sdim      Out = In;
97226633Sdim      return false;
98226633Sdim  }
99234353Sdim  llvm_unreachable("Invalid DecodeStatus!");
100226633Sdim}
101226633Sdim
102226633Sdim
103226633Sdim// Forward declare these because the autogenerated code will reference them.
104226633Sdim// Definitions are further down.
105234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
106226633Sdim                                   uint64_t Address, const void *Decoder);
107234353Sdimstatic DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst,
108226633Sdim                                               unsigned RegNo, uint64_t Address,
109226633Sdim                                               const void *Decoder);
110234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
111226633Sdim                                   uint64_t Address, const void *Decoder);
112234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
113226633Sdim                                   uint64_t Address, const void *Decoder);
114234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
115226633Sdim                                   uint64_t Address, const void *Decoder);
116234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
117226633Sdim                                   uint64_t Address, const void *Decoder);
118234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
119226633Sdim                                   uint64_t Address, const void *Decoder);
120234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
121226633Sdim                                   uint64_t Address, const void *Decoder);
122234353Sdimstatic DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
123226633Sdim                                                unsigned RegNo,
124226633Sdim                                                uint64_t Address,
125226633Sdim                                                const void *Decoder);
126234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
127226633Sdim                                   uint64_t Address, const void *Decoder);
128234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
129234353Sdim                                   uint64_t Address, const void *Decoder);
130234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
131234353Sdim                               unsigned RegNo, uint64_t Address,
132234353Sdim                               const void *Decoder);
133226633Sdim
134234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
135226633Sdim                               uint64_t Address, const void *Decoder);
136234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
137226633Sdim                               uint64_t Address, const void *Decoder);
138234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val,
139226633Sdim                               uint64_t Address, const void *Decoder);
140234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
141226633Sdim                               uint64_t Address, const void *Decoder);
142234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
143226633Sdim                               uint64_t Address, const void *Decoder);
144234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
145226633Sdim                               uint64_t Address, const void *Decoder);
146226633Sdim
147234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
148226633Sdim                               uint64_t Address, const void *Decoder);
149234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
150226633Sdim                               uint64_t Address, const void *Decoder);
151234353Sdimstatic DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst,
152226633Sdim                                                  unsigned Insn,
153226633Sdim                                                  uint64_t Address,
154226633Sdim                                                  const void *Decoder);
155234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
156226633Sdim                               uint64_t Address, const void *Decoder);
157234353Sdimstatic DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn,
158226633Sdim                               uint64_t Address, const void *Decoder);
159234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
160226633Sdim                               uint64_t Address, const void *Decoder);
161234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
162226633Sdim                               uint64_t Address, const void *Decoder);
163226633Sdim
164234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst,
165226633Sdim                                                  unsigned Insn,
166226633Sdim                                                  uint64_t Adddress,
167226633Sdim                                                  const void *Decoder);
168234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
169226633Sdim                               uint64_t Address, const void *Decoder);
170234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
171226633Sdim                               uint64_t Address, const void *Decoder);
172234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
173226633Sdim                               uint64_t Address, const void *Decoder);
174234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
175226633Sdim                               uint64_t Address, const void *Decoder);
176234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
177226633Sdim                               uint64_t Address, const void *Decoder);
178234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
179226633Sdim                               uint64_t Address, const void *Decoder);
180234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
181226633Sdim                               uint64_t Address, const void *Decoder);
182234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
183226633Sdim                               uint64_t Address, const void *Decoder);
184234353Sdimstatic DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
185226633Sdim                               uint64_t Address, const void *Decoder);
186234353Sdimstatic DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn,
187226633Sdim                               uint64_t Address, const void *Decoder);
188234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
189226633Sdim                               uint64_t Address, const void *Decoder);
190234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
191226633Sdim                               uint64_t Address, const void *Decoder);
192234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
193226633Sdim                               uint64_t Address, const void *Decoder);
194234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
195226633Sdim                               uint64_t Address, const void *Decoder);
196234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
197226633Sdim                               uint64_t Address, const void *Decoder);
198234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
199226633Sdim                               uint64_t Address, const void *Decoder);
200234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
201226633Sdim                               uint64_t Address, const void *Decoder);
202234353Sdimstatic DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val,
203226633Sdim                               uint64_t Address, const void *Decoder);
204234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
205226633Sdim                               uint64_t Address, const void *Decoder);
206234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
207226633Sdim                               uint64_t Address, const void *Decoder);
208234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
209226633Sdim                               uint64_t Address, const void *Decoder);
210234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
211226633Sdim                               uint64_t Address, const void *Decoder);
212234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
213226633Sdim                               uint64_t Address, const void *Decoder);
214234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
215226633Sdim                               uint64_t Address, const void *Decoder);
216234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
217226633Sdim                               uint64_t Address, const void *Decoder);
218234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
219226633Sdim                               uint64_t Address, const void *Decoder);
220234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
221226633Sdim                               uint64_t Address, const void *Decoder);
222234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
223226633Sdim                               uint64_t Address, const void *Decoder);
224234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
225226633Sdim                               uint64_t Address, const void *Decoder);
226234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
227226633Sdim                               uint64_t Address, const void *Decoder);
228234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
229226633Sdim                               uint64_t Address, const void *Decoder);
230234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
231226633Sdim                               uint64_t Address, const void *Decoder);
232234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
233226633Sdim                               uint64_t Address, const void *Decoder);
234234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
235226633Sdim                               uint64_t Address, const void *Decoder);
236234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
237226633Sdim                               uint64_t Address, const void *Decoder);
238234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
239226633Sdim                               uint64_t Address, const void *Decoder);
240234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
241226633Sdim                               uint64_t Address, const void *Decoder);
242234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
243226633Sdim                               uint64_t Address, const void *Decoder);
244234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
245226633Sdim                               uint64_t Address, const void *Decoder);
246234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
247226633Sdim                               uint64_t Address, const void *Decoder);
248234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
249226633Sdim                               uint64_t Address, const void *Decoder);
250234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
251226633Sdim                               uint64_t Address, const void *Decoder);
252234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
253226633Sdim                               uint64_t Address, const void *Decoder);
254234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
255226633Sdim                               uint64_t Address, const void *Decoder);
256234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
257234353Sdim                               uint64_t Address, const void *Decoder);
258234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
259234353Sdim                                uint64_t Address, const void *Decoder);
260234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
261234353Sdim                                uint64_t Address, const void *Decoder);
262226633Sdim
263234353Sdim
264234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
265226633Sdim                               uint64_t Address, const void *Decoder);
266234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
267226633Sdim                               uint64_t Address, const void *Decoder);
268234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
269226633Sdim                               uint64_t Address, const void *Decoder);
270234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
271226633Sdim                               uint64_t Address, const void *Decoder);
272234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
273226633Sdim                               uint64_t Address, const void *Decoder);
274234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
275226633Sdim                               uint64_t Address, const void *Decoder);
276234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
277226633Sdim                               uint64_t Address, const void *Decoder);
278234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
279226633Sdim                               uint64_t Address, const void *Decoder);
280234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
281226633Sdim                               uint64_t Address, const void *Decoder);
282234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
283226633Sdim                               uint64_t Address, const void *Decoder);
284234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
285226633Sdim                               uint64_t Address, const void *Decoder);
286234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
287226633Sdim                               uint64_t Address, const void *Decoder);
288234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
289226633Sdim                               uint64_t Address, const void *Decoder);
290234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
291226633Sdim                               uint64_t Address, const void *Decoder);
292234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
293226633Sdim                               uint64_t Address, const void *Decoder);
294234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
295226633Sdim                               uint64_t Address, const void *Decoder);
296234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
297226633Sdim                                uint64_t Address, const void *Decoder);
298234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
299226633Sdim                                uint64_t Address, const void *Decoder);
300234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
301226633Sdim                                uint64_t Address, const void *Decoder);
302234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
303226633Sdim                                uint64_t Address, const void *Decoder);
304234353Sdimstatic DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
305226633Sdim                                uint64_t Address, const void *Decoder);
306234353Sdimstatic DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
307226633Sdim                                uint64_t Address, const void *Decoder);
308234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
309226633Sdim                                uint64_t Address, const void *Decoder);
310234353Sdimstatic DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val,
311226633Sdim                                uint64_t Address, const void *Decoder);
312234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
313226633Sdim                                uint64_t Address, const void *Decoder);
314234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Val,
315226633Sdim                                uint64_t Address, const void *Decoder);
316234353Sdimstatic DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn,
317226633Sdim                               uint64_t Address, const void *Decoder);
318234353Sdimstatic DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn,
319226633Sdim                               uint64_t Address, const void *Decoder);
320234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val,
321226633Sdim                                uint64_t Address, const void *Decoder);
322234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
323226633Sdim                                uint64_t Address, const void *Decoder);
324234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
325226633Sdim                                uint64_t Address, const void *Decoder);
326226633Sdim
327234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
328234353Sdim                                uint64_t Address, const void *Decoder);
329234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
330234982Sdim                                uint64_t Address, const void *Decoder);
331226633Sdim#include "ARMGenDisassemblerTables.inc"
332226633Sdim#include "ARMGenInstrInfo.inc"
333218893Sdim#include "ARMGenEDInfo.inc"
334206124Srdivacky
335226633Sdimstatic MCDisassembler *createARMDisassembler(const Target &T, const MCSubtargetInfo &STI) {
336226633Sdim  return new ARMDisassembler(STI);
337226633Sdim}
338207618Srdivacky
339226633Sdimstatic MCDisassembler *createThumbDisassembler(const Target &T, const MCSubtargetInfo &STI) {
340226633Sdim  return new ThumbDisassembler(STI);
341226633Sdim}
342226633Sdim
343234353Sdimconst EDInstInfo *ARMDisassembler::getEDInfo() const {
344226633Sdim  return instInfoARM;
345226633Sdim}
346226633Sdim
347234353Sdimconst EDInstInfo *ThumbDisassembler::getEDInfo() const {
348226633Sdim  return instInfoARM;
349226633Sdim}
350226633Sdim
351226633SdimDecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
352226633Sdim                                             const MemoryObject &Region,
353226633Sdim                                             uint64_t Address,
354226633Sdim                                             raw_ostream &os,
355226633Sdim                                             raw_ostream &cs) const {
356226633Sdim  CommentStream = &cs;
357226633Sdim
358226633Sdim  uint8_t bytes[4];
359226633Sdim
360226633Sdim  assert(!(STI.getFeatureBits() & ARM::ModeThumb) &&
361226633Sdim         "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!");
362226633Sdim
363226633Sdim  // We want to read exactly 4 bytes of data.
364226633Sdim  if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
365226633Sdim    Size = 0;
366226633Sdim    return MCDisassembler::Fail;
367206124Srdivacky  }
368226633Sdim
369226633Sdim  // Encoded as a small-endian 32-bit word in the stream.
370226633Sdim  uint32_t insn = (bytes[3] << 24) |
371226633Sdim                  (bytes[2] << 16) |
372226633Sdim                  (bytes[1] <<  8) |
373226633Sdim                  (bytes[0] <<  0);
374226633Sdim
375226633Sdim  // Calling the auto-generated decoder function.
376226633Sdim  DecodeStatus result = decodeARMInstruction32(MI, insn, Address, this, STI);
377226633Sdim  if (result != MCDisassembler::Fail) {
378226633Sdim    Size = 4;
379226633Sdim    return result;
380226633Sdim  }
381226633Sdim
382226633Sdim  // VFP and NEON instructions, similarly, are shared between ARM
383226633Sdim  // and Thumb modes.
384226633Sdim  MI.clear();
385226633Sdim  result = decodeVFPInstruction32(MI, insn, Address, this, STI);
386226633Sdim  if (result != MCDisassembler::Fail) {
387226633Sdim    Size = 4;
388226633Sdim    return result;
389226633Sdim  }
390226633Sdim
391226633Sdim  MI.clear();
392226633Sdim  result = decodeNEONDataInstruction32(MI, insn, Address, this, STI);
393226633Sdim  if (result != MCDisassembler::Fail) {
394226633Sdim    Size = 4;
395226633Sdim    // Add a fake predicate operand, because we share these instruction
396226633Sdim    // definitions with Thumb2 where these instructions are predicable.
397226633Sdim    if (!DecodePredicateOperand(MI, 0xE, Address, this))
398226633Sdim      return MCDisassembler::Fail;
399226633Sdim    return result;
400226633Sdim  }
401226633Sdim
402226633Sdim  MI.clear();
403226633Sdim  result = decodeNEONLoadStoreInstruction32(MI, insn, Address, this, STI);
404226633Sdim  if (result != MCDisassembler::Fail) {
405226633Sdim    Size = 4;
406226633Sdim    // Add a fake predicate operand, because we share these instruction
407226633Sdim    // definitions with Thumb2 where these instructions are predicable.
408226633Sdim    if (!DecodePredicateOperand(MI, 0xE, Address, this))
409226633Sdim      return MCDisassembler::Fail;
410226633Sdim    return result;
411226633Sdim  }
412226633Sdim
413226633Sdim  MI.clear();
414226633Sdim  result = decodeNEONDupInstruction32(MI, insn, Address, this, STI);
415226633Sdim  if (result != MCDisassembler::Fail) {
416226633Sdim    Size = 4;
417226633Sdim    // Add a fake predicate operand, because we share these instruction
418226633Sdim    // definitions with Thumb2 where these instructions are predicable.
419226633Sdim    if (!DecodePredicateOperand(MI, 0xE, Address, this))
420226633Sdim      return MCDisassembler::Fail;
421226633Sdim    return result;
422226633Sdim  }
423226633Sdim
424226633Sdim  MI.clear();
425226633Sdim
426226633Sdim  Size = 0;
427226633Sdim  return MCDisassembler::Fail;
428206124Srdivacky}
429206124Srdivacky
430226633Sdimnamespace llvm {
431234353Sdimextern const MCInstrDesc ARMInsts[];
432226633Sdim}
433206124Srdivacky
434226633Sdim/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
435226633Sdim/// immediate Value in the MCInst.  The immediate Value has had any PC
436226633Sdim/// adjustment made by the caller.  If the instruction is a branch instruction
437226633Sdim/// then isBranch is true, else false.  If the getOpInfo() function was set as
438226633Sdim/// part of the setupForSymbolicDisassembly() call then that function is called
439226633Sdim/// to get any symbolic information at the Address for this instruction.  If
440226633Sdim/// that returns non-zero then the symbolic information it returns is used to
441226633Sdim/// create an MCExpr and that is added as an operand to the MCInst.  If
442226633Sdim/// getOpInfo() returns zero and isBranch is true then a symbol look up for
443226633Sdim/// Value is done and if a symbol is found an MCExpr is created with that, else
444226633Sdim/// an MCExpr with Value is created.  This function returns true if it adds an
445226633Sdim/// operand to the MCInst and false otherwise.
446226633Sdimstatic bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
447226633Sdim                                     bool isBranch, uint64_t InstSize,
448226633Sdim                                     MCInst &MI, const void *Decoder) {
449226633Sdim  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
450226633Sdim  LLVMOpInfoCallback getOpInfo = Dis->getLLVMOpInfoCallback();
451226633Sdim  struct LLVMOpInfo1 SymbolicOp;
452234353Sdim  memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1));
453226633Sdim  SymbolicOp.Value = Value;
454226633Sdim  void *DisInfo = Dis->getDisInfoBlock();
455234353Sdim
456234353Sdim  if (!getOpInfo ||
457234353Sdim      !getOpInfo(DisInfo, Address, 0 /* Offset */, InstSize, 1, &SymbolicOp)) {
458234353Sdim    // Clear SymbolicOp.Value from above and also all other fields.
459234353Sdim    memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1));
460234353Sdim    LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback();
461234353Sdim    if (!SymbolLookUp)
462234353Sdim      return false;
463234353Sdim    uint64_t ReferenceType;
464234353Sdim    if (isBranch)
465234353Sdim       ReferenceType = LLVMDisassembler_ReferenceType_In_Branch;
466234353Sdim    else
467234353Sdim       ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
468234353Sdim    const char *ReferenceName;
469234353Sdim    const char *Name = SymbolLookUp(DisInfo, Value, &ReferenceType, Address,
470234353Sdim                                    &ReferenceName);
471234353Sdim    if (Name) {
472234353Sdim      SymbolicOp.AddSymbol.Name = Name;
473234353Sdim      SymbolicOp.AddSymbol.Present = true;
474226633Sdim    }
475234353Sdim    // For branches always create an MCExpr so it gets printed as hex address.
476234353Sdim    else if (isBranch) {
477234353Sdim      SymbolicOp.Value = Value;
478234353Sdim    }
479234353Sdim    if(ReferenceType == LLVMDisassembler_ReferenceType_Out_SymbolStub)
480234353Sdim      (*Dis->CommentStream) << "symbol stub for: " << ReferenceName;
481234353Sdim    if (!Name && !isBranch)
482226633Sdim      return false;
483226633Sdim  }
484226633Sdim
485226633Sdim  MCContext *Ctx = Dis->getMCContext();
486226633Sdim  const MCExpr *Add = NULL;
487226633Sdim  if (SymbolicOp.AddSymbol.Present) {
488226633Sdim    if (SymbolicOp.AddSymbol.Name) {
489226633Sdim      StringRef Name(SymbolicOp.AddSymbol.Name);
490226633Sdim      MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name);
491226633Sdim      Add = MCSymbolRefExpr::Create(Sym, *Ctx);
492226633Sdim    } else {
493226633Sdim      Add = MCConstantExpr::Create(SymbolicOp.AddSymbol.Value, *Ctx);
494226633Sdim    }
495226633Sdim  }
496226633Sdim
497226633Sdim  const MCExpr *Sub = NULL;
498226633Sdim  if (SymbolicOp.SubtractSymbol.Present) {
499226633Sdim    if (SymbolicOp.SubtractSymbol.Name) {
500226633Sdim      StringRef Name(SymbolicOp.SubtractSymbol.Name);
501226633Sdim      MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name);
502226633Sdim      Sub = MCSymbolRefExpr::Create(Sym, *Ctx);
503226633Sdim    } else {
504226633Sdim      Sub = MCConstantExpr::Create(SymbolicOp.SubtractSymbol.Value, *Ctx);
505226633Sdim    }
506226633Sdim  }
507226633Sdim
508226633Sdim  const MCExpr *Off = NULL;
509226633Sdim  if (SymbolicOp.Value != 0)
510226633Sdim    Off = MCConstantExpr::Create(SymbolicOp.Value, *Ctx);
511226633Sdim
512226633Sdim  const MCExpr *Expr;
513226633Sdim  if (Sub) {
514226633Sdim    const MCExpr *LHS;
515226633Sdim    if (Add)
516226633Sdim      LHS = MCBinaryExpr::CreateSub(Add, Sub, *Ctx);
517206124Srdivacky    else
518226633Sdim      LHS = MCUnaryExpr::CreateMinus(Sub, *Ctx);
519226633Sdim    if (Off != 0)
520226633Sdim      Expr = MCBinaryExpr::CreateAdd(LHS, Off, *Ctx);
521226633Sdim    else
522226633Sdim      Expr = LHS;
523226633Sdim  } else if (Add) {
524226633Sdim    if (Off != 0)
525226633Sdim      Expr = MCBinaryExpr::CreateAdd(Add, Off, *Ctx);
526226633Sdim    else
527226633Sdim      Expr = Add;
528226633Sdim  } else {
529226633Sdim    if (Off != 0)
530226633Sdim      Expr = Off;
531226633Sdim    else
532226633Sdim      Expr = MCConstantExpr::Create(0, *Ctx);
533206124Srdivacky  }
534206124Srdivacky
535226633Sdim  if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_HI16)
536226633Sdim    MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateUpper16(Expr, *Ctx)));
537226633Sdim  else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_LO16)
538226633Sdim    MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateLower16(Expr, *Ctx)));
539226633Sdim  else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_None)
540226633Sdim    MI.addOperand(MCOperand::CreateExpr(Expr));
541234353Sdim  else
542234353Sdim    llvm_unreachable("bad SymbolicOp.VariantKind");
543212904Sdim
544226633Sdim  return true;
545226633Sdim}
546226633Sdim
547226633Sdim/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
548226633Sdim/// referenced by a load instruction with the base register that is the Pc.
549226633Sdim/// These can often be values in a literal pool near the Address of the
550226633Sdim/// instruction.  The Address of the instruction and its immediate Value are
551226633Sdim/// used as a possible literal pool entry.  The SymbolLookUp call back will
552226633Sdim/// return the name of a symbol referenced by the the literal pool's entry if
553226633Sdim/// the referenced address is that of a symbol.  Or it will return a pointer to
554226633Sdim/// a literal 'C' string if the referenced address of the literal pool's entry
555226633Sdim/// is an address into a section with 'C' string literals.
556226633Sdimstatic void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
557234353Sdim                                            const void *Decoder) {
558226633Sdim  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
559226633Sdim  LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback();
560226633Sdim  if (SymbolLookUp) {
561226633Sdim    void *DisInfo = Dis->getDisInfoBlock();
562226633Sdim    uint64_t ReferenceType;
563226633Sdim    ReferenceType = LLVMDisassembler_ReferenceType_In_PCrel_Load;
564226633Sdim    const char *ReferenceName;
565226633Sdim    (void)SymbolLookUp(DisInfo, Value, &ReferenceType, Address, &ReferenceName);
566226633Sdim    if(ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr ||
567226633Sdim       ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr)
568226633Sdim      (*Dis->CommentStream) << "literal pool for: " << ReferenceName;
569206124Srdivacky  }
570226633Sdim}
571206124Srdivacky
572226633Sdim// Thumb1 instructions don't have explicit S bits.  Rather, they
573226633Sdim// implicitly set CPSR.  Since it's not represented in the encoding, the
574226633Sdim// auto-generated decoder won't inject the CPSR operand.  We need to fix
575226633Sdim// that as a post-pass.
576226633Sdimstatic void AddThumb1SBit(MCInst &MI, bool InITBlock) {
577226633Sdim  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
578226633Sdim  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
579226633Sdim  MCInst::iterator I = MI.begin();
580226633Sdim  for (unsigned i = 0; i < NumOps; ++i, ++I) {
581226633Sdim    if (I == MI.end()) break;
582226633Sdim    if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
583226633Sdim      if (i > 0 && OpInfo[i-1].isPredicate()) continue;
584226633Sdim      MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
585226633Sdim      return;
586226633Sdim    }
587226633Sdim  }
588206124Srdivacky
589226633Sdim  MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
590226633Sdim}
591206124Srdivacky
592226633Sdim// Most Thumb instructions don't have explicit predicates in the
593226633Sdim// encoding, but rather get their predicates from IT context.  We need
594226633Sdim// to fix up the predicate operands using this context information as a
595226633Sdim// post-pass.
596226633SdimMCDisassembler::DecodeStatus
597226633SdimThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
598226633Sdim  MCDisassembler::DecodeStatus S = Success;
599206124Srdivacky
600226633Sdim  // A few instructions actually have predicates encoded in them.  Don't
601226633Sdim  // try to overwrite it if we're seeing one of those.
602226633Sdim  switch (MI.getOpcode()) {
603226633Sdim    case ARM::tBcc:
604226633Sdim    case ARM::t2Bcc:
605226633Sdim    case ARM::tCBZ:
606226633Sdim    case ARM::tCBNZ:
607226633Sdim    case ARM::tCPS:
608226633Sdim    case ARM::t2CPS3p:
609226633Sdim    case ARM::t2CPS2p:
610226633Sdim    case ARM::t2CPS1p:
611226633Sdim    case ARM::tMOVSr:
612226633Sdim    case ARM::tSETEND:
613226633Sdim      // Some instructions (mostly conditional branches) are not
614226633Sdim      // allowed in IT blocks.
615226633Sdim      if (!ITBlock.empty())
616226633Sdim        S = SoftFail;
617226633Sdim      else
618226633Sdim        return Success;
619226633Sdim      break;
620226633Sdim    case ARM::tB:
621226633Sdim    case ARM::t2B:
622226633Sdim    case ARM::t2TBB:
623226633Sdim    case ARM::t2TBH:
624226633Sdim      // Some instructions (mostly unconditional branches) can
625226633Sdim      // only appears at the end of, or outside of, an IT.
626226633Sdim      if (ITBlock.size() > 1)
627226633Sdim        S = SoftFail;
628226633Sdim      break;
629226633Sdim    default:
630226633Sdim      break;
631226633Sdim  }
632226633Sdim
633226633Sdim  // If we're in an IT block, base the predicate on that.  Otherwise,
634226633Sdim  // assume a predicate of AL.
635226633Sdim  unsigned CC;
636226633Sdim  if (!ITBlock.empty()) {
637226633Sdim    CC = ITBlock.back();
638226633Sdim    if (CC == 0xF)
639226633Sdim      CC = ARMCC::AL;
640226633Sdim    ITBlock.pop_back();
641226633Sdim  } else
642226633Sdim    CC = ARMCC::AL;
643226633Sdim
644226633Sdim  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
645226633Sdim  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
646226633Sdim  MCInst::iterator I = MI.begin();
647226633Sdim  for (unsigned i = 0; i < NumOps; ++i, ++I) {
648226633Sdim    if (I == MI.end()) break;
649226633Sdim    if (OpInfo[i].isPredicate()) {
650226633Sdim      I = MI.insert(I, MCOperand::CreateImm(CC));
651226633Sdim      ++I;
652226633Sdim      if (CC == ARMCC::AL)
653226633Sdim        MI.insert(I, MCOperand::CreateReg(0));
654226633Sdim      else
655226633Sdim        MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
656226633Sdim      return S;
657226633Sdim    }
658226633Sdim  }
659226633Sdim
660226633Sdim  I = MI.insert(I, MCOperand::CreateImm(CC));
661226633Sdim  ++I;
662226633Sdim  if (CC == ARMCC::AL)
663226633Sdim    MI.insert(I, MCOperand::CreateReg(0));
664226633Sdim  else
665226633Sdim    MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
666226633Sdim
667226633Sdim  return S;
668226633Sdim}
669226633Sdim
670226633Sdim// Thumb VFP instructions are a special case.  Because we share their
671226633Sdim// encodings between ARM and Thumb modes, and they are predicable in ARM
672226633Sdim// mode, the auto-generated decoder will give them an (incorrect)
673226633Sdim// predicate operand.  We need to rewrite these operands based on the IT
674226633Sdim// context as a post-pass.
675226633Sdimvoid ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const {
676226633Sdim  unsigned CC;
677226633Sdim  if (!ITBlock.empty()) {
678226633Sdim    CC = ITBlock.back();
679226633Sdim    ITBlock.pop_back();
680226633Sdim  } else
681226633Sdim    CC = ARMCC::AL;
682226633Sdim
683226633Sdim  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
684226633Sdim  MCInst::iterator I = MI.begin();
685226633Sdim  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
686226633Sdim  for (unsigned i = 0; i < NumOps; ++i, ++I) {
687226633Sdim    if (OpInfo[i].isPredicate() ) {
688226633Sdim      I->setImm(CC);
689226633Sdim      ++I;
690226633Sdim      if (CC == ARMCC::AL)
691226633Sdim        I->setReg(0);
692226633Sdim      else
693226633Sdim        I->setReg(ARM::CPSR);
694226633Sdim      return;
695226633Sdim    }
696226633Sdim  }
697226633Sdim}
698226633Sdim
699226633SdimDecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
700226633Sdim                                               const MemoryObject &Region,
701226633Sdim                                               uint64_t Address,
702226633Sdim                                               raw_ostream &os,
703226633Sdim                                               raw_ostream &cs) const {
704226633Sdim  CommentStream = &cs;
705226633Sdim
706226633Sdim  uint8_t bytes[4];
707226633Sdim
708226633Sdim  assert((STI.getFeatureBits() & ARM::ModeThumb) &&
709226633Sdim         "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
710226633Sdim
711226633Sdim  // We want to read exactly 2 bytes of data.
712226633Sdim  if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1) {
713226633Sdim    Size = 0;
714226633Sdim    return MCDisassembler::Fail;
715226633Sdim  }
716226633Sdim
717226633Sdim  uint16_t insn16 = (bytes[1] << 8) | bytes[0];
718226633Sdim  DecodeStatus result = decodeThumbInstruction16(MI, insn16, Address, this, STI);
719226633Sdim  if (result != MCDisassembler::Fail) {
720226633Sdim    Size = 2;
721226633Sdim    Check(result, AddThumbPredicate(MI));
722226633Sdim    return result;
723226633Sdim  }
724226633Sdim
725226633Sdim  MI.clear();
726226633Sdim  result = decodeThumbSBitInstruction16(MI, insn16, Address, this, STI);
727226633Sdim  if (result) {
728226633Sdim    Size = 2;
729226633Sdim    bool InITBlock = !ITBlock.empty();
730226633Sdim    Check(result, AddThumbPredicate(MI));
731226633Sdim    AddThumb1SBit(MI, InITBlock);
732226633Sdim    return result;
733226633Sdim  }
734226633Sdim
735226633Sdim  MI.clear();
736226633Sdim  result = decodeThumb2Instruction16(MI, insn16, Address, this, STI);
737226633Sdim  if (result != MCDisassembler::Fail) {
738226633Sdim    Size = 2;
739226633Sdim
740226633Sdim    // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
741226633Sdim    // the Thumb predicate.
742226633Sdim    if (MI.getOpcode() == ARM::t2IT && !ITBlock.empty())
743226633Sdim      result = MCDisassembler::SoftFail;
744226633Sdim
745226633Sdim    Check(result, AddThumbPredicate(MI));
746226633Sdim
747226633Sdim    // If we find an IT instruction, we need to parse its condition
748226633Sdim    // code and mask operands so that we can apply them correctly
749226633Sdim    // to the subsequent instructions.
750226633Sdim    if (MI.getOpcode() == ARM::t2IT) {
751226633Sdim
752226633Sdim      // (3 - the number of trailing zeros) is the number of then / else.
753226633Sdim      unsigned firstcond = MI.getOperand(0).getImm();
754226633Sdim      unsigned Mask = MI.getOperand(1).getImm();
755226633Sdim      unsigned CondBit0 = Mask >> 4 & 1;
756226633Sdim      unsigned NumTZ = CountTrailingZeros_32(Mask);
757226633Sdim      assert(NumTZ <= 3 && "Invalid IT mask!");
758226633Sdim      for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
759226633Sdim        bool T = ((Mask >> Pos) & 1) == CondBit0;
760226633Sdim        if (T)
761226633Sdim          ITBlock.insert(ITBlock.begin(), firstcond);
762226633Sdim        else
763226633Sdim          ITBlock.insert(ITBlock.begin(), firstcond ^ 1);
764206124Srdivacky      }
765226633Sdim
766226633Sdim      ITBlock.push_back(firstcond);
767226633Sdim    }
768226633Sdim
769226633Sdim    return result;
770226633Sdim  }
771226633Sdim
772226633Sdim  // We want to read exactly 4 bytes of data.
773226633Sdim  if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
774226633Sdim    Size = 0;
775226633Sdim    return MCDisassembler::Fail;
776226633Sdim  }
777226633Sdim
778226633Sdim  uint32_t insn32 = (bytes[3] <<  8) |
779226633Sdim                    (bytes[2] <<  0) |
780226633Sdim                    (bytes[1] << 24) |
781226633Sdim                    (bytes[0] << 16);
782226633Sdim  MI.clear();
783226633Sdim  result = decodeThumbInstruction32(MI, insn32, Address, this, STI);
784226633Sdim  if (result != MCDisassembler::Fail) {
785226633Sdim    Size = 4;
786226633Sdim    bool InITBlock = ITBlock.size();
787226633Sdim    Check(result, AddThumbPredicate(MI));
788226633Sdim    AddThumb1SBit(MI, InITBlock);
789226633Sdim    return result;
790226633Sdim  }
791226633Sdim
792226633Sdim  MI.clear();
793226633Sdim  result = decodeThumb2Instruction32(MI, insn32, Address, this, STI);
794226633Sdim  if (result != MCDisassembler::Fail) {
795226633Sdim    Size = 4;
796226633Sdim    Check(result, AddThumbPredicate(MI));
797226633Sdim    return result;
798226633Sdim  }
799226633Sdim
800226633Sdim  MI.clear();
801226633Sdim  result = decodeVFPInstruction32(MI, insn32, Address, this, STI);
802226633Sdim  if (result != MCDisassembler::Fail) {
803226633Sdim    Size = 4;
804226633Sdim    UpdateThumbVFPPredicate(MI);
805226633Sdim    return result;
806226633Sdim  }
807226633Sdim
808226633Sdim  MI.clear();
809226633Sdim  result = decodeNEONDupInstruction32(MI, insn32, Address, this, STI);
810226633Sdim  if (result != MCDisassembler::Fail) {
811226633Sdim    Size = 4;
812226633Sdim    Check(result, AddThumbPredicate(MI));
813226633Sdim    return result;
814226633Sdim  }
815226633Sdim
816226633Sdim  if (fieldFromInstruction32(insn32, 24, 8) == 0xF9) {
817226633Sdim    MI.clear();
818226633Sdim    uint32_t NEONLdStInsn = insn32;
819226633Sdim    NEONLdStInsn &= 0xF0FFFFFF;
820226633Sdim    NEONLdStInsn |= 0x04000000;
821226633Sdim    result = decodeNEONLoadStoreInstruction32(MI, NEONLdStInsn, Address, this, STI);
822226633Sdim    if (result != MCDisassembler::Fail) {
823226633Sdim      Size = 4;
824226633Sdim      Check(result, AddThumbPredicate(MI));
825226633Sdim      return result;
826226633Sdim    }
827226633Sdim  }
828226633Sdim
829226633Sdim  if (fieldFromInstruction32(insn32, 24, 4) == 0xF) {
830226633Sdim    MI.clear();
831226633Sdim    uint32_t NEONDataInsn = insn32;
832226633Sdim    NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
833226633Sdim    NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
834226633Sdim    NEONDataInsn |= 0x12000000; // Set bits 28 and 25
835226633Sdim    result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this, STI);
836226633Sdim    if (result != MCDisassembler::Fail) {
837226633Sdim      Size = 4;
838226633Sdim      Check(result, AddThumbPredicate(MI));
839226633Sdim      return result;
840226633Sdim    }
841226633Sdim  }
842226633Sdim
843226633Sdim  Size = 0;
844226633Sdim  return MCDisassembler::Fail;
845226633Sdim}
846226633Sdim
847226633Sdim
848226633Sdimextern "C" void LLVMInitializeARMDisassembler() {
849226633Sdim  TargetRegistry::RegisterMCDisassembler(TheARMTarget,
850226633Sdim                                         createARMDisassembler);
851226633Sdim  TargetRegistry::RegisterMCDisassembler(TheThumbTarget,
852226633Sdim                                         createThumbDisassembler);
853226633Sdim}
854226633Sdim
855234353Sdimstatic const uint16_t GPRDecoderTable[] = {
856226633Sdim  ARM::R0, ARM::R1, ARM::R2, ARM::R3,
857226633Sdim  ARM::R4, ARM::R5, ARM::R6, ARM::R7,
858226633Sdim  ARM::R8, ARM::R9, ARM::R10, ARM::R11,
859226633Sdim  ARM::R12, ARM::SP, ARM::LR, ARM::PC
860226633Sdim};
861226633Sdim
862234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
863226633Sdim                                   uint64_t Address, const void *Decoder) {
864226633Sdim  if (RegNo > 15)
865226633Sdim    return MCDisassembler::Fail;
866226633Sdim
867226633Sdim  unsigned Register = GPRDecoderTable[RegNo];
868226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
869226633Sdim  return MCDisassembler::Success;
870226633Sdim}
871226633Sdim
872226633Sdimstatic DecodeStatus
873234353SdimDecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
874226633Sdim                           uint64_t Address, const void *Decoder) {
875234353Sdim  DecodeStatus S = MCDisassembler::Success;
876234353Sdim
877234353Sdim  if (RegNo == 15)
878234353Sdim    S = MCDisassembler::SoftFail;
879234353Sdim
880234353Sdim  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
881234353Sdim
882234353Sdim  return S;
883226633Sdim}
884226633Sdim
885234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
886226633Sdim                                   uint64_t Address, const void *Decoder) {
887226633Sdim  if (RegNo > 7)
888226633Sdim    return MCDisassembler::Fail;
889226633Sdim  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
890226633Sdim}
891226633Sdim
892234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
893226633Sdim                                   uint64_t Address, const void *Decoder) {
894226633Sdim  unsigned Register = 0;
895226633Sdim  switch (RegNo) {
896226633Sdim    case 0:
897226633Sdim      Register = ARM::R0;
898206124Srdivacky      break;
899226633Sdim    case 1:
900226633Sdim      Register = ARM::R1;
901226633Sdim      break;
902226633Sdim    case 2:
903226633Sdim      Register = ARM::R2;
904226633Sdim      break;
905206124Srdivacky    case 3:
906226633Sdim      Register = ARM::R3;
907206124Srdivacky      break;
908226633Sdim    case 9:
909226633Sdim      Register = ARM::R9;
910226633Sdim      break;
911226633Sdim    case 12:
912226633Sdim      Register = ARM::R12;
913226633Sdim      break;
914206124Srdivacky    default:
915226633Sdim      return MCDisassembler::Fail;
916206124Srdivacky    }
917226633Sdim
918226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
919226633Sdim  return MCDisassembler::Success;
920226633Sdim}
921226633Sdim
922234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
923226633Sdim                                   uint64_t Address, const void *Decoder) {
924226633Sdim  if (RegNo == 13 || RegNo == 15) return MCDisassembler::Fail;
925226633Sdim  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
926226633Sdim}
927226633Sdim
928234353Sdimstatic const uint16_t SPRDecoderTable[] = {
929226633Sdim     ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
930226633Sdim     ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
931226633Sdim     ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
932226633Sdim    ARM::S12, ARM::S13, ARM::S14, ARM::S15,
933226633Sdim    ARM::S16, ARM::S17, ARM::S18, ARM::S19,
934226633Sdim    ARM::S20, ARM::S21, ARM::S22, ARM::S23,
935226633Sdim    ARM::S24, ARM::S25, ARM::S26, ARM::S27,
936226633Sdim    ARM::S28, ARM::S29, ARM::S30, ARM::S31
937226633Sdim};
938226633Sdim
939234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
940226633Sdim                                   uint64_t Address, const void *Decoder) {
941226633Sdim  if (RegNo > 31)
942226633Sdim    return MCDisassembler::Fail;
943226633Sdim
944226633Sdim  unsigned Register = SPRDecoderTable[RegNo];
945226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
946226633Sdim  return MCDisassembler::Success;
947226633Sdim}
948226633Sdim
949234353Sdimstatic const uint16_t DPRDecoderTable[] = {
950226633Sdim     ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
951226633Sdim     ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
952226633Sdim     ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
953226633Sdim    ARM::D12, ARM::D13, ARM::D14, ARM::D15,
954226633Sdim    ARM::D16, ARM::D17, ARM::D18, ARM::D19,
955226633Sdim    ARM::D20, ARM::D21, ARM::D22, ARM::D23,
956226633Sdim    ARM::D24, ARM::D25, ARM::D26, ARM::D27,
957226633Sdim    ARM::D28, ARM::D29, ARM::D30, ARM::D31
958226633Sdim};
959226633Sdim
960234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
961226633Sdim                                   uint64_t Address, const void *Decoder) {
962226633Sdim  if (RegNo > 31)
963226633Sdim    return MCDisassembler::Fail;
964226633Sdim
965226633Sdim  unsigned Register = DPRDecoderTable[RegNo];
966226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
967226633Sdim  return MCDisassembler::Success;
968226633Sdim}
969226633Sdim
970234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
971226633Sdim                                   uint64_t Address, const void *Decoder) {
972226633Sdim  if (RegNo > 7)
973226633Sdim    return MCDisassembler::Fail;
974226633Sdim  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
975226633Sdim}
976226633Sdim
977226633Sdimstatic DecodeStatus
978234353SdimDecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
979226633Sdim                            uint64_t Address, const void *Decoder) {
980226633Sdim  if (RegNo > 15)
981226633Sdim    return MCDisassembler::Fail;
982226633Sdim  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
983226633Sdim}
984226633Sdim
985234353Sdimstatic const uint16_t QPRDecoderTable[] = {
986226633Sdim     ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
987226633Sdim     ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
988226633Sdim     ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
989226633Sdim    ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
990226633Sdim};
991226633Sdim
992226633Sdim
993234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
994226633Sdim                                   uint64_t Address, const void *Decoder) {
995226633Sdim  if (RegNo > 31)
996226633Sdim    return MCDisassembler::Fail;
997226633Sdim  RegNo >>= 1;
998226633Sdim
999226633Sdim  unsigned Register = QPRDecoderTable[RegNo];
1000226633Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
1001226633Sdim  return MCDisassembler::Success;
1002226633Sdim}
1003226633Sdim
1004234353Sdimstatic const uint16_t DPairDecoderTable[] = {
1005234353Sdim  ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
1006234353Sdim  ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
1007234353Sdim  ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
1008234353Sdim  ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
1009234353Sdim  ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
1010234353Sdim  ARM::Q15
1011234353Sdim};
1012234353Sdim
1013234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
1014234353Sdim                                   uint64_t Address, const void *Decoder) {
1015234353Sdim  if (RegNo > 30)
1016234353Sdim    return MCDisassembler::Fail;
1017234353Sdim
1018234353Sdim  unsigned Register = DPairDecoderTable[RegNo];
1019234353Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
1020234353Sdim  return MCDisassembler::Success;
1021234353Sdim}
1022234353Sdim
1023234353Sdimstatic const uint16_t DPairSpacedDecoderTable[] = {
1024234353Sdim  ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
1025234353Sdim  ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
1026234353Sdim  ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
1027234353Sdim  ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
1028234353Sdim  ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
1029234353Sdim  ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
1030234353Sdim  ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
1031234353Sdim  ARM::D28_D30, ARM::D29_D31
1032234353Sdim};
1033234353Sdim
1034234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
1035234353Sdim                                                   unsigned RegNo,
1036234353Sdim                                                   uint64_t Address,
1037234353Sdim                                                   const void *Decoder) {
1038234353Sdim  if (RegNo > 29)
1039234353Sdim    return MCDisassembler::Fail;
1040234353Sdim
1041234353Sdim  unsigned Register = DPairSpacedDecoderTable[RegNo];
1042234353Sdim  Inst.addOperand(MCOperand::CreateReg(Register));
1043234353Sdim  return MCDisassembler::Success;
1044234353Sdim}
1045234353Sdim
1046234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
1047226633Sdim                               uint64_t Address, const void *Decoder) {
1048226633Sdim  if (Val == 0xF) return MCDisassembler::Fail;
1049226633Sdim  // AL predicate is not allowed on Thumb1 branches.
1050226633Sdim  if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
1051226633Sdim    return MCDisassembler::Fail;
1052226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
1053226633Sdim  if (Val == ARMCC::AL) {
1054226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
1055226633Sdim  } else
1056226633Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1057226633Sdim  return MCDisassembler::Success;
1058226633Sdim}
1059226633Sdim
1060234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
1061226633Sdim                               uint64_t Address, const void *Decoder) {
1062226633Sdim  if (Val)
1063226633Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1064226633Sdim  else
1065226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
1066226633Sdim  return MCDisassembler::Success;
1067226633Sdim}
1068226633Sdim
1069234353Sdimstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val,
1070226633Sdim                               uint64_t Address, const void *Decoder) {
1071226633Sdim  uint32_t imm = Val & 0xFF;
1072226633Sdim  uint32_t rot = (Val & 0xF00) >> 7;
1073226633Sdim  uint32_t rot_imm = (imm >> rot) | (imm << ((32-rot) & 0x1F));
1074226633Sdim  Inst.addOperand(MCOperand::CreateImm(rot_imm));
1075226633Sdim  return MCDisassembler::Success;
1076226633Sdim}
1077226633Sdim
1078234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
1079226633Sdim                               uint64_t Address, const void *Decoder) {
1080226633Sdim  DecodeStatus S = MCDisassembler::Success;
1081226633Sdim
1082226633Sdim  unsigned Rm = fieldFromInstruction32(Val, 0, 4);
1083226633Sdim  unsigned type = fieldFromInstruction32(Val, 5, 2);
1084226633Sdim  unsigned imm = fieldFromInstruction32(Val, 7, 5);
1085226633Sdim
1086226633Sdim  // Register-immediate
1087226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1088226633Sdim    return MCDisassembler::Fail;
1089226633Sdim
1090226633Sdim  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1091226633Sdim  switch (type) {
1092226633Sdim    case 0:
1093226633Sdim      Shift = ARM_AM::lsl;
1094226633Sdim      break;
1095226633Sdim    case 1:
1096226633Sdim      Shift = ARM_AM::lsr;
1097226633Sdim      break;
1098226633Sdim    case 2:
1099226633Sdim      Shift = ARM_AM::asr;
1100226633Sdim      break;
1101226633Sdim    case 3:
1102226633Sdim      Shift = ARM_AM::ror;
1103226633Sdim      break;
1104206124Srdivacky  }
1105206124Srdivacky
1106226633Sdim  if (Shift == ARM_AM::ror && imm == 0)
1107226633Sdim    Shift = ARM_AM::rrx;
1108226633Sdim
1109226633Sdim  unsigned Op = Shift | (imm << 3);
1110226633Sdim  Inst.addOperand(MCOperand::CreateImm(Op));
1111226633Sdim
1112226633Sdim  return S;
1113226633Sdim}
1114226633Sdim
1115234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
1116226633Sdim                               uint64_t Address, const void *Decoder) {
1117226633Sdim  DecodeStatus S = MCDisassembler::Success;
1118226633Sdim
1119226633Sdim  unsigned Rm = fieldFromInstruction32(Val, 0, 4);
1120226633Sdim  unsigned type = fieldFromInstruction32(Val, 5, 2);
1121226633Sdim  unsigned Rs = fieldFromInstruction32(Val, 8, 4);
1122226633Sdim
1123226633Sdim  // Register-register
1124226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1125226633Sdim    return MCDisassembler::Fail;
1126226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
1127226633Sdim    return MCDisassembler::Fail;
1128226633Sdim
1129226633Sdim  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1130226633Sdim  switch (type) {
1131226633Sdim    case 0:
1132226633Sdim      Shift = ARM_AM::lsl;
1133206124Srdivacky      break;
1134226633Sdim    case 1:
1135226633Sdim      Shift = ARM_AM::lsr;
1136206124Srdivacky      break;
1137226633Sdim    case 2:
1138226633Sdim      Shift = ARM_AM::asr;
1139206124Srdivacky      break;
1140226633Sdim    case 3:
1141226633Sdim      Shift = ARM_AM::ror;
1142226633Sdim      break;
1143226633Sdim  }
1144226633Sdim
1145226633Sdim  Inst.addOperand(MCOperand::CreateImm(Shift));
1146226633Sdim
1147226633Sdim  return S;
1148226633Sdim}
1149226633Sdim
1150234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
1151226633Sdim                                 uint64_t Address, const void *Decoder) {
1152226633Sdim  DecodeStatus S = MCDisassembler::Success;
1153226633Sdim
1154226633Sdim  bool writebackLoad = false;
1155226633Sdim  unsigned writebackReg = 0;
1156226633Sdim  switch (Inst.getOpcode()) {
1157206124Srdivacky    default:
1158226633Sdim      break;
1159226633Sdim    case ARM::LDMIA_UPD:
1160226633Sdim    case ARM::LDMDB_UPD:
1161226633Sdim    case ARM::LDMIB_UPD:
1162226633Sdim    case ARM::LDMDA_UPD:
1163226633Sdim    case ARM::t2LDMIA_UPD:
1164226633Sdim    case ARM::t2LDMDB_UPD:
1165226633Sdim      writebackLoad = true;
1166226633Sdim      writebackReg = Inst.getOperand(0).getReg();
1167226633Sdim      break;
1168226633Sdim  }
1169226633Sdim
1170226633Sdim  // Empty register lists are not allowed.
1171226633Sdim  if (CountPopulation_32(Val) == 0) return MCDisassembler::Fail;
1172226633Sdim  for (unsigned i = 0; i < 16; ++i) {
1173226633Sdim    if (Val & (1 << i)) {
1174226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
1175226633Sdim        return MCDisassembler::Fail;
1176226633Sdim      // Writeback not allowed if Rn is in the target list.
1177226633Sdim      if (writebackLoad && writebackReg == Inst.end()[-1].getReg())
1178226633Sdim        Check(S, MCDisassembler::SoftFail);
1179206124Srdivacky    }
1180206124Srdivacky  }
1181206124Srdivacky
1182226633Sdim  return S;
1183226633Sdim}
1184226633Sdim
1185234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
1186226633Sdim                                 uint64_t Address, const void *Decoder) {
1187226633Sdim  DecodeStatus S = MCDisassembler::Success;
1188226633Sdim
1189226633Sdim  unsigned Vd = fieldFromInstruction32(Val, 8, 4);
1190226633Sdim  unsigned regs = Val & 0xFF;
1191226633Sdim
1192226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
1193226633Sdim    return MCDisassembler::Fail;
1194226633Sdim  for (unsigned i = 0; i < (regs - 1); ++i) {
1195226633Sdim    if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1196226633Sdim      return MCDisassembler::Fail;
1197226633Sdim  }
1198226633Sdim
1199226633Sdim  return S;
1200226633Sdim}
1201226633Sdim
1202234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
1203226633Sdim                                 uint64_t Address, const void *Decoder) {
1204226633Sdim  DecodeStatus S = MCDisassembler::Success;
1205226633Sdim
1206226633Sdim  unsigned Vd = fieldFromInstruction32(Val, 8, 4);
1207226633Sdim  unsigned regs = (Val & 0xFF) / 2;
1208226633Sdim
1209226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
1210226633Sdim      return MCDisassembler::Fail;
1211226633Sdim  for (unsigned i = 0; i < (regs - 1); ++i) {
1212226633Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1213226633Sdim      return MCDisassembler::Fail;
1214226633Sdim  }
1215226633Sdim
1216226633Sdim  return S;
1217226633Sdim}
1218226633Sdim
1219234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
1220226633Sdim                                      uint64_t Address, const void *Decoder) {
1221226633Sdim  // This operand encodes a mask of contiguous zeros between a specified MSB
1222226633Sdim  // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
1223226633Sdim  // the mask of all bits LSB-and-lower, and then xor them to create
1224226633Sdim  // the mask of that's all ones on [msb, lsb].  Finally we not it to
1225226633Sdim  // create the final mask.
1226226633Sdim  unsigned msb = fieldFromInstruction32(Val, 5, 5);
1227226633Sdim  unsigned lsb = fieldFromInstruction32(Val, 0, 5);
1228226633Sdim
1229226633Sdim  DecodeStatus S = MCDisassembler::Success;
1230226633Sdim  if (lsb > msb) Check(S, MCDisassembler::SoftFail);
1231226633Sdim
1232226633Sdim  uint32_t msb_mask = 0xFFFFFFFF;
1233226633Sdim  if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
1234226633Sdim  uint32_t lsb_mask = (1U << lsb) - 1;
1235226633Sdim
1236226633Sdim  Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask)));
1237226633Sdim  return S;
1238226633Sdim}
1239226633Sdim
1240234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
1241226633Sdim                                  uint64_t Address, const void *Decoder) {
1242226633Sdim  DecodeStatus S = MCDisassembler::Success;
1243226633Sdim
1244226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1245226633Sdim  unsigned CRd = fieldFromInstruction32(Insn, 12, 4);
1246226633Sdim  unsigned coproc = fieldFromInstruction32(Insn, 8, 4);
1247226633Sdim  unsigned imm = fieldFromInstruction32(Insn, 0, 8);
1248226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1249226633Sdim  unsigned U = fieldFromInstruction32(Insn, 23, 1);
1250226633Sdim
1251226633Sdim  switch (Inst.getOpcode()) {
1252226633Sdim    case ARM::LDC_OFFSET:
1253226633Sdim    case ARM::LDC_PRE:
1254226633Sdim    case ARM::LDC_POST:
1255226633Sdim    case ARM::LDC_OPTION:
1256226633Sdim    case ARM::LDCL_OFFSET:
1257226633Sdim    case ARM::LDCL_PRE:
1258226633Sdim    case ARM::LDCL_POST:
1259226633Sdim    case ARM::LDCL_OPTION:
1260226633Sdim    case ARM::STC_OFFSET:
1261226633Sdim    case ARM::STC_PRE:
1262226633Sdim    case ARM::STC_POST:
1263226633Sdim    case ARM::STC_OPTION:
1264226633Sdim    case ARM::STCL_OFFSET:
1265226633Sdim    case ARM::STCL_PRE:
1266226633Sdim    case ARM::STCL_POST:
1267226633Sdim    case ARM::STCL_OPTION:
1268226633Sdim    case ARM::t2LDC_OFFSET:
1269226633Sdim    case ARM::t2LDC_PRE:
1270226633Sdim    case ARM::t2LDC_POST:
1271226633Sdim    case ARM::t2LDC_OPTION:
1272226633Sdim    case ARM::t2LDCL_OFFSET:
1273226633Sdim    case ARM::t2LDCL_PRE:
1274226633Sdim    case ARM::t2LDCL_POST:
1275226633Sdim    case ARM::t2LDCL_OPTION:
1276226633Sdim    case ARM::t2STC_OFFSET:
1277226633Sdim    case ARM::t2STC_PRE:
1278226633Sdim    case ARM::t2STC_POST:
1279226633Sdim    case ARM::t2STC_OPTION:
1280226633Sdim    case ARM::t2STCL_OFFSET:
1281226633Sdim    case ARM::t2STCL_PRE:
1282226633Sdim    case ARM::t2STCL_POST:
1283226633Sdim    case ARM::t2STCL_OPTION:
1284226633Sdim      if (coproc == 0xA || coproc == 0xB)
1285226633Sdim        return MCDisassembler::Fail;
1286206124Srdivacky      break;
1287226633Sdim    default:
1288226633Sdim      break;
1289226633Sdim  }
1290226633Sdim
1291226633Sdim  Inst.addOperand(MCOperand::CreateImm(coproc));
1292226633Sdim  Inst.addOperand(MCOperand::CreateImm(CRd));
1293226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1294226633Sdim    return MCDisassembler::Fail;
1295226633Sdim
1296226633Sdim  switch (Inst.getOpcode()) {
1297226633Sdim    case ARM::t2LDC2_OFFSET:
1298226633Sdim    case ARM::t2LDC2L_OFFSET:
1299226633Sdim    case ARM::t2LDC2_PRE:
1300226633Sdim    case ARM::t2LDC2L_PRE:
1301226633Sdim    case ARM::t2STC2_OFFSET:
1302226633Sdim    case ARM::t2STC2L_OFFSET:
1303226633Sdim    case ARM::t2STC2_PRE:
1304226633Sdim    case ARM::t2STC2L_PRE:
1305226633Sdim    case ARM::LDC2_OFFSET:
1306226633Sdim    case ARM::LDC2L_OFFSET:
1307226633Sdim    case ARM::LDC2_PRE:
1308226633Sdim    case ARM::LDC2L_PRE:
1309226633Sdim    case ARM::STC2_OFFSET:
1310226633Sdim    case ARM::STC2L_OFFSET:
1311226633Sdim    case ARM::STC2_PRE:
1312226633Sdim    case ARM::STC2L_PRE:
1313226633Sdim    case ARM::t2LDC_OFFSET:
1314226633Sdim    case ARM::t2LDCL_OFFSET:
1315226633Sdim    case ARM::t2LDC_PRE:
1316226633Sdim    case ARM::t2LDCL_PRE:
1317226633Sdim    case ARM::t2STC_OFFSET:
1318226633Sdim    case ARM::t2STCL_OFFSET:
1319226633Sdim    case ARM::t2STC_PRE:
1320226633Sdim    case ARM::t2STCL_PRE:
1321226633Sdim    case ARM::LDC_OFFSET:
1322226633Sdim    case ARM::LDCL_OFFSET:
1323226633Sdim    case ARM::LDC_PRE:
1324226633Sdim    case ARM::LDCL_PRE:
1325226633Sdim    case ARM::STC_OFFSET:
1326226633Sdim    case ARM::STCL_OFFSET:
1327226633Sdim    case ARM::STC_PRE:
1328226633Sdim    case ARM::STCL_PRE:
1329226633Sdim      imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
1330226633Sdim      Inst.addOperand(MCOperand::CreateImm(imm));
1331226633Sdim      break;
1332226633Sdim    case ARM::t2LDC2_POST:
1333226633Sdim    case ARM::t2LDC2L_POST:
1334226633Sdim    case ARM::t2STC2_POST:
1335226633Sdim    case ARM::t2STC2L_POST:
1336226633Sdim    case ARM::LDC2_POST:
1337226633Sdim    case ARM::LDC2L_POST:
1338226633Sdim    case ARM::STC2_POST:
1339226633Sdim    case ARM::STC2L_POST:
1340226633Sdim    case ARM::t2LDC_POST:
1341226633Sdim    case ARM::t2LDCL_POST:
1342226633Sdim    case ARM::t2STC_POST:
1343226633Sdim    case ARM::t2STCL_POST:
1344226633Sdim    case ARM::LDC_POST:
1345226633Sdim    case ARM::LDCL_POST:
1346226633Sdim    case ARM::STC_POST:
1347226633Sdim    case ARM::STCL_POST:
1348226633Sdim      imm |= U << 8;
1349226633Sdim      // fall through.
1350226633Sdim    default:
1351226633Sdim      // The 'option' variant doesn't encode 'U' in the immediate since
1352226633Sdim      // the immediate is unsigned [0,255].
1353226633Sdim      Inst.addOperand(MCOperand::CreateImm(imm));
1354226633Sdim      break;
1355226633Sdim  }
1356226633Sdim
1357226633Sdim  switch (Inst.getOpcode()) {
1358226633Sdim    case ARM::LDC_OFFSET:
1359226633Sdim    case ARM::LDC_PRE:
1360226633Sdim    case ARM::LDC_POST:
1361226633Sdim    case ARM::LDC_OPTION:
1362226633Sdim    case ARM::LDCL_OFFSET:
1363226633Sdim    case ARM::LDCL_PRE:
1364226633Sdim    case ARM::LDCL_POST:
1365226633Sdim    case ARM::LDCL_OPTION:
1366226633Sdim    case ARM::STC_OFFSET:
1367226633Sdim    case ARM::STC_PRE:
1368226633Sdim    case ARM::STC_POST:
1369226633Sdim    case ARM::STC_OPTION:
1370226633Sdim    case ARM::STCL_OFFSET:
1371226633Sdim    case ARM::STCL_PRE:
1372226633Sdim    case ARM::STCL_POST:
1373226633Sdim    case ARM::STCL_OPTION:
1374226633Sdim      if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1375226633Sdim        return MCDisassembler::Fail;
1376226633Sdim      break;
1377226633Sdim    default:
1378226633Sdim      break;
1379226633Sdim  }
1380226633Sdim
1381226633Sdim  return S;
1382226633Sdim}
1383226633Sdim
1384226633Sdimstatic DecodeStatus
1385234353SdimDecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn,
1386226633Sdim                              uint64_t Address, const void *Decoder) {
1387226633Sdim  DecodeStatus S = MCDisassembler::Success;
1388226633Sdim
1389226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1390226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
1391226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
1392226633Sdim  unsigned imm = fieldFromInstruction32(Insn, 0, 12);
1393226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1394226633Sdim  unsigned reg = fieldFromInstruction32(Insn, 25, 1);
1395226633Sdim  unsigned P = fieldFromInstruction32(Insn, 24, 1);
1396226633Sdim  unsigned W = fieldFromInstruction32(Insn, 21, 1);
1397226633Sdim
1398226633Sdim  // On stores, the writeback operand precedes Rt.
1399226633Sdim  switch (Inst.getOpcode()) {
1400226633Sdim    case ARM::STR_POST_IMM:
1401226633Sdim    case ARM::STR_POST_REG:
1402226633Sdim    case ARM::STRB_POST_IMM:
1403226633Sdim    case ARM::STRB_POST_REG:
1404226633Sdim    case ARM::STRT_POST_REG:
1405226633Sdim    case ARM::STRT_POST_IMM:
1406226633Sdim    case ARM::STRBT_POST_REG:
1407226633Sdim    case ARM::STRBT_POST_IMM:
1408226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1409226633Sdim        return MCDisassembler::Fail;
1410226633Sdim      break;
1411226633Sdim    default:
1412226633Sdim      break;
1413226633Sdim  }
1414226633Sdim
1415226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1416226633Sdim    return MCDisassembler::Fail;
1417226633Sdim
1418226633Sdim  // On loads, the writeback operand comes after Rt.
1419226633Sdim  switch (Inst.getOpcode()) {
1420226633Sdim    case ARM::LDR_POST_IMM:
1421226633Sdim    case ARM::LDR_POST_REG:
1422226633Sdim    case ARM::LDRB_POST_IMM:
1423226633Sdim    case ARM::LDRB_POST_REG:
1424226633Sdim    case ARM::LDRBT_POST_REG:
1425226633Sdim    case ARM::LDRBT_POST_IMM:
1426226633Sdim    case ARM::LDRT_POST_REG:
1427226633Sdim    case ARM::LDRT_POST_IMM:
1428226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1429226633Sdim        return MCDisassembler::Fail;
1430226633Sdim      break;
1431226633Sdim    default:
1432226633Sdim      break;
1433226633Sdim  }
1434226633Sdim
1435226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1436226633Sdim    return MCDisassembler::Fail;
1437226633Sdim
1438226633Sdim  ARM_AM::AddrOpc Op = ARM_AM::add;
1439226633Sdim  if (!fieldFromInstruction32(Insn, 23, 1))
1440226633Sdim    Op = ARM_AM::sub;
1441226633Sdim
1442226633Sdim  bool writeback = (P == 0) || (W == 1);
1443226633Sdim  unsigned idx_mode = 0;
1444226633Sdim  if (P && writeback)
1445226633Sdim    idx_mode = ARMII::IndexModePre;
1446226633Sdim  else if (!P && writeback)
1447226633Sdim    idx_mode = ARMII::IndexModePost;
1448226633Sdim
1449226633Sdim  if (writeback && (Rn == 15 || Rn == Rt))
1450226633Sdim    S = MCDisassembler::SoftFail; // UNPREDICTABLE
1451226633Sdim
1452226633Sdim  if (reg) {
1453226633Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1454226633Sdim      return MCDisassembler::Fail;
1455226633Sdim    ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
1456226633Sdim    switch( fieldFromInstruction32(Insn, 5, 2)) {
1457226633Sdim      case 0:
1458226633Sdim        Opc = ARM_AM::lsl;
1459226633Sdim        break;
1460226633Sdim      case 1:
1461226633Sdim        Opc = ARM_AM::lsr;
1462226633Sdim        break;
1463226633Sdim      case 2:
1464226633Sdim        Opc = ARM_AM::asr;
1465226633Sdim        break;
1466226633Sdim      case 3:
1467226633Sdim        Opc = ARM_AM::ror;
1468226633Sdim        break;
1469206124Srdivacky      default:
1470226633Sdim        return MCDisassembler::Fail;
1471226633Sdim    }
1472226633Sdim    unsigned amt = fieldFromInstruction32(Insn, 7, 5);
1473226633Sdim    unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
1474226633Sdim
1475226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
1476226633Sdim  } else {
1477226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
1478226633Sdim    unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
1479226633Sdim    Inst.addOperand(MCOperand::CreateImm(tmp));
1480226633Sdim  }
1481226633Sdim
1482226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1483226633Sdim    return MCDisassembler::Fail;
1484226633Sdim
1485226633Sdim  return S;
1486226633Sdim}
1487226633Sdim
1488234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
1489226633Sdim                                  uint64_t Address, const void *Decoder) {
1490226633Sdim  DecodeStatus S = MCDisassembler::Success;
1491226633Sdim
1492226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 13, 4);
1493226633Sdim  unsigned Rm = fieldFromInstruction32(Val,  0, 4);
1494226633Sdim  unsigned type = fieldFromInstruction32(Val, 5, 2);
1495226633Sdim  unsigned imm = fieldFromInstruction32(Val, 7, 5);
1496226633Sdim  unsigned U = fieldFromInstruction32(Val, 12, 1);
1497226633Sdim
1498226633Sdim  ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
1499226633Sdim  switch (type) {
1500226633Sdim    case 0:
1501226633Sdim      ShOp = ARM_AM::lsl;
1502206124Srdivacky      break;
1503226633Sdim    case 1:
1504226633Sdim      ShOp = ARM_AM::lsr;
1505226633Sdim      break;
1506226633Sdim    case 2:
1507226633Sdim      ShOp = ARM_AM::asr;
1508226633Sdim      break;
1509226633Sdim    case 3:
1510226633Sdim      ShOp = ARM_AM::ror;
1511226633Sdim      break;
1512226633Sdim  }
1513226633Sdim
1514226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1515226633Sdim    return MCDisassembler::Fail;
1516226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1517226633Sdim    return MCDisassembler::Fail;
1518226633Sdim  unsigned shift;
1519226633Sdim  if (U)
1520226633Sdim    shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
1521226633Sdim  else
1522226633Sdim    shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
1523226633Sdim  Inst.addOperand(MCOperand::CreateImm(shift));
1524226633Sdim
1525226633Sdim  return S;
1526226633Sdim}
1527226633Sdim
1528226633Sdimstatic DecodeStatus
1529234353SdimDecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
1530226633Sdim                           uint64_t Address, const void *Decoder) {
1531226633Sdim  DecodeStatus S = MCDisassembler::Success;
1532226633Sdim
1533226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
1534226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1535226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
1536226633Sdim  unsigned type = fieldFromInstruction32(Insn, 22, 1);
1537226633Sdim  unsigned imm = fieldFromInstruction32(Insn, 8, 4);
1538226633Sdim  unsigned U = ((~fieldFromInstruction32(Insn, 23, 1)) & 1) << 8;
1539226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1540226633Sdim  unsigned W = fieldFromInstruction32(Insn, 21, 1);
1541226633Sdim  unsigned P = fieldFromInstruction32(Insn, 24, 1);
1542234353Sdim  unsigned Rt2 = Rt + 1;
1543226633Sdim
1544226633Sdim  bool writeback = (W == 1) | (P == 0);
1545226633Sdim
1546226633Sdim  // For {LD,ST}RD, Rt must be even, else undefined.
1547226633Sdim  switch (Inst.getOpcode()) {
1548226633Sdim    case ARM::STRD:
1549226633Sdim    case ARM::STRD_PRE:
1550226633Sdim    case ARM::STRD_POST:
1551226633Sdim    case ARM::LDRD:
1552226633Sdim    case ARM::LDRD_PRE:
1553226633Sdim    case ARM::LDRD_POST:
1554234353Sdim      if (Rt & 0x1) S = MCDisassembler::SoftFail;
1555226633Sdim      break;
1556226633Sdim    default:
1557226633Sdim      break;
1558226633Sdim  }
1559234353Sdim  switch (Inst.getOpcode()) {
1560234353Sdim    case ARM::STRD:
1561234353Sdim    case ARM::STRD_PRE:
1562234353Sdim    case ARM::STRD_POST:
1563234353Sdim      if (P == 0 && W == 1)
1564234353Sdim        S = MCDisassembler::SoftFail;
1565234353Sdim
1566234353Sdim      if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
1567234353Sdim        S = MCDisassembler::SoftFail;
1568234353Sdim      if (type && Rm == 15)
1569234353Sdim        S = MCDisassembler::SoftFail;
1570234353Sdim      if (Rt2 == 15)
1571234353Sdim        S = MCDisassembler::SoftFail;
1572234353Sdim      if (!type && fieldFromInstruction32(Insn, 8, 4))
1573234353Sdim        S = MCDisassembler::SoftFail;
1574234353Sdim      break;
1575234353Sdim    case ARM::STRH:
1576234353Sdim    case ARM::STRH_PRE:
1577234353Sdim    case ARM::STRH_POST:
1578234353Sdim      if (Rt == 15)
1579234353Sdim        S = MCDisassembler::SoftFail;
1580234353Sdim      if (writeback && (Rn == 15 || Rn == Rt))
1581234353Sdim        S = MCDisassembler::SoftFail;
1582234353Sdim      if (!type && Rm == 15)
1583234353Sdim        S = MCDisassembler::SoftFail;
1584234353Sdim      break;
1585234353Sdim    case ARM::LDRD:
1586234353Sdim    case ARM::LDRD_PRE:
1587234353Sdim    case ARM::LDRD_POST:
1588234353Sdim      if (type && Rn == 15){
1589234353Sdim        if (Rt2 == 15)
1590234353Sdim          S = MCDisassembler::SoftFail;
1591234353Sdim        break;
1592234353Sdim      }
1593234353Sdim      if (P == 0 && W == 1)
1594234353Sdim        S = MCDisassembler::SoftFail;
1595234353Sdim      if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
1596234353Sdim        S = MCDisassembler::SoftFail;
1597234353Sdim      if (!type && writeback && Rn == 15)
1598234353Sdim        S = MCDisassembler::SoftFail;
1599234353Sdim      if (writeback && (Rn == Rt || Rn == Rt2))
1600234353Sdim        S = MCDisassembler::SoftFail;
1601234353Sdim      break;
1602234353Sdim    case ARM::LDRH:
1603234353Sdim    case ARM::LDRH_PRE:
1604234353Sdim    case ARM::LDRH_POST:
1605234353Sdim      if (type && Rn == 15){
1606234353Sdim        if (Rt == 15)
1607234353Sdim          S = MCDisassembler::SoftFail;
1608234353Sdim        break;
1609234353Sdim      }
1610234353Sdim      if (Rt == 15)
1611234353Sdim        S = MCDisassembler::SoftFail;
1612234353Sdim      if (!type && Rm == 15)
1613234353Sdim        S = MCDisassembler::SoftFail;
1614234353Sdim      if (!type && writeback && (Rn == 15 || Rn == Rt))
1615234353Sdim        S = MCDisassembler::SoftFail;
1616234353Sdim      break;
1617234353Sdim    case ARM::LDRSH:
1618234353Sdim    case ARM::LDRSH_PRE:
1619234353Sdim    case ARM::LDRSH_POST:
1620234353Sdim    case ARM::LDRSB:
1621234353Sdim    case ARM::LDRSB_PRE:
1622234353Sdim    case ARM::LDRSB_POST:
1623234353Sdim      if (type && Rn == 15){
1624234353Sdim        if (Rt == 15)
1625234353Sdim          S = MCDisassembler::SoftFail;
1626234353Sdim        break;
1627234353Sdim      }
1628234353Sdim      if (type && (Rt == 15 || (writeback && Rn == Rt)))
1629234353Sdim        S = MCDisassembler::SoftFail;
1630234353Sdim      if (!type && (Rt == 15 || Rm == 15))
1631234353Sdim        S = MCDisassembler::SoftFail;
1632234353Sdim      if (!type && writeback && (Rn == 15 || Rn == Rt))
1633234353Sdim        S = MCDisassembler::SoftFail;
1634234353Sdim      break;
1635234353Sdim    default:
1636234353Sdim      break;
1637234353Sdim  }
1638226633Sdim
1639226633Sdim  if (writeback) { // Writeback
1640226633Sdim    if (P)
1641226633Sdim      U |= ARMII::IndexModePre << 9;
1642226633Sdim    else
1643226633Sdim      U |= ARMII::IndexModePost << 9;
1644226633Sdim
1645226633Sdim    // On stores, the writeback operand precedes Rt.
1646226633Sdim    switch (Inst.getOpcode()) {
1647226633Sdim    case ARM::STRD:
1648226633Sdim    case ARM::STRD_PRE:
1649226633Sdim    case ARM::STRD_POST:
1650226633Sdim    case ARM::STRH:
1651226633Sdim    case ARM::STRH_PRE:
1652226633Sdim    case ARM::STRH_POST:
1653226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1654226633Sdim        return MCDisassembler::Fail;
1655226633Sdim      break;
1656226633Sdim    default:
1657226633Sdim      break;
1658226633Sdim    }
1659226633Sdim  }
1660226633Sdim
1661226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1662226633Sdim    return MCDisassembler::Fail;
1663226633Sdim  switch (Inst.getOpcode()) {
1664226633Sdim    case ARM::STRD:
1665226633Sdim    case ARM::STRD_PRE:
1666226633Sdim    case ARM::STRD_POST:
1667226633Sdim    case ARM::LDRD:
1668226633Sdim    case ARM::LDRD_PRE:
1669226633Sdim    case ARM::LDRD_POST:
1670226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
1671226633Sdim        return MCDisassembler::Fail;
1672226633Sdim      break;
1673226633Sdim    default:
1674226633Sdim      break;
1675226633Sdim  }
1676226633Sdim
1677226633Sdim  if (writeback) {
1678226633Sdim    // On loads, the writeback operand comes after Rt.
1679226633Sdim    switch (Inst.getOpcode()) {
1680226633Sdim    case ARM::LDRD:
1681226633Sdim    case ARM::LDRD_PRE:
1682226633Sdim    case ARM::LDRD_POST:
1683226633Sdim    case ARM::LDRH:
1684226633Sdim    case ARM::LDRH_PRE:
1685226633Sdim    case ARM::LDRH_POST:
1686226633Sdim    case ARM::LDRSH:
1687226633Sdim    case ARM::LDRSH_PRE:
1688226633Sdim    case ARM::LDRSH_POST:
1689226633Sdim    case ARM::LDRSB:
1690226633Sdim    case ARM::LDRSB_PRE:
1691226633Sdim    case ARM::LDRSB_POST:
1692226633Sdim    case ARM::LDRHTr:
1693226633Sdim    case ARM::LDRSBTr:
1694226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1695226633Sdim        return MCDisassembler::Fail;
1696226633Sdim      break;
1697226633Sdim    default:
1698226633Sdim      break;
1699226633Sdim    }
1700226633Sdim  }
1701226633Sdim
1702226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1703226633Sdim    return MCDisassembler::Fail;
1704226633Sdim
1705226633Sdim  if (type) {
1706226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
1707226633Sdim    Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm));
1708226633Sdim  } else {
1709226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1710226633Sdim    return MCDisassembler::Fail;
1711226633Sdim    Inst.addOperand(MCOperand::CreateImm(U));
1712226633Sdim  }
1713226633Sdim
1714226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1715226633Sdim    return MCDisassembler::Fail;
1716226633Sdim
1717226633Sdim  return S;
1718226633Sdim}
1719226633Sdim
1720234353Sdimstatic DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
1721226633Sdim                                 uint64_t Address, const void *Decoder) {
1722226633Sdim  DecodeStatus S = MCDisassembler::Success;
1723226633Sdim
1724226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1725226633Sdim  unsigned mode = fieldFromInstruction32(Insn, 23, 2);
1726226633Sdim
1727226633Sdim  switch (mode) {
1728226633Sdim    case 0:
1729226633Sdim      mode = ARM_AM::da;
1730226633Sdim      break;
1731226633Sdim    case 1:
1732226633Sdim      mode = ARM_AM::ia;
1733226633Sdim      break;
1734226633Sdim    case 2:
1735226633Sdim      mode = ARM_AM::db;
1736226633Sdim      break;
1737226633Sdim    case 3:
1738226633Sdim      mode = ARM_AM::ib;
1739226633Sdim      break;
1740226633Sdim  }
1741226633Sdim
1742226633Sdim  Inst.addOperand(MCOperand::CreateImm(mode));
1743226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1744226633Sdim    return MCDisassembler::Fail;
1745226633Sdim
1746226633Sdim  return S;
1747226633Sdim}
1748226633Sdim
1749234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst,
1750226633Sdim                                  unsigned Insn,
1751226633Sdim                                  uint64_t Address, const void *Decoder) {
1752226633Sdim  DecodeStatus S = MCDisassembler::Success;
1753226633Sdim
1754226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1755226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1756226633Sdim  unsigned reglist = fieldFromInstruction32(Insn, 0, 16);
1757226633Sdim
1758226633Sdim  if (pred == 0xF) {
1759226633Sdim    switch (Inst.getOpcode()) {
1760226633Sdim      case ARM::LDMDA:
1761226633Sdim        Inst.setOpcode(ARM::RFEDA);
1762226633Sdim        break;
1763226633Sdim      case ARM::LDMDA_UPD:
1764226633Sdim        Inst.setOpcode(ARM::RFEDA_UPD);
1765226633Sdim        break;
1766226633Sdim      case ARM::LDMDB:
1767226633Sdim        Inst.setOpcode(ARM::RFEDB);
1768226633Sdim        break;
1769226633Sdim      case ARM::LDMDB_UPD:
1770226633Sdim        Inst.setOpcode(ARM::RFEDB_UPD);
1771226633Sdim        break;
1772226633Sdim      case ARM::LDMIA:
1773226633Sdim        Inst.setOpcode(ARM::RFEIA);
1774226633Sdim        break;
1775226633Sdim      case ARM::LDMIA_UPD:
1776226633Sdim        Inst.setOpcode(ARM::RFEIA_UPD);
1777226633Sdim        break;
1778226633Sdim      case ARM::LDMIB:
1779226633Sdim        Inst.setOpcode(ARM::RFEIB);
1780226633Sdim        break;
1781226633Sdim      case ARM::LDMIB_UPD:
1782226633Sdim        Inst.setOpcode(ARM::RFEIB_UPD);
1783226633Sdim        break;
1784226633Sdim      case ARM::STMDA:
1785226633Sdim        Inst.setOpcode(ARM::SRSDA);
1786226633Sdim        break;
1787226633Sdim      case ARM::STMDA_UPD:
1788226633Sdim        Inst.setOpcode(ARM::SRSDA_UPD);
1789226633Sdim        break;
1790226633Sdim      case ARM::STMDB:
1791226633Sdim        Inst.setOpcode(ARM::SRSDB);
1792226633Sdim        break;
1793226633Sdim      case ARM::STMDB_UPD:
1794226633Sdim        Inst.setOpcode(ARM::SRSDB_UPD);
1795226633Sdim        break;
1796226633Sdim      case ARM::STMIA:
1797226633Sdim        Inst.setOpcode(ARM::SRSIA);
1798226633Sdim        break;
1799226633Sdim      case ARM::STMIA_UPD:
1800226633Sdim        Inst.setOpcode(ARM::SRSIA_UPD);
1801226633Sdim        break;
1802226633Sdim      case ARM::STMIB:
1803226633Sdim        Inst.setOpcode(ARM::SRSIB);
1804226633Sdim        break;
1805226633Sdim      case ARM::STMIB_UPD:
1806226633Sdim        Inst.setOpcode(ARM::SRSIB_UPD);
1807226633Sdim        break;
1808206124Srdivacky      default:
1809226633Sdim        if (!Check(S, MCDisassembler::Fail)) return MCDisassembler::Fail;
1810226633Sdim    }
1811226633Sdim
1812226633Sdim    // For stores (which become SRS's, the only operand is the mode.
1813226633Sdim    if (fieldFromInstruction32(Insn, 20, 1) == 0) {
1814226633Sdim      Inst.addOperand(
1815226633Sdim          MCOperand::CreateImm(fieldFromInstruction32(Insn, 0, 4)));
1816226633Sdim      return S;
1817226633Sdim    }
1818226633Sdim
1819226633Sdim    return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
1820226633Sdim  }
1821226633Sdim
1822226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1823226633Sdim    return MCDisassembler::Fail;
1824226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1825226633Sdim    return MCDisassembler::Fail; // Tied
1826226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1827226633Sdim    return MCDisassembler::Fail;
1828226633Sdim  if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
1829226633Sdim    return MCDisassembler::Fail;
1830226633Sdim
1831226633Sdim  return S;
1832226633Sdim}
1833226633Sdim
1834234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
1835226633Sdim                                 uint64_t Address, const void *Decoder) {
1836226633Sdim  unsigned imod = fieldFromInstruction32(Insn, 18, 2);
1837226633Sdim  unsigned M = fieldFromInstruction32(Insn, 17, 1);
1838226633Sdim  unsigned iflags = fieldFromInstruction32(Insn, 6, 3);
1839226633Sdim  unsigned mode = fieldFromInstruction32(Insn, 0, 5);
1840226633Sdim
1841226633Sdim  DecodeStatus S = MCDisassembler::Success;
1842226633Sdim
1843226633Sdim  // imod == '01' --> UNPREDICTABLE
1844226633Sdim  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
1845226633Sdim  // return failure here.  The '01' imod value is unprintable, so there's
1846226633Sdim  // nothing useful we could do even if we returned UNPREDICTABLE.
1847226633Sdim
1848226633Sdim  if (imod == 1) return MCDisassembler::Fail;
1849226633Sdim
1850226633Sdim  if (imod && M) {
1851226633Sdim    Inst.setOpcode(ARM::CPS3p);
1852226633Sdim    Inst.addOperand(MCOperand::CreateImm(imod));
1853226633Sdim    Inst.addOperand(MCOperand::CreateImm(iflags));
1854226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1855226633Sdim  } else if (imod && !M) {
1856226633Sdim    Inst.setOpcode(ARM::CPS2p);
1857226633Sdim    Inst.addOperand(MCOperand::CreateImm(imod));
1858226633Sdim    Inst.addOperand(MCOperand::CreateImm(iflags));
1859226633Sdim    if (mode) S = MCDisassembler::SoftFail;
1860226633Sdim  } else if (!imod && M) {
1861226633Sdim    Inst.setOpcode(ARM::CPS1p);
1862226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1863226633Sdim    if (iflags) S = MCDisassembler::SoftFail;
1864226633Sdim  } else {
1865226633Sdim    // imod == '00' && M == '0' --> UNPREDICTABLE
1866226633Sdim    Inst.setOpcode(ARM::CPS1p);
1867226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1868226633Sdim    S = MCDisassembler::SoftFail;
1869226633Sdim  }
1870226633Sdim
1871226633Sdim  return S;
1872226633Sdim}
1873226633Sdim
1874234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
1875226633Sdim                                 uint64_t Address, const void *Decoder) {
1876226633Sdim  unsigned imod = fieldFromInstruction32(Insn, 9, 2);
1877226633Sdim  unsigned M = fieldFromInstruction32(Insn, 8, 1);
1878226633Sdim  unsigned iflags = fieldFromInstruction32(Insn, 5, 3);
1879226633Sdim  unsigned mode = fieldFromInstruction32(Insn, 0, 5);
1880226633Sdim
1881226633Sdim  DecodeStatus S = MCDisassembler::Success;
1882226633Sdim
1883226633Sdim  // imod == '01' --> UNPREDICTABLE
1884226633Sdim  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
1885226633Sdim  // return failure here.  The '01' imod value is unprintable, so there's
1886226633Sdim  // nothing useful we could do even if we returned UNPREDICTABLE.
1887226633Sdim
1888226633Sdim  if (imod == 1) return MCDisassembler::Fail;
1889226633Sdim
1890226633Sdim  if (imod && M) {
1891226633Sdim    Inst.setOpcode(ARM::t2CPS3p);
1892226633Sdim    Inst.addOperand(MCOperand::CreateImm(imod));
1893226633Sdim    Inst.addOperand(MCOperand::CreateImm(iflags));
1894226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1895226633Sdim  } else if (imod && !M) {
1896226633Sdim    Inst.setOpcode(ARM::t2CPS2p);
1897226633Sdim    Inst.addOperand(MCOperand::CreateImm(imod));
1898226633Sdim    Inst.addOperand(MCOperand::CreateImm(iflags));
1899226633Sdim    if (mode) S = MCDisassembler::SoftFail;
1900226633Sdim  } else if (!imod && M) {
1901226633Sdim    Inst.setOpcode(ARM::t2CPS1p);
1902226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1903226633Sdim    if (iflags) S = MCDisassembler::SoftFail;
1904226633Sdim  } else {
1905226633Sdim    // imod == '00' && M == '0' --> UNPREDICTABLE
1906226633Sdim    Inst.setOpcode(ARM::t2CPS1p);
1907226633Sdim    Inst.addOperand(MCOperand::CreateImm(mode));
1908226633Sdim    S = MCDisassembler::SoftFail;
1909226633Sdim  }
1910226633Sdim
1911226633Sdim  return S;
1912226633Sdim}
1913226633Sdim
1914234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
1915226633Sdim                                 uint64_t Address, const void *Decoder) {
1916226633Sdim  DecodeStatus S = MCDisassembler::Success;
1917226633Sdim
1918226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 8, 4);
1919226633Sdim  unsigned imm = 0;
1920226633Sdim
1921226633Sdim  imm |= (fieldFromInstruction32(Insn, 0, 8) << 0);
1922226633Sdim  imm |= (fieldFromInstruction32(Insn, 12, 3) << 8);
1923226633Sdim  imm |= (fieldFromInstruction32(Insn, 16, 4) << 12);
1924226633Sdim  imm |= (fieldFromInstruction32(Insn, 26, 1) << 11);
1925226633Sdim
1926226633Sdim  if (Inst.getOpcode() == ARM::t2MOVTi16)
1927226633Sdim    if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1928226633Sdim      return MCDisassembler::Fail;
1929226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1930226633Sdim    return MCDisassembler::Fail;
1931226633Sdim
1932226633Sdim  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
1933226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
1934226633Sdim
1935226633Sdim  return S;
1936226633Sdim}
1937226633Sdim
1938234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
1939226633Sdim                                 uint64_t Address, const void *Decoder) {
1940226633Sdim  DecodeStatus S = MCDisassembler::Success;
1941226633Sdim
1942226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
1943226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1944226633Sdim  unsigned imm = 0;
1945226633Sdim
1946226633Sdim  imm |= (fieldFromInstruction32(Insn, 0, 12) << 0);
1947226633Sdim  imm |= (fieldFromInstruction32(Insn, 16, 4) << 12);
1948226633Sdim
1949226633Sdim  if (Inst.getOpcode() == ARM::MOVTi16)
1950226633Sdim    if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1951226633Sdim      return MCDisassembler::Fail;
1952226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1953226633Sdim    return MCDisassembler::Fail;
1954226633Sdim
1955226633Sdim  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
1956226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
1957226633Sdim
1958226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1959226633Sdim    return MCDisassembler::Fail;
1960226633Sdim
1961226633Sdim  return S;
1962226633Sdim}
1963226633Sdim
1964234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
1965226633Sdim                                 uint64_t Address, const void *Decoder) {
1966226633Sdim  DecodeStatus S = MCDisassembler::Success;
1967226633Sdim
1968226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 16, 4);
1969226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 0, 4);
1970226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 8, 4);
1971226633Sdim  unsigned Ra = fieldFromInstruction32(Insn, 12, 4);
1972226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1973226633Sdim
1974226633Sdim  if (pred == 0xF)
1975226633Sdim    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
1976226633Sdim
1977226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
1978226633Sdim    return MCDisassembler::Fail;
1979226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
1980226633Sdim    return MCDisassembler::Fail;
1981226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1982226633Sdim    return MCDisassembler::Fail;
1983226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
1984226633Sdim    return MCDisassembler::Fail;
1985226633Sdim
1986226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1987226633Sdim    return MCDisassembler::Fail;
1988226633Sdim
1989226633Sdim  return S;
1990226633Sdim}
1991226633Sdim
1992234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
1993226633Sdim                           uint64_t Address, const void *Decoder) {
1994226633Sdim  DecodeStatus S = MCDisassembler::Success;
1995226633Sdim
1996226633Sdim  unsigned add = fieldFromInstruction32(Val, 12, 1);
1997226633Sdim  unsigned imm = fieldFromInstruction32(Val, 0, 12);
1998226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 13, 4);
1999226633Sdim
2000226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2001226633Sdim    return MCDisassembler::Fail;
2002226633Sdim
2003226633Sdim  if (!add) imm *= -1;
2004226633Sdim  if (imm == 0 && !add) imm = INT32_MIN;
2005226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
2006226633Sdim  if (Rn == 15)
2007226633Sdim    tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
2008226633Sdim
2009226633Sdim  return S;
2010226633Sdim}
2011226633Sdim
2012234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
2013226633Sdim                                   uint64_t Address, const void *Decoder) {
2014226633Sdim  DecodeStatus S = MCDisassembler::Success;
2015226633Sdim
2016226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 9, 4);
2017226633Sdim  unsigned U = fieldFromInstruction32(Val, 8, 1);
2018226633Sdim  unsigned imm = fieldFromInstruction32(Val, 0, 8);
2019226633Sdim
2020226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2021226633Sdim    return MCDisassembler::Fail;
2022226633Sdim
2023226633Sdim  if (U)
2024226633Sdim    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
2025226633Sdim  else
2026226633Sdim    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
2027226633Sdim
2028226633Sdim  return S;
2029226633Sdim}
2030226633Sdim
2031234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
2032226633Sdim                                   uint64_t Address, const void *Decoder) {
2033226633Sdim  return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
2034226633Sdim}
2035226633Sdim
2036226633Sdimstatic DecodeStatus
2037234353SdimDecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2038234353Sdim                     uint64_t Address, const void *Decoder) {
2039234353Sdim  DecodeStatus S = MCDisassembler::Success;
2040234353Sdim  unsigned imm = (fieldFromInstruction32(Insn, 0, 11) << 0) |
2041234353Sdim                 (fieldFromInstruction32(Insn, 11, 1) << 18) |
2042234353Sdim                 (fieldFromInstruction32(Insn, 13, 1) << 17) |
2043234353Sdim                 (fieldFromInstruction32(Insn, 16, 6) << 11) |
2044234353Sdim                 (fieldFromInstruction32(Insn, 26, 1) << 19);
2045234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<20>(imm<<1) + 4,
2046234353Sdim                                true, 4, Inst, Decoder))
2047234353Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<20>(imm << 1)));
2048234353Sdim  return S;
2049234353Sdim}
2050234353Sdim
2051234353Sdimstatic DecodeStatus
2052234353SdimDecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
2053226633Sdim                           uint64_t Address, const void *Decoder) {
2054226633Sdim  DecodeStatus S = MCDisassembler::Success;
2055226633Sdim
2056226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
2057226633Sdim  unsigned imm = fieldFromInstruction32(Insn, 0, 24) << 2;
2058226633Sdim
2059226633Sdim  if (pred == 0xF) {
2060226633Sdim    Inst.setOpcode(ARM::BLXi);
2061226633Sdim    imm |= fieldFromInstruction32(Insn, 24, 1) << 1;
2062234353Sdim    if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2063234353Sdim                                  true, 4, Inst, Decoder))
2064226633Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
2065226633Sdim    return S;
2066226633Sdim  }
2067226633Sdim
2068234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2069234353Sdim                                true, 4, Inst, Decoder))
2070226633Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
2071226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2072226633Sdim    return MCDisassembler::Fail;
2073226633Sdim
2074226633Sdim  return S;
2075226633Sdim}
2076226633Sdim
2077226633Sdim
2078234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
2079226633Sdim                                   uint64_t Address, const void *Decoder) {
2080226633Sdim  DecodeStatus S = MCDisassembler::Success;
2081226633Sdim
2082226633Sdim  unsigned Rm = fieldFromInstruction32(Val, 0, 4);
2083226633Sdim  unsigned align = fieldFromInstruction32(Val, 4, 2);
2084226633Sdim
2085226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2086226633Sdim    return MCDisassembler::Fail;
2087226633Sdim  if (!align)
2088226633Sdim    Inst.addOperand(MCOperand::CreateImm(0));
2089226633Sdim  else
2090226633Sdim    Inst.addOperand(MCOperand::CreateImm(4 << align));
2091226633Sdim
2092226633Sdim  return S;
2093226633Sdim}
2094226633Sdim
2095234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
2096226633Sdim                                   uint64_t Address, const void *Decoder) {
2097226633Sdim  DecodeStatus S = MCDisassembler::Success;
2098226633Sdim
2099226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2100226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2101226633Sdim  unsigned wb = fieldFromInstruction32(Insn, 16, 4);
2102226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2103226633Sdim  Rn |= fieldFromInstruction32(Insn, 4, 2) << 4;
2104226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2105226633Sdim
2106226633Sdim  // First output register
2107234353Sdim  switch (Inst.getOpcode()) {
2108234353Sdim  case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
2109234353Sdim  case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
2110234353Sdim  case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
2111234353Sdim  case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
2112234353Sdim  case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
2113234353Sdim  case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
2114234353Sdim  case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
2115234353Sdim  case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
2116234353Sdim  case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
2117234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2118234353Sdim      return MCDisassembler::Fail;
2119234353Sdim    break;
2120234353Sdim  case ARM::VLD2b16:
2121234353Sdim  case ARM::VLD2b32:
2122234353Sdim  case ARM::VLD2b8:
2123234353Sdim  case ARM::VLD2b16wb_fixed:
2124234353Sdim  case ARM::VLD2b16wb_register:
2125234353Sdim  case ARM::VLD2b32wb_fixed:
2126234353Sdim  case ARM::VLD2b32wb_register:
2127234353Sdim  case ARM::VLD2b8wb_fixed:
2128234353Sdim  case ARM::VLD2b8wb_register:
2129234353Sdim    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2130234353Sdim      return MCDisassembler::Fail;
2131234353Sdim    break;
2132234353Sdim  default:
2133234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2134234353Sdim      return MCDisassembler::Fail;
2135234353Sdim  }
2136226633Sdim
2137226633Sdim  // Second output register
2138226633Sdim  switch (Inst.getOpcode()) {
2139226633Sdim    case ARM::VLD3d8:
2140226633Sdim    case ARM::VLD3d16:
2141226633Sdim    case ARM::VLD3d32:
2142226633Sdim    case ARM::VLD3d8_UPD:
2143226633Sdim    case ARM::VLD3d16_UPD:
2144226633Sdim    case ARM::VLD3d32_UPD:
2145226633Sdim    case ARM::VLD4d8:
2146226633Sdim    case ARM::VLD4d16:
2147226633Sdim    case ARM::VLD4d32:
2148226633Sdim    case ARM::VLD4d8_UPD:
2149226633Sdim    case ARM::VLD4d16_UPD:
2150226633Sdim    case ARM::VLD4d32_UPD:
2151226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2152226633Sdim        return MCDisassembler::Fail;
2153206124Srdivacky      break;
2154226633Sdim    case ARM::VLD3q8:
2155226633Sdim    case ARM::VLD3q16:
2156226633Sdim    case ARM::VLD3q32:
2157226633Sdim    case ARM::VLD3q8_UPD:
2158226633Sdim    case ARM::VLD3q16_UPD:
2159226633Sdim    case ARM::VLD3q32_UPD:
2160226633Sdim    case ARM::VLD4q8:
2161226633Sdim    case ARM::VLD4q16:
2162226633Sdim    case ARM::VLD4q32:
2163226633Sdim    case ARM::VLD4q8_UPD:
2164226633Sdim    case ARM::VLD4q16_UPD:
2165226633Sdim    case ARM::VLD4q32_UPD:
2166226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2167226633Sdim        return MCDisassembler::Fail;
2168206124Srdivacky    default:
2169226633Sdim      break;
2170226633Sdim  }
2171226633Sdim
2172226633Sdim  // Third output register
2173226633Sdim  switch(Inst.getOpcode()) {
2174226633Sdim    case ARM::VLD3d8:
2175226633Sdim    case ARM::VLD3d16:
2176226633Sdim    case ARM::VLD3d32:
2177226633Sdim    case ARM::VLD3d8_UPD:
2178226633Sdim    case ARM::VLD3d16_UPD:
2179226633Sdim    case ARM::VLD3d32_UPD:
2180226633Sdim    case ARM::VLD4d8:
2181226633Sdim    case ARM::VLD4d16:
2182226633Sdim    case ARM::VLD4d32:
2183226633Sdim    case ARM::VLD4d8_UPD:
2184226633Sdim    case ARM::VLD4d16_UPD:
2185226633Sdim    case ARM::VLD4d32_UPD:
2186226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2187226633Sdim        return MCDisassembler::Fail;
2188226633Sdim      break;
2189226633Sdim    case ARM::VLD3q8:
2190226633Sdim    case ARM::VLD3q16:
2191226633Sdim    case ARM::VLD3q32:
2192226633Sdim    case ARM::VLD3q8_UPD:
2193226633Sdim    case ARM::VLD3q16_UPD:
2194226633Sdim    case ARM::VLD3q32_UPD:
2195226633Sdim    case ARM::VLD4q8:
2196226633Sdim    case ARM::VLD4q16:
2197226633Sdim    case ARM::VLD4q32:
2198226633Sdim    case ARM::VLD4q8_UPD:
2199226633Sdim    case ARM::VLD4q16_UPD:
2200226633Sdim    case ARM::VLD4q32_UPD:
2201226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2202226633Sdim        return MCDisassembler::Fail;
2203226633Sdim      break;
2204226633Sdim    default:
2205226633Sdim      break;
2206226633Sdim  }
2207226633Sdim
2208226633Sdim  // Fourth output register
2209226633Sdim  switch (Inst.getOpcode()) {
2210226633Sdim    case ARM::VLD4d8:
2211226633Sdim    case ARM::VLD4d16:
2212226633Sdim    case ARM::VLD4d32:
2213226633Sdim    case ARM::VLD4d8_UPD:
2214226633Sdim    case ARM::VLD4d16_UPD:
2215226633Sdim    case ARM::VLD4d32_UPD:
2216226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2217226633Sdim        return MCDisassembler::Fail;
2218226633Sdim      break;
2219226633Sdim    case ARM::VLD4q8:
2220226633Sdim    case ARM::VLD4q16:
2221226633Sdim    case ARM::VLD4q32:
2222226633Sdim    case ARM::VLD4q8_UPD:
2223226633Sdim    case ARM::VLD4q16_UPD:
2224226633Sdim    case ARM::VLD4q32_UPD:
2225226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2226226633Sdim        return MCDisassembler::Fail;
2227226633Sdim      break;
2228226633Sdim    default:
2229226633Sdim      break;
2230226633Sdim  }
2231226633Sdim
2232226633Sdim  // Writeback operand
2233226633Sdim  switch (Inst.getOpcode()) {
2234234353Sdim    case ARM::VLD1d8wb_fixed:
2235234353Sdim    case ARM::VLD1d16wb_fixed:
2236234353Sdim    case ARM::VLD1d32wb_fixed:
2237234353Sdim    case ARM::VLD1d64wb_fixed:
2238234353Sdim    case ARM::VLD1d8wb_register:
2239234353Sdim    case ARM::VLD1d16wb_register:
2240234353Sdim    case ARM::VLD1d32wb_register:
2241234353Sdim    case ARM::VLD1d64wb_register:
2242234353Sdim    case ARM::VLD1q8wb_fixed:
2243234353Sdim    case ARM::VLD1q16wb_fixed:
2244234353Sdim    case ARM::VLD1q32wb_fixed:
2245234353Sdim    case ARM::VLD1q64wb_fixed:
2246234353Sdim    case ARM::VLD1q8wb_register:
2247234353Sdim    case ARM::VLD1q16wb_register:
2248234353Sdim    case ARM::VLD1q32wb_register:
2249234353Sdim    case ARM::VLD1q64wb_register:
2250234353Sdim    case ARM::VLD1d8Twb_fixed:
2251234353Sdim    case ARM::VLD1d8Twb_register:
2252234353Sdim    case ARM::VLD1d16Twb_fixed:
2253234353Sdim    case ARM::VLD1d16Twb_register:
2254234353Sdim    case ARM::VLD1d32Twb_fixed:
2255234353Sdim    case ARM::VLD1d32Twb_register:
2256234353Sdim    case ARM::VLD1d64Twb_fixed:
2257234353Sdim    case ARM::VLD1d64Twb_register:
2258234353Sdim    case ARM::VLD1d8Qwb_fixed:
2259234353Sdim    case ARM::VLD1d8Qwb_register:
2260234353Sdim    case ARM::VLD1d16Qwb_fixed:
2261234353Sdim    case ARM::VLD1d16Qwb_register:
2262234353Sdim    case ARM::VLD1d32Qwb_fixed:
2263234353Sdim    case ARM::VLD1d32Qwb_register:
2264234353Sdim    case ARM::VLD1d64Qwb_fixed:
2265234353Sdim    case ARM::VLD1d64Qwb_register:
2266234353Sdim    case ARM::VLD2d8wb_fixed:
2267234353Sdim    case ARM::VLD2d16wb_fixed:
2268234353Sdim    case ARM::VLD2d32wb_fixed:
2269234353Sdim    case ARM::VLD2q8wb_fixed:
2270234353Sdim    case ARM::VLD2q16wb_fixed:
2271234353Sdim    case ARM::VLD2q32wb_fixed:
2272234353Sdim    case ARM::VLD2d8wb_register:
2273234353Sdim    case ARM::VLD2d16wb_register:
2274234353Sdim    case ARM::VLD2d32wb_register:
2275234353Sdim    case ARM::VLD2q8wb_register:
2276234353Sdim    case ARM::VLD2q16wb_register:
2277234353Sdim    case ARM::VLD2q32wb_register:
2278234353Sdim    case ARM::VLD2b8wb_fixed:
2279234353Sdim    case ARM::VLD2b16wb_fixed:
2280234353Sdim    case ARM::VLD2b32wb_fixed:
2281234353Sdim    case ARM::VLD2b8wb_register:
2282234353Sdim    case ARM::VLD2b16wb_register:
2283234353Sdim    case ARM::VLD2b32wb_register:
2284234353Sdim      Inst.addOperand(MCOperand::CreateImm(0));
2285234353Sdim      break;
2286226633Sdim    case ARM::VLD3d8_UPD:
2287226633Sdim    case ARM::VLD3d16_UPD:
2288226633Sdim    case ARM::VLD3d32_UPD:
2289226633Sdim    case ARM::VLD3q8_UPD:
2290226633Sdim    case ARM::VLD3q16_UPD:
2291226633Sdim    case ARM::VLD3q32_UPD:
2292226633Sdim    case ARM::VLD4d8_UPD:
2293226633Sdim    case ARM::VLD4d16_UPD:
2294226633Sdim    case ARM::VLD4d32_UPD:
2295226633Sdim    case ARM::VLD4q8_UPD:
2296226633Sdim    case ARM::VLD4q16_UPD:
2297226633Sdim    case ARM::VLD4q32_UPD:
2298226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2299226633Sdim        return MCDisassembler::Fail;
2300226633Sdim      break;
2301226633Sdim    default:
2302226633Sdim      break;
2303226633Sdim  }
2304226633Sdim
2305226633Sdim  // AddrMode6 Base (register+alignment)
2306226633Sdim  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2307226633Sdim    return MCDisassembler::Fail;
2308226633Sdim
2309226633Sdim  // AddrMode6 Offset (register)
2310234353Sdim  switch (Inst.getOpcode()) {
2311234353Sdim  default:
2312234353Sdim    // The below have been updated to have explicit am6offset split
2313234353Sdim    // between fixed and register offset. For those instructions not
2314234353Sdim    // yet updated, we need to add an additional reg0 operand for the
2315234353Sdim    // fixed variant.
2316234353Sdim    //
2317234353Sdim    // The fixed offset encodes as Rm == 0xd, so we check for that.
2318234353Sdim    if (Rm == 0xd) {
2319234353Sdim      Inst.addOperand(MCOperand::CreateReg(0));
2320234353Sdim      break;
2321234353Sdim    }
2322234353Sdim    // Fall through to handle the register offset variant.
2323234353Sdim  case ARM::VLD1d8wb_fixed:
2324234353Sdim  case ARM::VLD1d16wb_fixed:
2325234353Sdim  case ARM::VLD1d32wb_fixed:
2326234353Sdim  case ARM::VLD1d64wb_fixed:
2327234353Sdim  case ARM::VLD1d8Twb_fixed:
2328234353Sdim  case ARM::VLD1d16Twb_fixed:
2329234353Sdim  case ARM::VLD1d32Twb_fixed:
2330234353Sdim  case ARM::VLD1d64Twb_fixed:
2331234353Sdim  case ARM::VLD1d8Qwb_fixed:
2332234353Sdim  case ARM::VLD1d16Qwb_fixed:
2333234353Sdim  case ARM::VLD1d32Qwb_fixed:
2334234353Sdim  case ARM::VLD1d64Qwb_fixed:
2335234353Sdim  case ARM::VLD1d8wb_register:
2336234353Sdim  case ARM::VLD1d16wb_register:
2337234353Sdim  case ARM::VLD1d32wb_register:
2338234353Sdim  case ARM::VLD1d64wb_register:
2339234353Sdim  case ARM::VLD1q8wb_fixed:
2340234353Sdim  case ARM::VLD1q16wb_fixed:
2341234353Sdim  case ARM::VLD1q32wb_fixed:
2342234353Sdim  case ARM::VLD1q64wb_fixed:
2343234353Sdim  case ARM::VLD1q8wb_register:
2344234353Sdim  case ARM::VLD1q16wb_register:
2345234353Sdim  case ARM::VLD1q32wb_register:
2346234353Sdim  case ARM::VLD1q64wb_register:
2347234353Sdim    // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2348234353Sdim    // variant encodes Rm == 0xf. Anything else is a register offset post-
2349234353Sdim    // increment and we need to add the register operand to the instruction.
2350234353Sdim    if (Rm != 0xD && Rm != 0xF &&
2351234353Sdim        !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2352226633Sdim      return MCDisassembler::Fail;
2353234353Sdim    break;
2354234353Sdim  case ARM::VLD2d8wb_fixed:
2355234353Sdim  case ARM::VLD2d16wb_fixed:
2356234353Sdim  case ARM::VLD2d32wb_fixed:
2357234353Sdim  case ARM::VLD2b8wb_fixed:
2358234353Sdim  case ARM::VLD2b16wb_fixed:
2359234353Sdim  case ARM::VLD2b32wb_fixed:
2360234353Sdim  case ARM::VLD2q8wb_fixed:
2361234353Sdim  case ARM::VLD2q16wb_fixed:
2362234353Sdim  case ARM::VLD2q32wb_fixed:
2363234353Sdim    break;
2364226633Sdim  }
2365226633Sdim
2366226633Sdim  return S;
2367226633Sdim}
2368226633Sdim
2369234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
2370226633Sdim                                 uint64_t Address, const void *Decoder) {
2371226633Sdim  DecodeStatus S = MCDisassembler::Success;
2372226633Sdim
2373226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2374226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2375226633Sdim  unsigned wb = fieldFromInstruction32(Insn, 16, 4);
2376226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2377226633Sdim  Rn |= fieldFromInstruction32(Insn, 4, 2) << 4;
2378226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2379226633Sdim
2380226633Sdim  // Writeback Operand
2381226633Sdim  switch (Inst.getOpcode()) {
2382234353Sdim    case ARM::VST1d8wb_fixed:
2383234353Sdim    case ARM::VST1d16wb_fixed:
2384234353Sdim    case ARM::VST1d32wb_fixed:
2385234353Sdim    case ARM::VST1d64wb_fixed:
2386234353Sdim    case ARM::VST1d8wb_register:
2387234353Sdim    case ARM::VST1d16wb_register:
2388234353Sdim    case ARM::VST1d32wb_register:
2389234353Sdim    case ARM::VST1d64wb_register:
2390234353Sdim    case ARM::VST1q8wb_fixed:
2391234353Sdim    case ARM::VST1q16wb_fixed:
2392234353Sdim    case ARM::VST1q32wb_fixed:
2393234353Sdim    case ARM::VST1q64wb_fixed:
2394234353Sdim    case ARM::VST1q8wb_register:
2395234353Sdim    case ARM::VST1q16wb_register:
2396234353Sdim    case ARM::VST1q32wb_register:
2397234353Sdim    case ARM::VST1q64wb_register:
2398234353Sdim    case ARM::VST1d8Twb_fixed:
2399234353Sdim    case ARM::VST1d16Twb_fixed:
2400234353Sdim    case ARM::VST1d32Twb_fixed:
2401234353Sdim    case ARM::VST1d64Twb_fixed:
2402234353Sdim    case ARM::VST1d8Twb_register:
2403234353Sdim    case ARM::VST1d16Twb_register:
2404234353Sdim    case ARM::VST1d32Twb_register:
2405234353Sdim    case ARM::VST1d64Twb_register:
2406234353Sdim    case ARM::VST1d8Qwb_fixed:
2407234353Sdim    case ARM::VST1d16Qwb_fixed:
2408234353Sdim    case ARM::VST1d32Qwb_fixed:
2409234353Sdim    case ARM::VST1d64Qwb_fixed:
2410234353Sdim    case ARM::VST1d8Qwb_register:
2411234353Sdim    case ARM::VST1d16Qwb_register:
2412234353Sdim    case ARM::VST1d32Qwb_register:
2413234353Sdim    case ARM::VST1d64Qwb_register:
2414234353Sdim    case ARM::VST2d8wb_fixed:
2415234353Sdim    case ARM::VST2d16wb_fixed:
2416234353Sdim    case ARM::VST2d32wb_fixed:
2417234353Sdim    case ARM::VST2d8wb_register:
2418234353Sdim    case ARM::VST2d16wb_register:
2419234353Sdim    case ARM::VST2d32wb_register:
2420234353Sdim    case ARM::VST2q8wb_fixed:
2421234353Sdim    case ARM::VST2q16wb_fixed:
2422234353Sdim    case ARM::VST2q32wb_fixed:
2423234353Sdim    case ARM::VST2q8wb_register:
2424234353Sdim    case ARM::VST2q16wb_register:
2425234353Sdim    case ARM::VST2q32wb_register:
2426234353Sdim    case ARM::VST2b8wb_fixed:
2427234353Sdim    case ARM::VST2b16wb_fixed:
2428234353Sdim    case ARM::VST2b32wb_fixed:
2429234353Sdim    case ARM::VST2b8wb_register:
2430234353Sdim    case ARM::VST2b16wb_register:
2431234353Sdim    case ARM::VST2b32wb_register:
2432234353Sdim      if (Rm == 0xF)
2433234353Sdim        return MCDisassembler::Fail;
2434234353Sdim      Inst.addOperand(MCOperand::CreateImm(0));
2435234353Sdim      break;
2436226633Sdim    case ARM::VST3d8_UPD:
2437226633Sdim    case ARM::VST3d16_UPD:
2438226633Sdim    case ARM::VST3d32_UPD:
2439226633Sdim    case ARM::VST3q8_UPD:
2440226633Sdim    case ARM::VST3q16_UPD:
2441226633Sdim    case ARM::VST3q32_UPD:
2442226633Sdim    case ARM::VST4d8_UPD:
2443226633Sdim    case ARM::VST4d16_UPD:
2444226633Sdim    case ARM::VST4d32_UPD:
2445226633Sdim    case ARM::VST4q8_UPD:
2446226633Sdim    case ARM::VST4q16_UPD:
2447226633Sdim    case ARM::VST4q32_UPD:
2448226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2449226633Sdim        return MCDisassembler::Fail;
2450226633Sdim      break;
2451226633Sdim    default:
2452226633Sdim      break;
2453226633Sdim  }
2454226633Sdim
2455226633Sdim  // AddrMode6 Base (register+alignment)
2456226633Sdim  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2457226633Sdim    return MCDisassembler::Fail;
2458226633Sdim
2459226633Sdim  // AddrMode6 Offset (register)
2460234353Sdim  switch (Inst.getOpcode()) {
2461234353Sdim    default:
2462234353Sdim      if (Rm == 0xD)
2463234353Sdim        Inst.addOperand(MCOperand::CreateReg(0));
2464234353Sdim      else if (Rm != 0xF) {
2465234353Sdim        if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2466234353Sdim          return MCDisassembler::Fail;
2467234353Sdim      }
2468234353Sdim      break;
2469234353Sdim    case ARM::VST1d8wb_fixed:
2470234353Sdim    case ARM::VST1d16wb_fixed:
2471234353Sdim    case ARM::VST1d32wb_fixed:
2472234353Sdim    case ARM::VST1d64wb_fixed:
2473234353Sdim    case ARM::VST1q8wb_fixed:
2474234353Sdim    case ARM::VST1q16wb_fixed:
2475234353Sdim    case ARM::VST1q32wb_fixed:
2476234353Sdim    case ARM::VST1q64wb_fixed:
2477234353Sdim    case ARM::VST1d8Twb_fixed:
2478234353Sdim    case ARM::VST1d16Twb_fixed:
2479234353Sdim    case ARM::VST1d32Twb_fixed:
2480234353Sdim    case ARM::VST1d64Twb_fixed:
2481234353Sdim    case ARM::VST1d8Qwb_fixed:
2482234353Sdim    case ARM::VST1d16Qwb_fixed:
2483234353Sdim    case ARM::VST1d32Qwb_fixed:
2484234353Sdim    case ARM::VST1d64Qwb_fixed:
2485234353Sdim    case ARM::VST2d8wb_fixed:
2486234353Sdim    case ARM::VST2d16wb_fixed:
2487234353Sdim    case ARM::VST2d32wb_fixed:
2488234353Sdim    case ARM::VST2q8wb_fixed:
2489234353Sdim    case ARM::VST2q16wb_fixed:
2490234353Sdim    case ARM::VST2q32wb_fixed:
2491234353Sdim    case ARM::VST2b8wb_fixed:
2492234353Sdim    case ARM::VST2b16wb_fixed:
2493234353Sdim    case ARM::VST2b32wb_fixed:
2494234353Sdim      break;
2495226633Sdim  }
2496226633Sdim
2497234353Sdim
2498226633Sdim  // First input register
2499234353Sdim  switch (Inst.getOpcode()) {
2500234353Sdim  case ARM::VST1q16:
2501234353Sdim  case ARM::VST1q32:
2502234353Sdim  case ARM::VST1q64:
2503234353Sdim  case ARM::VST1q8:
2504234353Sdim  case ARM::VST1q16wb_fixed:
2505234353Sdim  case ARM::VST1q16wb_register:
2506234353Sdim  case ARM::VST1q32wb_fixed:
2507234353Sdim  case ARM::VST1q32wb_register:
2508234353Sdim  case ARM::VST1q64wb_fixed:
2509234353Sdim  case ARM::VST1q64wb_register:
2510234353Sdim  case ARM::VST1q8wb_fixed:
2511234353Sdim  case ARM::VST1q8wb_register:
2512234353Sdim  case ARM::VST2d16:
2513234353Sdim  case ARM::VST2d32:
2514234353Sdim  case ARM::VST2d8:
2515234353Sdim  case ARM::VST2d16wb_fixed:
2516234353Sdim  case ARM::VST2d16wb_register:
2517234353Sdim  case ARM::VST2d32wb_fixed:
2518234353Sdim  case ARM::VST2d32wb_register:
2519234353Sdim  case ARM::VST2d8wb_fixed:
2520234353Sdim  case ARM::VST2d8wb_register:
2521234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2522234353Sdim      return MCDisassembler::Fail;
2523234353Sdim    break;
2524234353Sdim  case ARM::VST2b16:
2525234353Sdim  case ARM::VST2b32:
2526234353Sdim  case ARM::VST2b8:
2527234353Sdim  case ARM::VST2b16wb_fixed:
2528234353Sdim  case ARM::VST2b16wb_register:
2529234353Sdim  case ARM::VST2b32wb_fixed:
2530234353Sdim  case ARM::VST2b32wb_register:
2531234353Sdim  case ARM::VST2b8wb_fixed:
2532234353Sdim  case ARM::VST2b8wb_register:
2533234353Sdim    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2534234353Sdim      return MCDisassembler::Fail;
2535234353Sdim    break;
2536234353Sdim  default:
2537234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2538234353Sdim      return MCDisassembler::Fail;
2539234353Sdim  }
2540226633Sdim
2541226633Sdim  // Second input register
2542226633Sdim  switch (Inst.getOpcode()) {
2543226633Sdim    case ARM::VST3d8:
2544226633Sdim    case ARM::VST3d16:
2545226633Sdim    case ARM::VST3d32:
2546226633Sdim    case ARM::VST3d8_UPD:
2547226633Sdim    case ARM::VST3d16_UPD:
2548226633Sdim    case ARM::VST3d32_UPD:
2549226633Sdim    case ARM::VST4d8:
2550226633Sdim    case ARM::VST4d16:
2551226633Sdim    case ARM::VST4d32:
2552226633Sdim    case ARM::VST4d8_UPD:
2553226633Sdim    case ARM::VST4d16_UPD:
2554226633Sdim    case ARM::VST4d32_UPD:
2555226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2556226633Sdim        return MCDisassembler::Fail;
2557226633Sdim      break;
2558226633Sdim    case ARM::VST3q8:
2559226633Sdim    case ARM::VST3q16:
2560226633Sdim    case ARM::VST3q32:
2561226633Sdim    case ARM::VST3q8_UPD:
2562226633Sdim    case ARM::VST3q16_UPD:
2563226633Sdim    case ARM::VST3q32_UPD:
2564226633Sdim    case ARM::VST4q8:
2565226633Sdim    case ARM::VST4q16:
2566226633Sdim    case ARM::VST4q32:
2567226633Sdim    case ARM::VST4q8_UPD:
2568226633Sdim    case ARM::VST4q16_UPD:
2569226633Sdim    case ARM::VST4q32_UPD:
2570226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2571226633Sdim        return MCDisassembler::Fail;
2572226633Sdim      break;
2573226633Sdim    default:
2574226633Sdim      break;
2575226633Sdim  }
2576226633Sdim
2577226633Sdim  // Third input register
2578226633Sdim  switch (Inst.getOpcode()) {
2579226633Sdim    case ARM::VST3d8:
2580226633Sdim    case ARM::VST3d16:
2581226633Sdim    case ARM::VST3d32:
2582226633Sdim    case ARM::VST3d8_UPD:
2583226633Sdim    case ARM::VST3d16_UPD:
2584226633Sdim    case ARM::VST3d32_UPD:
2585226633Sdim    case ARM::VST4d8:
2586226633Sdim    case ARM::VST4d16:
2587226633Sdim    case ARM::VST4d32:
2588226633Sdim    case ARM::VST4d8_UPD:
2589226633Sdim    case ARM::VST4d16_UPD:
2590226633Sdim    case ARM::VST4d32_UPD:
2591226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2592226633Sdim        return MCDisassembler::Fail;
2593226633Sdim      break;
2594226633Sdim    case ARM::VST3q8:
2595226633Sdim    case ARM::VST3q16:
2596226633Sdim    case ARM::VST3q32:
2597226633Sdim    case ARM::VST3q8_UPD:
2598226633Sdim    case ARM::VST3q16_UPD:
2599226633Sdim    case ARM::VST3q32_UPD:
2600226633Sdim    case ARM::VST4q8:
2601226633Sdim    case ARM::VST4q16:
2602226633Sdim    case ARM::VST4q32:
2603226633Sdim    case ARM::VST4q8_UPD:
2604226633Sdim    case ARM::VST4q16_UPD:
2605226633Sdim    case ARM::VST4q32_UPD:
2606226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2607226633Sdim        return MCDisassembler::Fail;
2608226633Sdim      break;
2609226633Sdim    default:
2610226633Sdim      break;
2611226633Sdim  }
2612226633Sdim
2613226633Sdim  // Fourth input register
2614226633Sdim  switch (Inst.getOpcode()) {
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+3)%32, Address, Decoder)))
2622226633Sdim        return MCDisassembler::Fail;
2623226633Sdim      break;
2624226633Sdim    case ARM::VST4q8:
2625226633Sdim    case ARM::VST4q16:
2626226633Sdim    case ARM::VST4q32:
2627226633Sdim    case ARM::VST4q8_UPD:
2628226633Sdim    case ARM::VST4q16_UPD:
2629226633Sdim    case ARM::VST4q32_UPD:
2630226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2631226633Sdim        return MCDisassembler::Fail;
2632226633Sdim      break;
2633226633Sdim    default:
2634226633Sdim      break;
2635226633Sdim  }
2636226633Sdim
2637226633Sdim  return S;
2638226633Sdim}
2639226633Sdim
2640234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
2641226633Sdim                                    uint64_t Address, const void *Decoder) {
2642226633Sdim  DecodeStatus S = MCDisassembler::Success;
2643226633Sdim
2644226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2645226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2646226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2647226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2648226633Sdim  unsigned align = fieldFromInstruction32(Insn, 4, 1);
2649226633Sdim  unsigned size = fieldFromInstruction32(Insn, 6, 2);
2650226633Sdim
2651226633Sdim  align *= (1 << size);
2652226633Sdim
2653234353Sdim  switch (Inst.getOpcode()) {
2654234353Sdim  case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
2655234353Sdim  case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
2656234353Sdim  case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
2657234353Sdim  case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
2658234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2659226633Sdim      return MCDisassembler::Fail;
2660234353Sdim    break;
2661234353Sdim  default:
2662234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2663234353Sdim      return MCDisassembler::Fail;
2664234353Sdim    break;
2665226633Sdim  }
2666226633Sdim  if (Rm != 0xF) {
2667226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2668226633Sdim      return MCDisassembler::Fail;
2669226633Sdim  }
2670226633Sdim
2671226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2672226633Sdim    return MCDisassembler::Fail;
2673226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
2674226633Sdim
2675234353Sdim  // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2676234353Sdim  // variant encodes Rm == 0xf. Anything else is a register offset post-
2677234353Sdim  // increment and we need to add the register operand to the instruction.
2678234353Sdim  if (Rm != 0xD && Rm != 0xF &&
2679234353Sdim      !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2680234353Sdim    return MCDisassembler::Fail;
2681226633Sdim
2682226633Sdim  return S;
2683226633Sdim}
2684226633Sdim
2685234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
2686226633Sdim                                    uint64_t Address, const void *Decoder) {
2687226633Sdim  DecodeStatus S = MCDisassembler::Success;
2688226633Sdim
2689226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2690226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2691226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2692226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2693226633Sdim  unsigned align = fieldFromInstruction32(Insn, 4, 1);
2694226633Sdim  unsigned size = 1 << fieldFromInstruction32(Insn, 6, 2);
2695226633Sdim  align *= 2*size;
2696226633Sdim
2697234353Sdim  switch (Inst.getOpcode()) {
2698234353Sdim  case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
2699234353Sdim  case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
2700234353Sdim  case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
2701234353Sdim  case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
2702234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2703226633Sdim      return MCDisassembler::Fail;
2704234353Sdim    break;
2705234353Sdim  case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
2706234353Sdim  case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
2707234353Sdim  case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
2708234353Sdim  case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
2709234353Sdim    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2710234353Sdim      return MCDisassembler::Fail;
2711234353Sdim    break;
2712234353Sdim  default:
2713234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2714234353Sdim      return MCDisassembler::Fail;
2715234353Sdim    break;
2716226633Sdim  }
2717226633Sdim
2718234353Sdim  if (Rm != 0xF)
2719234353Sdim    Inst.addOperand(MCOperand::CreateImm(0));
2720234353Sdim
2721226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2722226633Sdim    return MCDisassembler::Fail;
2723226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
2724226633Sdim
2725234982Sdim  if (Rm != 0xD && Rm != 0xF) {
2726226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2727226633Sdim      return MCDisassembler::Fail;
2728226633Sdim  }
2729226633Sdim
2730226633Sdim  return S;
2731226633Sdim}
2732226633Sdim
2733234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
2734226633Sdim                                    uint64_t Address, const void *Decoder) {
2735226633Sdim  DecodeStatus S = MCDisassembler::Success;
2736226633Sdim
2737226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2738226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2739226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2740226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2741226633Sdim  unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
2742226633Sdim
2743226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2744226633Sdim    return MCDisassembler::Fail;
2745226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2746226633Sdim    return MCDisassembler::Fail;
2747226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2748226633Sdim    return MCDisassembler::Fail;
2749226633Sdim  if (Rm != 0xF) {
2750226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2751226633Sdim      return MCDisassembler::Fail;
2752226633Sdim  }
2753226633Sdim
2754226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2755226633Sdim    return MCDisassembler::Fail;
2756226633Sdim  Inst.addOperand(MCOperand::CreateImm(0));
2757226633Sdim
2758226633Sdim  if (Rm == 0xD)
2759226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
2760226633Sdim  else if (Rm != 0xF) {
2761226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2762226633Sdim      return MCDisassembler::Fail;
2763226633Sdim  }
2764226633Sdim
2765226633Sdim  return S;
2766226633Sdim}
2767226633Sdim
2768234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
2769226633Sdim                                    uint64_t Address, const void *Decoder) {
2770226633Sdim  DecodeStatus S = MCDisassembler::Success;
2771226633Sdim
2772226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2773226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2774226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2775226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2776226633Sdim  unsigned size = fieldFromInstruction32(Insn, 6, 2);
2777226633Sdim  unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
2778226633Sdim  unsigned align = fieldFromInstruction32(Insn, 4, 1);
2779226633Sdim
2780226633Sdim  if (size == 0x3) {
2781226633Sdim    size = 4;
2782226633Sdim    align = 16;
2783226633Sdim  } else {
2784226633Sdim    if (size == 2) {
2785226633Sdim      size = 1 << size;
2786226633Sdim      align *= 8;
2787226633Sdim    } else {
2788226633Sdim      size = 1 << size;
2789226633Sdim      align *= 4*size;
2790206124Srdivacky    }
2791206124Srdivacky  }
2792206124Srdivacky
2793226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2794226633Sdim    return MCDisassembler::Fail;
2795226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2796226633Sdim    return MCDisassembler::Fail;
2797226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2798226633Sdim    return MCDisassembler::Fail;
2799226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
2800226633Sdim    return MCDisassembler::Fail;
2801226633Sdim  if (Rm != 0xF) {
2802226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2803226633Sdim      return MCDisassembler::Fail;
2804226633Sdim  }
2805226633Sdim
2806226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2807226633Sdim    return MCDisassembler::Fail;
2808226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
2809226633Sdim
2810226633Sdim  if (Rm == 0xD)
2811226633Sdim    Inst.addOperand(MCOperand::CreateReg(0));
2812226633Sdim  else if (Rm != 0xF) {
2813226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2814226633Sdim      return MCDisassembler::Fail;
2815226633Sdim  }
2816226633Sdim
2817226633Sdim  return S;
2818206124Srdivacky}
2819206124Srdivacky
2820226633Sdimstatic DecodeStatus
2821234353SdimDecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn,
2822226633Sdim                            uint64_t Address, const void *Decoder) {
2823226633Sdim  DecodeStatus S = MCDisassembler::Success;
2824206124Srdivacky
2825226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2826226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2827226633Sdim  unsigned imm = fieldFromInstruction32(Insn, 0, 4);
2828226633Sdim  imm |= fieldFromInstruction32(Insn, 16, 3) << 4;
2829226633Sdim  imm |= fieldFromInstruction32(Insn, 24, 1) << 7;
2830226633Sdim  imm |= fieldFromInstruction32(Insn, 8, 4) << 8;
2831226633Sdim  imm |= fieldFromInstruction32(Insn, 5, 1) << 12;
2832226633Sdim  unsigned Q = fieldFromInstruction32(Insn, 6, 1);
2833206124Srdivacky
2834226633Sdim  if (Q) {
2835226633Sdim    if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
2836226633Sdim    return MCDisassembler::Fail;
2837226633Sdim  } else {
2838226633Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2839226633Sdim    return MCDisassembler::Fail;
2840226633Sdim  }
2841206124Srdivacky
2842226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
2843206124Srdivacky
2844226633Sdim  switch (Inst.getOpcode()) {
2845226633Sdim    case ARM::VORRiv4i16:
2846226633Sdim    case ARM::VORRiv2i32:
2847226633Sdim    case ARM::VBICiv4i16:
2848226633Sdim    case ARM::VBICiv2i32:
2849226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2850226633Sdim        return MCDisassembler::Fail;
2851226633Sdim      break;
2852226633Sdim    case ARM::VORRiv8i16:
2853226633Sdim    case ARM::VORRiv4i32:
2854226633Sdim    case ARM::VBICiv8i16:
2855226633Sdim    case ARM::VBICiv4i32:
2856226633Sdim      if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
2857226633Sdim        return MCDisassembler::Fail;
2858226633Sdim      break;
2859226633Sdim    default:
2860226633Sdim      break;
2861226633Sdim  }
2862206124Srdivacky
2863226633Sdim  return S;
2864226633Sdim}
2865226633Sdim
2866234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
2867226633Sdim                                        uint64_t Address, const void *Decoder) {
2868226633Sdim  DecodeStatus S = MCDisassembler::Success;
2869226633Sdim
2870226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2871226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2872226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2873226633Sdim  Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
2874226633Sdim  unsigned size = fieldFromInstruction32(Insn, 18, 2);
2875226633Sdim
2876226633Sdim  if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
2877226633Sdim    return MCDisassembler::Fail;
2878226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
2879226633Sdim    return MCDisassembler::Fail;
2880226633Sdim  Inst.addOperand(MCOperand::CreateImm(8 << size));
2881226633Sdim
2882226633Sdim  return S;
2883226633Sdim}
2884226633Sdim
2885234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
2886226633Sdim                               uint64_t Address, const void *Decoder) {
2887226633Sdim  Inst.addOperand(MCOperand::CreateImm(8 - Val));
2888226633Sdim  return MCDisassembler::Success;
2889226633Sdim}
2890226633Sdim
2891234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
2892226633Sdim                               uint64_t Address, const void *Decoder) {
2893226633Sdim  Inst.addOperand(MCOperand::CreateImm(16 - Val));
2894226633Sdim  return MCDisassembler::Success;
2895226633Sdim}
2896226633Sdim
2897234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
2898226633Sdim                               uint64_t Address, const void *Decoder) {
2899226633Sdim  Inst.addOperand(MCOperand::CreateImm(32 - Val));
2900226633Sdim  return MCDisassembler::Success;
2901226633Sdim}
2902226633Sdim
2903234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
2904226633Sdim                               uint64_t Address, const void *Decoder) {
2905226633Sdim  Inst.addOperand(MCOperand::CreateImm(64 - Val));
2906226633Sdim  return MCDisassembler::Success;
2907226633Sdim}
2908226633Sdim
2909234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
2910226633Sdim                               uint64_t Address, const void *Decoder) {
2911226633Sdim  DecodeStatus S = MCDisassembler::Success;
2912226633Sdim
2913226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2914226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2915226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2916226633Sdim  Rn |= fieldFromInstruction32(Insn, 7, 1) << 4;
2917226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2918226633Sdim  Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
2919226633Sdim  unsigned op = fieldFromInstruction32(Insn, 6, 1);
2920226633Sdim
2921226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2922226633Sdim    return MCDisassembler::Fail;
2923226633Sdim  if (op) {
2924226633Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2925226633Sdim    return MCDisassembler::Fail; // Writeback
2926206124Srdivacky  }
2927226633Sdim
2928234353Sdim  switch (Inst.getOpcode()) {
2929234353Sdim  case ARM::VTBL2:
2930234353Sdim  case ARM::VTBX2:
2931234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
2932234353Sdim      return MCDisassembler::Fail;
2933234353Sdim    break;
2934234353Sdim  default:
2935234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
2936234353Sdim      return MCDisassembler::Fail;
2937226633Sdim  }
2938226633Sdim
2939226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
2940226633Sdim    return MCDisassembler::Fail;
2941226633Sdim
2942226633Sdim  return S;
2943206124Srdivacky}
2944206124Srdivacky
2945234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
2946226633Sdim                                     uint64_t Address, const void *Decoder) {
2947226633Sdim  DecodeStatus S = MCDisassembler::Success;
2948221345Sdim
2949226633Sdim  unsigned dst = fieldFromInstruction16(Insn, 8, 3);
2950226633Sdim  unsigned imm = fieldFromInstruction16(Insn, 0, 8);
2951221345Sdim
2952226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
2953226633Sdim    return MCDisassembler::Fail;
2954226633Sdim
2955226633Sdim  switch(Inst.getOpcode()) {
2956226633Sdim    default:
2957226633Sdim      return MCDisassembler::Fail;
2958226633Sdim    case ARM::tADR:
2959226633Sdim      break; // tADR does not explicitly represent the PC as an operand.
2960226633Sdim    case ARM::tADDrSPi:
2961226633Sdim      Inst.addOperand(MCOperand::CreateReg(ARM::SP));
2962226633Sdim      break;
2963221345Sdim  }
2964226633Sdim
2965226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
2966226633Sdim  return S;
2967221345Sdim}
2968221345Sdim
2969234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
2970226633Sdim                                 uint64_t Address, const void *Decoder) {
2971234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
2972234353Sdim                                true, 2, Inst, Decoder))
2973234353Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
2974226633Sdim  return MCDisassembler::Success;
2975226633Sdim}
2976206124Srdivacky
2977234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
2978226633Sdim                                 uint64_t Address, const void *Decoder) {
2979234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<22>(Val<<1) + 4,
2980234353Sdim                                true, 4, Inst, Decoder))
2981234353Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
2982226633Sdim  return MCDisassembler::Success;
2983226633Sdim}
2984206124Srdivacky
2985234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
2986226633Sdim                                 uint64_t Address, const void *Decoder) {
2987234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<7>(Val<<1) + 4,
2988234353Sdim                                true, 2, Inst, Decoder))
2989234353Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<7>(Val << 1)));
2990226633Sdim  return MCDisassembler::Success;
2991226633Sdim}
2992206124Srdivacky
2993234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
2994226633Sdim                                 uint64_t Address, const void *Decoder) {
2995226633Sdim  DecodeStatus S = MCDisassembler::Success;
2996206124Srdivacky
2997226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 0, 3);
2998226633Sdim  unsigned Rm = fieldFromInstruction32(Val, 3, 3);
2999226633Sdim
3000226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3001226633Sdim    return MCDisassembler::Fail;
3002226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
3003226633Sdim    return MCDisassembler::Fail;
3004226633Sdim
3005226633Sdim  return S;
3006226633Sdim}
3007226633Sdim
3008234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
3009226633Sdim                                  uint64_t Address, const void *Decoder) {
3010226633Sdim  DecodeStatus S = MCDisassembler::Success;
3011226633Sdim
3012226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 0, 3);
3013226633Sdim  unsigned imm = fieldFromInstruction32(Val, 3, 5);
3014226633Sdim
3015226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3016226633Sdim    return MCDisassembler::Fail;
3017226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3018226633Sdim
3019226633Sdim  return S;
3020226633Sdim}
3021226633Sdim
3022234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
3023226633Sdim                                  uint64_t Address, const void *Decoder) {
3024226633Sdim  unsigned imm = Val << 2;
3025226633Sdim
3026226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3027226633Sdim  tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
3028226633Sdim
3029226633Sdim  return MCDisassembler::Success;
3030226633Sdim}
3031226633Sdim
3032234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
3033226633Sdim                                  uint64_t Address, const void *Decoder) {
3034226633Sdim  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3035226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
3036226633Sdim
3037226633Sdim  return MCDisassembler::Success;
3038226633Sdim}
3039226633Sdim
3040234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
3041226633Sdim                                  uint64_t Address, const void *Decoder) {
3042226633Sdim  DecodeStatus S = MCDisassembler::Success;
3043226633Sdim
3044226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 6, 4);
3045226633Sdim  unsigned Rm = fieldFromInstruction32(Val, 2, 4);
3046226633Sdim  unsigned imm = fieldFromInstruction32(Val, 0, 2);
3047226633Sdim
3048226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3049226633Sdim    return MCDisassembler::Fail;
3050226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3051226633Sdim    return MCDisassembler::Fail;
3052226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3053226633Sdim
3054226633Sdim  return S;
3055226633Sdim}
3056226633Sdim
3057234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
3058226633Sdim                              uint64_t Address, const void *Decoder) {
3059226633Sdim  DecodeStatus S = MCDisassembler::Success;
3060226633Sdim
3061226633Sdim  switch (Inst.getOpcode()) {
3062226633Sdim    case ARM::t2PLDs:
3063226633Sdim    case ARM::t2PLDWs:
3064226633Sdim    case ARM::t2PLIs:
3065226633Sdim      break;
3066226633Sdim    default: {
3067226633Sdim      unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3068226633Sdim      if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3069226633Sdim    return MCDisassembler::Fail;
3070206124Srdivacky    }
3071226633Sdim  }
3072206124Srdivacky
3073226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3074226633Sdim  if (Rn == 0xF) {
3075226633Sdim    switch (Inst.getOpcode()) {
3076226633Sdim      case ARM::t2LDRBs:
3077226633Sdim        Inst.setOpcode(ARM::t2LDRBpci);
3078226633Sdim        break;
3079226633Sdim      case ARM::t2LDRHs:
3080226633Sdim        Inst.setOpcode(ARM::t2LDRHpci);
3081226633Sdim        break;
3082226633Sdim      case ARM::t2LDRSHs:
3083226633Sdim        Inst.setOpcode(ARM::t2LDRSHpci);
3084226633Sdim        break;
3085226633Sdim      case ARM::t2LDRSBs:
3086226633Sdim        Inst.setOpcode(ARM::t2LDRSBpci);
3087226633Sdim        break;
3088226633Sdim      case ARM::t2PLDs:
3089226633Sdim        Inst.setOpcode(ARM::t2PLDi12);
3090226633Sdim        Inst.addOperand(MCOperand::CreateReg(ARM::PC));
3091226633Sdim        break;
3092226633Sdim      default:
3093226633Sdim        return MCDisassembler::Fail;
3094206124Srdivacky    }
3095206124Srdivacky
3096226633Sdim    int imm = fieldFromInstruction32(Insn, 0, 12);
3097226633Sdim    if (!fieldFromInstruction32(Insn, 23, 1)) imm *= -1;
3098226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
3099221345Sdim
3100226633Sdim    return S;
3101226633Sdim  }
3102226633Sdim
3103226633Sdim  unsigned addrmode = fieldFromInstruction32(Insn, 4, 2);
3104226633Sdim  addrmode |= fieldFromInstruction32(Insn, 0, 4) << 2;
3105226633Sdim  addrmode |= fieldFromInstruction32(Insn, 16, 4) << 6;
3106226633Sdim  if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
3107226633Sdim    return MCDisassembler::Fail;
3108226633Sdim
3109226633Sdim  return S;
3110226633Sdim}
3111226633Sdim
3112234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
3113226633Sdim                           uint64_t Address, const void *Decoder) {
3114226633Sdim  int imm = Val & 0xFF;
3115226633Sdim  if (!(Val & 0x100)) imm *= -1;
3116226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm << 2));
3117226633Sdim
3118226633Sdim  return MCDisassembler::Success;
3119226633Sdim}
3120226633Sdim
3121234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
3122226633Sdim                                   uint64_t Address, const void *Decoder) {
3123226633Sdim  DecodeStatus S = MCDisassembler::Success;
3124226633Sdim
3125226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 9, 4);
3126226633Sdim  unsigned imm = fieldFromInstruction32(Val, 0, 9);
3127226633Sdim
3128226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3129226633Sdim    return MCDisassembler::Fail;
3130226633Sdim  if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
3131226633Sdim    return MCDisassembler::Fail;
3132226633Sdim
3133226633Sdim  return S;
3134226633Sdim}
3135226633Sdim
3136234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
3137226633Sdim                                   uint64_t Address, const void *Decoder) {
3138226633Sdim  DecodeStatus S = MCDisassembler::Success;
3139226633Sdim
3140226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 8, 4);
3141226633Sdim  unsigned imm = fieldFromInstruction32(Val, 0, 8);
3142226633Sdim
3143226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
3144226633Sdim    return MCDisassembler::Fail;
3145226633Sdim
3146226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3147226633Sdim
3148226633Sdim  return S;
3149226633Sdim}
3150226633Sdim
3151234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
3152226633Sdim                         uint64_t Address, const void *Decoder) {
3153226633Sdim  int imm = Val & 0xFF;
3154226633Sdim  if (Val == 0)
3155226633Sdim    imm = INT32_MIN;
3156226633Sdim  else if (!(Val & 0x100))
3157226633Sdim    imm *= -1;
3158226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3159226633Sdim
3160226633Sdim  return MCDisassembler::Success;
3161226633Sdim}
3162226633Sdim
3163226633Sdim
3164234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
3165226633Sdim                                 uint64_t Address, const void *Decoder) {
3166226633Sdim  DecodeStatus S = MCDisassembler::Success;
3167226633Sdim
3168226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 9, 4);
3169226633Sdim  unsigned imm = fieldFromInstruction32(Val, 0, 9);
3170226633Sdim
3171226633Sdim  // Some instructions always use an additive offset.
3172226633Sdim  switch (Inst.getOpcode()) {
3173226633Sdim    case ARM::t2LDRT:
3174226633Sdim    case ARM::t2LDRBT:
3175226633Sdim    case ARM::t2LDRHT:
3176226633Sdim    case ARM::t2LDRSBT:
3177226633Sdim    case ARM::t2LDRSHT:
3178226633Sdim    case ARM::t2STRT:
3179226633Sdim    case ARM::t2STRBT:
3180226633Sdim    case ARM::t2STRHT:
3181226633Sdim      imm |= 0x100;
3182226633Sdim      break;
3183226633Sdim    default:
3184226633Sdim      break;
3185226633Sdim  }
3186226633Sdim
3187226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3188226633Sdim    return MCDisassembler::Fail;
3189226633Sdim  if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
3190226633Sdim    return MCDisassembler::Fail;
3191226633Sdim
3192226633Sdim  return S;
3193226633Sdim}
3194226633Sdim
3195234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
3196226633Sdim                                    uint64_t Address, const void *Decoder) {
3197226633Sdim  DecodeStatus S = MCDisassembler::Success;
3198226633Sdim
3199226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3200226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3201226633Sdim  unsigned addr = fieldFromInstruction32(Insn, 0, 8);
3202226633Sdim  addr |= fieldFromInstruction32(Insn, 9, 1) << 8;
3203226633Sdim  addr |= Rn << 9;
3204226633Sdim  unsigned load = fieldFromInstruction32(Insn, 20, 1);
3205226633Sdim
3206226633Sdim  if (!load) {
3207226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3208226633Sdim      return MCDisassembler::Fail;
3209226633Sdim  }
3210226633Sdim
3211226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3212226633Sdim    return MCDisassembler::Fail;
3213226633Sdim
3214226633Sdim  if (load) {
3215226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3216226633Sdim      return MCDisassembler::Fail;
3217226633Sdim  }
3218226633Sdim
3219226633Sdim  if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
3220226633Sdim    return MCDisassembler::Fail;
3221226633Sdim
3222226633Sdim  return S;
3223226633Sdim}
3224226633Sdim
3225234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
3226226633Sdim                                  uint64_t Address, const void *Decoder) {
3227226633Sdim  DecodeStatus S = MCDisassembler::Success;
3228226633Sdim
3229226633Sdim  unsigned Rn = fieldFromInstruction32(Val, 13, 4);
3230226633Sdim  unsigned imm = fieldFromInstruction32(Val, 0, 12);
3231226633Sdim
3232226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3233226633Sdim    return MCDisassembler::Fail;
3234226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3235226633Sdim
3236226633Sdim  return S;
3237226633Sdim}
3238226633Sdim
3239226633Sdim
3240234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
3241226633Sdim                                uint64_t Address, const void *Decoder) {
3242226633Sdim  unsigned imm = fieldFromInstruction16(Insn, 0, 7);
3243226633Sdim
3244226633Sdim  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3245226633Sdim  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3246226633Sdim  Inst.addOperand(MCOperand::CreateImm(imm));
3247226633Sdim
3248226633Sdim  return MCDisassembler::Success;
3249226633Sdim}
3250226633Sdim
3251234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
3252226633Sdim                                uint64_t Address, const void *Decoder) {
3253226633Sdim  DecodeStatus S = MCDisassembler::Success;
3254226633Sdim
3255226633Sdim  if (Inst.getOpcode() == ARM::tADDrSP) {
3256226633Sdim    unsigned Rdm = fieldFromInstruction16(Insn, 0, 3);
3257226633Sdim    Rdm |= fieldFromInstruction16(Insn, 7, 1) << 3;
3258226633Sdim
3259226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3260226633Sdim    return MCDisassembler::Fail;
3261226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3262226633Sdim    return MCDisassembler::Fail;
3263226633Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3264226633Sdim  } else if (Inst.getOpcode() == ARM::tADDspr) {
3265226633Sdim    unsigned Rm = fieldFromInstruction16(Insn, 3, 4);
3266226633Sdim
3267226633Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3268226633Sdim    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3269226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3270226633Sdim    return MCDisassembler::Fail;
3271226633Sdim  }
3272226633Sdim
3273226633Sdim  return S;
3274226633Sdim}
3275226633Sdim
3276234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
3277226633Sdim                           uint64_t Address, const void *Decoder) {
3278226633Sdim  unsigned imod = fieldFromInstruction16(Insn, 4, 1) | 0x2;
3279226633Sdim  unsigned flags = fieldFromInstruction16(Insn, 0, 3);
3280226633Sdim
3281226633Sdim  Inst.addOperand(MCOperand::CreateImm(imod));
3282226633Sdim  Inst.addOperand(MCOperand::CreateImm(flags));
3283226633Sdim
3284226633Sdim  return MCDisassembler::Success;
3285226633Sdim}
3286226633Sdim
3287234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
3288226633Sdim                             uint64_t Address, const void *Decoder) {
3289226633Sdim  DecodeStatus S = MCDisassembler::Success;
3290226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3291226633Sdim  unsigned add = fieldFromInstruction32(Insn, 4, 1);
3292226633Sdim
3293234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
3294226633Sdim    return MCDisassembler::Fail;
3295226633Sdim  Inst.addOperand(MCOperand::CreateImm(add));
3296226633Sdim
3297226633Sdim  return S;
3298226633Sdim}
3299226633Sdim
3300234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
3301226633Sdim                                 uint64_t Address, const void *Decoder) {
3302234353Sdim  if (!tryAddingSymbolicOperand(Address,
3303226633Sdim                                (Address & ~2u) + SignExtend32<22>(Val << 1) + 4,
3304226633Sdim                                true, 4, Inst, Decoder))
3305226633Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
3306226633Sdim  return MCDisassembler::Success;
3307226633Sdim}
3308226633Sdim
3309234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
3310226633Sdim                              uint64_t Address, const void *Decoder) {
3311226633Sdim  if (Val == 0xA || Val == 0xB)
3312226633Sdim    return MCDisassembler::Fail;
3313226633Sdim
3314226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
3315226633Sdim  return MCDisassembler::Success;
3316226633Sdim}
3317226633Sdim
3318226633Sdimstatic DecodeStatus
3319234353SdimDecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
3320226633Sdim                       uint64_t Address, const void *Decoder) {
3321226633Sdim  DecodeStatus S = MCDisassembler::Success;
3322226633Sdim
3323226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3324226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3325226633Sdim
3326226633Sdim  if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
3327226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3328226633Sdim    return MCDisassembler::Fail;
3329226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3330226633Sdim    return MCDisassembler::Fail;
3331226633Sdim  return S;
3332226633Sdim}
3333226633Sdim
3334226633Sdimstatic DecodeStatus
3335234353SdimDecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
3336226633Sdim                           uint64_t Address, const void *Decoder) {
3337226633Sdim  DecodeStatus S = MCDisassembler::Success;
3338226633Sdim
3339226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 22, 4);
3340226633Sdim  if (pred == 0xE || pred == 0xF) {
3341226633Sdim    unsigned opc = fieldFromInstruction32(Insn, 4, 28);
3342226633Sdim    switch (opc) {
3343226633Sdim      default:
3344226633Sdim        return MCDisassembler::Fail;
3345226633Sdim      case 0xf3bf8f4:
3346226633Sdim        Inst.setOpcode(ARM::t2DSB);
3347226633Sdim        break;
3348226633Sdim      case 0xf3bf8f5:
3349226633Sdim        Inst.setOpcode(ARM::t2DMB);
3350226633Sdim        break;
3351226633Sdim      case 0xf3bf8f6:
3352226633Sdim        Inst.setOpcode(ARM::t2ISB);
3353226633Sdim        break;
3354221345Sdim    }
3355206124Srdivacky
3356226633Sdim    unsigned imm = fieldFromInstruction32(Insn, 0, 4);
3357226633Sdim    return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
3358226633Sdim  }
3359226633Sdim
3360226633Sdim  unsigned brtarget = fieldFromInstruction32(Insn, 0, 11) << 1;
3361226633Sdim  brtarget |= fieldFromInstruction32(Insn, 11, 1) << 19;
3362226633Sdim  brtarget |= fieldFromInstruction32(Insn, 13, 1) << 18;
3363226633Sdim  brtarget |= fieldFromInstruction32(Insn, 16, 6) << 12;
3364226633Sdim  brtarget |= fieldFromInstruction32(Insn, 26, 1) << 20;
3365226633Sdim
3366226633Sdim  if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
3367226633Sdim    return MCDisassembler::Fail;
3368226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3369226633Sdim    return MCDisassembler::Fail;
3370226633Sdim
3371226633Sdim  return S;
3372226633Sdim}
3373226633Sdim
3374226633Sdim// Decode a shifted immediate operand.  These basically consist
3375226633Sdim// of an 8-bit value, and a 4-bit directive that specifies either
3376226633Sdim// a splat operation or a rotation.
3377234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
3378226633Sdim                          uint64_t Address, const void *Decoder) {
3379226633Sdim  unsigned ctrl = fieldFromInstruction32(Val, 10, 2);
3380226633Sdim  if (ctrl == 0) {
3381226633Sdim    unsigned byte = fieldFromInstruction32(Val, 8, 2);
3382226633Sdim    unsigned imm = fieldFromInstruction32(Val, 0, 8);
3383226633Sdim    switch (byte) {
3384226633Sdim      case 0:
3385226633Sdim        Inst.addOperand(MCOperand::CreateImm(imm));
3386226633Sdim        break;
3387226633Sdim      case 1:
3388226633Sdim        Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm));
3389226633Sdim        break;
3390226633Sdim      case 2:
3391226633Sdim        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8)));
3392226633Sdim        break;
3393226633Sdim      case 3:
3394226633Sdim        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) |
3395226633Sdim                                             (imm << 8)  |  imm));
3396226633Sdim        break;
3397221345Sdim    }
3398226633Sdim  } else {
3399226633Sdim    unsigned unrot = fieldFromInstruction32(Val, 0, 7) | 0x80;
3400226633Sdim    unsigned rot = fieldFromInstruction32(Val, 7, 5);
3401226633Sdim    unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
3402226633Sdim    Inst.addOperand(MCOperand::CreateImm(imm));
3403226633Sdim  }
3404221345Sdim
3405226633Sdim  return MCDisassembler::Success;
3406226633Sdim}
3407206124Srdivacky
3408226633Sdimstatic DecodeStatus
3409234353SdimDecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
3410226633Sdim                            uint64_t Address, const void *Decoder){
3411234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<8>(Val<<1) + 4,
3412234353Sdim                                true, 2, Inst, Decoder))
3413234353Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<8>(Val << 1)));
3414226633Sdim  return MCDisassembler::Success;
3415226633Sdim}
3416226633Sdim
3417234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
3418226633Sdim                                       uint64_t Address, const void *Decoder){
3419234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<22>(Val<<1) + 4,
3420234353Sdim                                true, 4, Inst, Decoder))
3421234353Sdim    Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
3422226633Sdim  return MCDisassembler::Success;
3423226633Sdim}
3424226633Sdim
3425234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
3426226633Sdim                                   uint64_t Address, const void *Decoder) {
3427226633Sdim  switch (Val) {
3428226633Sdim  default:
3429226633Sdim    return MCDisassembler::Fail;
3430226633Sdim  case 0xF: // SY
3431226633Sdim  case 0xE: // ST
3432226633Sdim  case 0xB: // ISH
3433226633Sdim  case 0xA: // ISHST
3434226633Sdim  case 0x7: // NSH
3435226633Sdim  case 0x6: // NSHST
3436226633Sdim  case 0x3: // OSH
3437226633Sdim  case 0x2: // OSHST
3438226633Sdim    break;
3439206124Srdivacky  }
3440206124Srdivacky
3441226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
3442226633Sdim  return MCDisassembler::Success;
3443206124Srdivacky}
3444206124Srdivacky
3445234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
3446226633Sdim                          uint64_t Address, const void *Decoder) {
3447226633Sdim  if (!Val) return MCDisassembler::Fail;
3448226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
3449226633Sdim  return MCDisassembler::Success;
3450226633Sdim}
3451206124Srdivacky
3452234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
3453226633Sdim                                        uint64_t Address, const void *Decoder) {
3454226633Sdim  DecodeStatus S = MCDisassembler::Success;
3455206124Srdivacky
3456226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3457226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3458226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3459206124Srdivacky
3460226633Sdim  if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail;
3461206274Srdivacky
3462226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3463226633Sdim    return MCDisassembler::Fail;
3464226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
3465226633Sdim    return MCDisassembler::Fail;
3466226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3467226633Sdim    return MCDisassembler::Fail;
3468226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3469226633Sdim    return MCDisassembler::Fail;
3470206124Srdivacky
3471226633Sdim  return S;
3472226633Sdim}
3473206124Srdivacky
3474206124Srdivacky
3475234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
3476226633Sdim                                         uint64_t Address, const void *Decoder){
3477226633Sdim  DecodeStatus S = MCDisassembler::Success;
3478221345Sdim
3479226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3480226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 0, 4);
3481226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3482226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3483206124Srdivacky
3484226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
3485226633Sdim    return MCDisassembler::Fail;
3486226633Sdim
3487226633Sdim  if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail;
3488226633Sdim  if (Rd == Rn || Rd == Rt || Rd == Rt+1) return MCDisassembler::Fail;
3489226633Sdim
3490226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3491226633Sdim    return MCDisassembler::Fail;
3492226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
3493226633Sdim    return MCDisassembler::Fail;
3494226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3495226633Sdim    return MCDisassembler::Fail;
3496226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3497226633Sdim    return MCDisassembler::Fail;
3498226633Sdim
3499226633Sdim  return S;
3500206124Srdivacky}
3501206124Srdivacky
3502234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
3503226633Sdim                            uint64_t Address, const void *Decoder) {
3504226633Sdim  DecodeStatus S = MCDisassembler::Success;
3505206274Srdivacky
3506226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3507226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3508226633Sdim  unsigned imm = fieldFromInstruction32(Insn, 0, 12);
3509226633Sdim  imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
3510226633Sdim  imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
3511226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3512206124Srdivacky
3513226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
3514206124Srdivacky
3515226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3516226633Sdim    return MCDisassembler::Fail;
3517226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3518226633Sdim    return MCDisassembler::Fail;
3519226633Sdim  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
3520226633Sdim    return MCDisassembler::Fail;
3521226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3522226633Sdim    return MCDisassembler::Fail;
3523206124Srdivacky
3524226633Sdim  return S;
3525226633Sdim}
3526206124Srdivacky
3527234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
3528226633Sdim                            uint64_t Address, const void *Decoder) {
3529226633Sdim  DecodeStatus S = MCDisassembler::Success;
3530226633Sdim
3531226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3532226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3533226633Sdim  unsigned imm = fieldFromInstruction32(Insn, 0, 12);
3534226633Sdim  imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
3535226633Sdim  imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
3536226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3537226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3538226633Sdim
3539226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
3540226633Sdim  if (Rm == 0xF) S = MCDisassembler::SoftFail;
3541226633Sdim
3542226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3543226633Sdim    return MCDisassembler::Fail;
3544226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3545226633Sdim    return MCDisassembler::Fail;
3546226633Sdim  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
3547226633Sdim    return MCDisassembler::Fail;
3548226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3549226633Sdim    return MCDisassembler::Fail;
3550226633Sdim
3551226633Sdim  return S;
3552226633Sdim}
3553226633Sdim
3554226633Sdim
3555234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
3556226633Sdim                            uint64_t Address, const void *Decoder) {
3557226633Sdim  DecodeStatus S = MCDisassembler::Success;
3558226633Sdim
3559226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3560226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3561226633Sdim  unsigned imm = fieldFromInstruction32(Insn, 0, 12);
3562226633Sdim  imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
3563226633Sdim  imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
3564226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3565226633Sdim
3566226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
3567226633Sdim
3568226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3569226633Sdim    return MCDisassembler::Fail;
3570226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3571226633Sdim    return MCDisassembler::Fail;
3572226633Sdim  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
3573226633Sdim    return MCDisassembler::Fail;
3574226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3575226633Sdim    return MCDisassembler::Fail;
3576226633Sdim
3577226633Sdim  return S;
3578226633Sdim}
3579226633Sdim
3580234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
3581226633Sdim                            uint64_t Address, const void *Decoder) {
3582226633Sdim  DecodeStatus S = MCDisassembler::Success;
3583226633Sdim
3584226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3585226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3586226633Sdim  unsigned imm = fieldFromInstruction32(Insn, 0, 12);
3587226633Sdim  imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
3588226633Sdim  imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
3589226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3590226633Sdim
3591226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
3592226633Sdim
3593226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3594226633Sdim    return MCDisassembler::Fail;
3595226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3596226633Sdim    return MCDisassembler::Fail;
3597226633Sdim  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
3598226633Sdim    return MCDisassembler::Fail;
3599226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3600226633Sdim    return MCDisassembler::Fail;
3601226633Sdim
3602226633Sdim  return S;
3603226633Sdim}
3604226633Sdim
3605234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
3606226633Sdim                         uint64_t Address, const void *Decoder) {
3607226633Sdim  DecodeStatus S = MCDisassembler::Success;
3608226633Sdim
3609226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3610226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3611226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3612226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3613226633Sdim  unsigned size = fieldFromInstruction32(Insn, 10, 2);
3614226633Sdim
3615226633Sdim  unsigned align = 0;
3616226633Sdim  unsigned index = 0;
3617226633Sdim  switch (size) {
3618226633Sdim    default:
3619226633Sdim      return MCDisassembler::Fail;
3620226633Sdim    case 0:
3621226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3622226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3623226633Sdim      index = fieldFromInstruction32(Insn, 5, 3);
3624226633Sdim      break;
3625226633Sdim    case 1:
3626226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
3627226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3628226633Sdim      index = fieldFromInstruction32(Insn, 6, 2);
3629226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3630226633Sdim        align = 2;
3631226633Sdim      break;
3632226633Sdim    case 2:
3633226633Sdim      if (fieldFromInstruction32(Insn, 6, 1))
3634226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3635226633Sdim      index = fieldFromInstruction32(Insn, 7, 1);
3636226633Sdim      if (fieldFromInstruction32(Insn, 4, 2) != 0)
3637226633Sdim        align = 4;
3638206124Srdivacky  }
3639206124Srdivacky
3640226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3641226633Sdim    return MCDisassembler::Fail;
3642226633Sdim  if (Rm != 0xF) { // Writeback
3643226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3644226633Sdim      return MCDisassembler::Fail;
3645226633Sdim  }
3646226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3647226633Sdim    return MCDisassembler::Fail;
3648226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3649226633Sdim  if (Rm != 0xF) {
3650226633Sdim    if (Rm != 0xD) {
3651226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3652226633Sdim        return MCDisassembler::Fail;
3653226633Sdim    } else
3654226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3655226633Sdim  }
3656206124Srdivacky
3657226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3658226633Sdim    return MCDisassembler::Fail;
3659226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3660206124Srdivacky
3661226633Sdim  return S;
3662226633Sdim}
3663206124Srdivacky
3664234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
3665226633Sdim                         uint64_t Address, const void *Decoder) {
3666226633Sdim  DecodeStatus S = MCDisassembler::Success;
3667206124Srdivacky
3668226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3669226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3670226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3671226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3672226633Sdim  unsigned size = fieldFromInstruction32(Insn, 10, 2);
3673207618Srdivacky
3674226633Sdim  unsigned align = 0;
3675226633Sdim  unsigned index = 0;
3676226633Sdim  switch (size) {
3677226633Sdim    default:
3678226633Sdim      return MCDisassembler::Fail;
3679226633Sdim    case 0:
3680226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3681226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3682226633Sdim      index = fieldFromInstruction32(Insn, 5, 3);
3683226633Sdim      break;
3684226633Sdim    case 1:
3685226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
3686226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3687226633Sdim      index = fieldFromInstruction32(Insn, 6, 2);
3688226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3689226633Sdim        align = 2;
3690226633Sdim      break;
3691226633Sdim    case 2:
3692226633Sdim      if (fieldFromInstruction32(Insn, 6, 1))
3693226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3694226633Sdim      index = fieldFromInstruction32(Insn, 7, 1);
3695226633Sdim      if (fieldFromInstruction32(Insn, 4, 2) != 0)
3696226633Sdim        align = 4;
3697226633Sdim  }
3698221345Sdim
3699226633Sdim  if (Rm != 0xF) { // Writeback
3700226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3701226633Sdim    return MCDisassembler::Fail;
3702226633Sdim  }
3703226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3704226633Sdim    return MCDisassembler::Fail;
3705226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3706226633Sdim  if (Rm != 0xF) {
3707226633Sdim    if (Rm != 0xD) {
3708226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3709226633Sdim    return MCDisassembler::Fail;
3710226633Sdim    } else
3711226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3712226633Sdim  }
3713206124Srdivacky
3714226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3715226633Sdim    return MCDisassembler::Fail;
3716226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3717226633Sdim
3718226633Sdim  return S;
3719206124Srdivacky}
3720206124Srdivacky
3721226633Sdim
3722234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
3723226633Sdim                         uint64_t Address, const void *Decoder) {
3724226633Sdim  DecodeStatus S = MCDisassembler::Success;
3725226633Sdim
3726226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3727226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3728226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3729226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3730226633Sdim  unsigned size = fieldFromInstruction32(Insn, 10, 2);
3731226633Sdim
3732226633Sdim  unsigned align = 0;
3733226633Sdim  unsigned index = 0;
3734226633Sdim  unsigned inc = 1;
3735226633Sdim  switch (size) {
3736226633Sdim    default:
3737226633Sdim      return MCDisassembler::Fail;
3738226633Sdim    case 0:
3739226633Sdim      index = fieldFromInstruction32(Insn, 5, 3);
3740226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3741226633Sdim        align = 2;
3742226633Sdim      break;
3743226633Sdim    case 1:
3744226633Sdim      index = fieldFromInstruction32(Insn, 6, 2);
3745226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3746226633Sdim        align = 4;
3747226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
3748226633Sdim        inc = 2;
3749226633Sdim      break;
3750226633Sdim    case 2:
3751226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
3752226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3753226633Sdim      index = fieldFromInstruction32(Insn, 7, 1);
3754226633Sdim      if (fieldFromInstruction32(Insn, 4, 1) != 0)
3755226633Sdim        align = 8;
3756226633Sdim      if (fieldFromInstruction32(Insn, 6, 1))
3757226633Sdim        inc = 2;
3758226633Sdim      break;
3759207618Srdivacky  }
3760226633Sdim
3761226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3762226633Sdim    return MCDisassembler::Fail;
3763226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3764226633Sdim    return MCDisassembler::Fail;
3765226633Sdim  if (Rm != 0xF) { // Writeback
3766226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3767226633Sdim      return MCDisassembler::Fail;
3768226633Sdim  }
3769226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3770226633Sdim    return MCDisassembler::Fail;
3771226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3772226633Sdim  if (Rm != 0xF) {
3773226633Sdim    if (Rm != 0xD) {
3774226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3775226633Sdim        return MCDisassembler::Fail;
3776226633Sdim    } else
3777226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3778226633Sdim  }
3779226633Sdim
3780226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3781226633Sdim    return MCDisassembler::Fail;
3782226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3783226633Sdim    return MCDisassembler::Fail;
3784226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3785226633Sdim
3786226633Sdim  return S;
3787206124Srdivacky}
3788206124Srdivacky
3789234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
3790226633Sdim                         uint64_t Address, const void *Decoder) {
3791226633Sdim  DecodeStatus S = MCDisassembler::Success;
3792207618Srdivacky
3793226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3794226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3795226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3796226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3797226633Sdim  unsigned size = fieldFromInstruction32(Insn, 10, 2);
3798226633Sdim
3799226633Sdim  unsigned align = 0;
3800226633Sdim  unsigned index = 0;
3801226633Sdim  unsigned inc = 1;
3802226633Sdim  switch (size) {
3803226633Sdim    default:
3804226633Sdim      return MCDisassembler::Fail;
3805226633Sdim    case 0:
3806226633Sdim      index = fieldFromInstruction32(Insn, 5, 3);
3807226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3808226633Sdim        align = 2;
3809226633Sdim      break;
3810226633Sdim    case 1:
3811226633Sdim      index = fieldFromInstruction32(Insn, 6, 2);
3812226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3813226633Sdim        align = 4;
3814226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
3815226633Sdim        inc = 2;
3816226633Sdim      break;
3817226633Sdim    case 2:
3818226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
3819226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3820226633Sdim      index = fieldFromInstruction32(Insn, 7, 1);
3821226633Sdim      if (fieldFromInstruction32(Insn, 4, 1) != 0)
3822226633Sdim        align = 8;
3823226633Sdim      if (fieldFromInstruction32(Insn, 6, 1))
3824226633Sdim        inc = 2;
3825226633Sdim      break;
3826207618Srdivacky  }
3827226633Sdim
3828226633Sdim  if (Rm != 0xF) { // Writeback
3829226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3830226633Sdim      return MCDisassembler::Fail;
3831207618Srdivacky  }
3832226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3833226633Sdim    return MCDisassembler::Fail;
3834226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3835226633Sdim  if (Rm != 0xF) {
3836226633Sdim    if (Rm != 0xD) {
3837226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3838226633Sdim        return MCDisassembler::Fail;
3839226633Sdim    } else
3840226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3841226633Sdim  }
3842207618Srdivacky
3843226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3844226633Sdim    return MCDisassembler::Fail;
3845226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3846226633Sdim    return MCDisassembler::Fail;
3847226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3848207618Srdivacky
3849226633Sdim  return S;
3850206124Srdivacky}
3851206124Srdivacky
3852226633Sdim
3853234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
3854226633Sdim                         uint64_t Address, const void *Decoder) {
3855226633Sdim  DecodeStatus S = MCDisassembler::Success;
3856226633Sdim
3857226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3858226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3859226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3860226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3861226633Sdim  unsigned size = fieldFromInstruction32(Insn, 10, 2);
3862226633Sdim
3863226633Sdim  unsigned align = 0;
3864226633Sdim  unsigned index = 0;
3865226633Sdim  unsigned inc = 1;
3866226633Sdim  switch (size) {
3867226633Sdim    default:
3868226633Sdim      return MCDisassembler::Fail;
3869226633Sdim    case 0:
3870226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3871226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3872226633Sdim      index = fieldFromInstruction32(Insn, 5, 3);
3873226633Sdim      break;
3874226633Sdim    case 1:
3875226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3876226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3877226633Sdim      index = fieldFromInstruction32(Insn, 6, 2);
3878226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
3879226633Sdim        inc = 2;
3880226633Sdim      break;
3881226633Sdim    case 2:
3882226633Sdim      if (fieldFromInstruction32(Insn, 4, 2))
3883226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3884226633Sdim      index = fieldFromInstruction32(Insn, 7, 1);
3885226633Sdim      if (fieldFromInstruction32(Insn, 6, 1))
3886226633Sdim        inc = 2;
3887226633Sdim      break;
3888206124Srdivacky  }
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  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
3895226633Sdim    return MCDisassembler::Fail;
3896226633Sdim
3897226633Sdim  if (Rm != 0xF) { // Writeback
3898226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3899226633Sdim    return MCDisassembler::Fail;
3900226633Sdim  }
3901226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3902226633Sdim    return MCDisassembler::Fail;
3903226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3904226633Sdim  if (Rm != 0xF) {
3905226633Sdim    if (Rm != 0xD) {
3906226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3907226633Sdim    return MCDisassembler::Fail;
3908226633Sdim    } else
3909226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3910226633Sdim  }
3911226633Sdim
3912226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3913226633Sdim    return MCDisassembler::Fail;
3914226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3915226633Sdim    return MCDisassembler::Fail;
3916226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
3917226633Sdim    return MCDisassembler::Fail;
3918226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3919226633Sdim
3920226633Sdim  return S;
3921206124Srdivacky}
3922206124Srdivacky
3923234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
3924226633Sdim                         uint64_t Address, const void *Decoder) {
3925226633Sdim  DecodeStatus S = MCDisassembler::Success;
3926226633Sdim
3927226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3928226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3929226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3930226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3931226633Sdim  unsigned size = fieldFromInstruction32(Insn, 10, 2);
3932226633Sdim
3933226633Sdim  unsigned align = 0;
3934226633Sdim  unsigned index = 0;
3935226633Sdim  unsigned inc = 1;
3936226633Sdim  switch (size) {
3937226633Sdim    default:
3938226633Sdim      return MCDisassembler::Fail;
3939226633Sdim    case 0:
3940226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3941226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3942226633Sdim      index = fieldFromInstruction32(Insn, 5, 3);
3943226633Sdim      break;
3944226633Sdim    case 1:
3945226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
3946226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3947226633Sdim      index = fieldFromInstruction32(Insn, 6, 2);
3948226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
3949226633Sdim        inc = 2;
3950226633Sdim      break;
3951226633Sdim    case 2:
3952226633Sdim      if (fieldFromInstruction32(Insn, 4, 2))
3953226633Sdim        return MCDisassembler::Fail; // UNDEFINED
3954226633Sdim      index = fieldFromInstruction32(Insn, 7, 1);
3955226633Sdim      if (fieldFromInstruction32(Insn, 6, 1))
3956226633Sdim        inc = 2;
3957226633Sdim      break;
3958226633Sdim  }
3959226633Sdim
3960226633Sdim  if (Rm != 0xF) { // Writeback
3961226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3962226633Sdim    return MCDisassembler::Fail;
3963226633Sdim  }
3964226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3965226633Sdim    return MCDisassembler::Fail;
3966226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
3967226633Sdim  if (Rm != 0xF) {
3968226633Sdim    if (Rm != 0xD) {
3969226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3970226633Sdim    return MCDisassembler::Fail;
3971226633Sdim    } else
3972226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
3973226633Sdim  }
3974226633Sdim
3975226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3976226633Sdim    return MCDisassembler::Fail;
3977226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3978226633Sdim    return MCDisassembler::Fail;
3979226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
3980226633Sdim    return MCDisassembler::Fail;
3981226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
3982226633Sdim
3983226633Sdim  return S;
3984206124Srdivacky}
3985206124Srdivacky
3986226633Sdim
3987234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
3988226633Sdim                         uint64_t Address, const void *Decoder) {
3989226633Sdim  DecodeStatus S = MCDisassembler::Success;
3990226633Sdim
3991226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3992226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3993226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3994226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3995226633Sdim  unsigned size = fieldFromInstruction32(Insn, 10, 2);
3996226633Sdim
3997226633Sdim  unsigned align = 0;
3998226633Sdim  unsigned index = 0;
3999226633Sdim  unsigned inc = 1;
4000226633Sdim  switch (size) {
4001226633Sdim    default:
4002226633Sdim      return MCDisassembler::Fail;
4003226633Sdim    case 0:
4004226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
4005226633Sdim        align = 4;
4006226633Sdim      index = fieldFromInstruction32(Insn, 5, 3);
4007226633Sdim      break;
4008226633Sdim    case 1:
4009226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
4010226633Sdim        align = 8;
4011226633Sdim      index = fieldFromInstruction32(Insn, 6, 2);
4012226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
4013226633Sdim        inc = 2;
4014226633Sdim      break;
4015226633Sdim    case 2:
4016226633Sdim      if (fieldFromInstruction32(Insn, 4, 2))
4017226633Sdim        align = 4 << fieldFromInstruction32(Insn, 4, 2);
4018226633Sdim      index = fieldFromInstruction32(Insn, 7, 1);
4019226633Sdim      if (fieldFromInstruction32(Insn, 6, 1))
4020226633Sdim        inc = 2;
4021226633Sdim      break;
4022226633Sdim  }
4023226633Sdim
4024226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4025226633Sdim    return MCDisassembler::Fail;
4026226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4027226633Sdim    return MCDisassembler::Fail;
4028226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4029226633Sdim    return MCDisassembler::Fail;
4030226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4031226633Sdim    return MCDisassembler::Fail;
4032226633Sdim
4033226633Sdim  if (Rm != 0xF) { // Writeback
4034226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4035226633Sdim      return MCDisassembler::Fail;
4036226633Sdim  }
4037226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4038226633Sdim    return MCDisassembler::Fail;
4039226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
4040226633Sdim  if (Rm != 0xF) {
4041226633Sdim    if (Rm != 0xD) {
4042226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4043226633Sdim        return MCDisassembler::Fail;
4044226633Sdim    } else
4045226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
4046226633Sdim  }
4047226633Sdim
4048226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4049226633Sdim    return MCDisassembler::Fail;
4050226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4051226633Sdim    return MCDisassembler::Fail;
4052226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4053226633Sdim    return MCDisassembler::Fail;
4054226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4055226633Sdim    return MCDisassembler::Fail;
4056226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
4057226633Sdim
4058226633Sdim  return S;
4059206124Srdivacky}
4060206124Srdivacky
4061234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
4062226633Sdim                         uint64_t Address, const void *Decoder) {
4063226633Sdim  DecodeStatus S = MCDisassembler::Success;
4064226633Sdim
4065226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
4066226633Sdim  unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
4067226633Sdim  unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
4068226633Sdim  Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
4069226633Sdim  unsigned size = fieldFromInstruction32(Insn, 10, 2);
4070226633Sdim
4071226633Sdim  unsigned align = 0;
4072226633Sdim  unsigned index = 0;
4073226633Sdim  unsigned inc = 1;
4074226633Sdim  switch (size) {
4075226633Sdim    default:
4076226633Sdim      return MCDisassembler::Fail;
4077226633Sdim    case 0:
4078226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
4079226633Sdim        align = 4;
4080226633Sdim      index = fieldFromInstruction32(Insn, 5, 3);
4081226633Sdim      break;
4082226633Sdim    case 1:
4083226633Sdim      if (fieldFromInstruction32(Insn, 4, 1))
4084226633Sdim        align = 8;
4085226633Sdim      index = fieldFromInstruction32(Insn, 6, 2);
4086226633Sdim      if (fieldFromInstruction32(Insn, 5, 1))
4087226633Sdim        inc = 2;
4088226633Sdim      break;
4089226633Sdim    case 2:
4090226633Sdim      if (fieldFromInstruction32(Insn, 4, 2))
4091226633Sdim        align = 4 << fieldFromInstruction32(Insn, 4, 2);
4092226633Sdim      index = fieldFromInstruction32(Insn, 7, 1);
4093226633Sdim      if (fieldFromInstruction32(Insn, 6, 1))
4094226633Sdim        inc = 2;
4095226633Sdim      break;
4096226633Sdim  }
4097226633Sdim
4098226633Sdim  if (Rm != 0xF) { // Writeback
4099226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4100226633Sdim    return MCDisassembler::Fail;
4101226633Sdim  }
4102226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4103226633Sdim    return MCDisassembler::Fail;
4104226633Sdim  Inst.addOperand(MCOperand::CreateImm(align));
4105226633Sdim  if (Rm != 0xF) {
4106226633Sdim    if (Rm != 0xD) {
4107226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4108226633Sdim    return MCDisassembler::Fail;
4109226633Sdim    } else
4110226633Sdim      Inst.addOperand(MCOperand::CreateReg(0));
4111226633Sdim  }
4112226633Sdim
4113226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4114226633Sdim    return MCDisassembler::Fail;
4115226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4116226633Sdim    return MCDisassembler::Fail;
4117226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4118226633Sdim    return MCDisassembler::Fail;
4119226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4120226633Sdim    return MCDisassembler::Fail;
4121226633Sdim  Inst.addOperand(MCOperand::CreateImm(index));
4122226633Sdim
4123226633Sdim  return S;
4124206124Srdivacky}
4125206124Srdivacky
4126234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
4127226633Sdim                                  uint64_t Address, const void *Decoder) {
4128226633Sdim  DecodeStatus S = MCDisassembler::Success;
4129226633Sdim  unsigned Rt  = fieldFromInstruction32(Insn, 12, 4);
4130226633Sdim  unsigned Rt2 = fieldFromInstruction32(Insn, 16, 4);
4131226633Sdim  unsigned Rm  = fieldFromInstruction32(Insn,  0, 4);
4132226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
4133226633Sdim  Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
4134226633Sdim
4135226633Sdim  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4136226633Sdim    S = MCDisassembler::SoftFail;
4137226633Sdim
4138226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4139226633Sdim    return MCDisassembler::Fail;
4140226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4141226633Sdim    return MCDisassembler::Fail;
4142226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4143226633Sdim    return MCDisassembler::Fail;
4144226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4145226633Sdim    return MCDisassembler::Fail;
4146226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4147226633Sdim    return MCDisassembler::Fail;
4148226633Sdim
4149226633Sdim  return S;
4150207618Srdivacky}
4151207618Srdivacky
4152234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
4153226633Sdim                                  uint64_t Address, const void *Decoder) {
4154226633Sdim  DecodeStatus S = MCDisassembler::Success;
4155226633Sdim  unsigned Rt  = fieldFromInstruction32(Insn, 12, 4);
4156226633Sdim  unsigned Rt2 = fieldFromInstruction32(Insn, 16, 4);
4157226633Sdim  unsigned Rm  = fieldFromInstruction32(Insn,  0, 4);
4158226633Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
4159226633Sdim  Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
4160226633Sdim
4161226633Sdim  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4162226633Sdim    S = MCDisassembler::SoftFail;
4163226633Sdim
4164226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4165226633Sdim    return MCDisassembler::Fail;
4166226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4167226633Sdim    return MCDisassembler::Fail;
4168226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4169226633Sdim    return MCDisassembler::Fail;
4170226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4171226633Sdim    return MCDisassembler::Fail;
4172226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4173226633Sdim    return MCDisassembler::Fail;
4174226633Sdim
4175226633Sdim  return S;
4176207618Srdivacky}
4177226633Sdim
4178234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn,
4179226633Sdim                             uint64_t Address, const void *Decoder) {
4180226633Sdim  DecodeStatus S = MCDisassembler::Success;
4181226633Sdim  unsigned pred = fieldFromInstruction16(Insn, 4, 4);
4182226633Sdim  // The InstPrinter needs to have the low bit of the predicate in
4183226633Sdim  // the mask operand to be able to print it properly.
4184226633Sdim  unsigned mask = fieldFromInstruction16(Insn, 0, 5);
4185226633Sdim
4186226633Sdim  if (pred == 0xF) {
4187226633Sdim    pred = 0xE;
4188226633Sdim    S = MCDisassembler::SoftFail;
4189226633Sdim  }
4190226633Sdim
4191226633Sdim  if ((mask & 0xF) == 0) {
4192226633Sdim    // Preserve the high bit of the mask, which is the low bit of
4193226633Sdim    // the predicate.
4194226633Sdim    mask &= 0x10;
4195226633Sdim    mask |= 0x8;
4196226633Sdim    S = MCDisassembler::SoftFail;
4197226633Sdim  }
4198226633Sdim
4199226633Sdim  Inst.addOperand(MCOperand::CreateImm(pred));
4200226633Sdim  Inst.addOperand(MCOperand::CreateImm(mask));
4201226633Sdim  return S;
4202226633Sdim}
4203226633Sdim
4204226633Sdimstatic DecodeStatus
4205234353SdimDecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
4206226633Sdim                           uint64_t Address, const void *Decoder) {
4207226633Sdim  DecodeStatus S = MCDisassembler::Success;
4208226633Sdim
4209226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
4210226633Sdim  unsigned Rt2 = fieldFromInstruction32(Insn, 8, 4);
4211226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
4212226633Sdim  unsigned addr = fieldFromInstruction32(Insn, 0, 8);
4213226633Sdim  unsigned W = fieldFromInstruction32(Insn, 21, 1);
4214226633Sdim  unsigned U = fieldFromInstruction32(Insn, 23, 1);
4215226633Sdim  unsigned P = fieldFromInstruction32(Insn, 24, 1);
4216226633Sdim  bool writeback = (W == 1) | (P == 0);
4217226633Sdim
4218226633Sdim  addr |= (U << 8) | (Rn << 9);
4219226633Sdim
4220226633Sdim  if (writeback && (Rn == Rt || Rn == Rt2))
4221226633Sdim    Check(S, MCDisassembler::SoftFail);
4222226633Sdim  if (Rt == Rt2)
4223226633Sdim    Check(S, MCDisassembler::SoftFail);
4224226633Sdim
4225226633Sdim  // Rt
4226226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4227226633Sdim    return MCDisassembler::Fail;
4228226633Sdim  // Rt2
4229226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4230226633Sdim    return MCDisassembler::Fail;
4231226633Sdim  // Writeback operand
4232226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4233226633Sdim    return MCDisassembler::Fail;
4234226633Sdim  // addr
4235226633Sdim  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4236226633Sdim    return MCDisassembler::Fail;
4237226633Sdim
4238226633Sdim  return S;
4239226633Sdim}
4240226633Sdim
4241226633Sdimstatic DecodeStatus
4242234353SdimDecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
4243226633Sdim                           uint64_t Address, const void *Decoder) {
4244226633Sdim  DecodeStatus S = MCDisassembler::Success;
4245226633Sdim
4246226633Sdim  unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
4247226633Sdim  unsigned Rt2 = fieldFromInstruction32(Insn, 8, 4);
4248226633Sdim  unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
4249226633Sdim  unsigned addr = fieldFromInstruction32(Insn, 0, 8);
4250226633Sdim  unsigned W = fieldFromInstruction32(Insn, 21, 1);
4251226633Sdim  unsigned U = fieldFromInstruction32(Insn, 23, 1);
4252226633Sdim  unsigned P = fieldFromInstruction32(Insn, 24, 1);
4253226633Sdim  bool writeback = (W == 1) | (P == 0);
4254226633Sdim
4255226633Sdim  addr |= (U << 8) | (Rn << 9);
4256226633Sdim
4257226633Sdim  if (writeback && (Rn == Rt || Rn == Rt2))
4258226633Sdim    Check(S, MCDisassembler::SoftFail);
4259226633Sdim
4260226633Sdim  // Writeback operand
4261226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4262226633Sdim    return MCDisassembler::Fail;
4263226633Sdim  // Rt
4264226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4265226633Sdim    return MCDisassembler::Fail;
4266226633Sdim  // Rt2
4267226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4268226633Sdim    return MCDisassembler::Fail;
4269226633Sdim  // addr
4270226633Sdim  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4271226633Sdim    return MCDisassembler::Fail;
4272226633Sdim
4273226633Sdim  return S;
4274226633Sdim}
4275226633Sdim
4276234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn,
4277226633Sdim                                uint64_t Address, const void *Decoder) {
4278226633Sdim  unsigned sign1 = fieldFromInstruction32(Insn, 21, 1);
4279226633Sdim  unsigned sign2 = fieldFromInstruction32(Insn, 23, 1);
4280226633Sdim  if (sign1 != sign2) return MCDisassembler::Fail;
4281226633Sdim
4282226633Sdim  unsigned Val = fieldFromInstruction32(Insn, 0, 8);
4283226633Sdim  Val |= fieldFromInstruction32(Insn, 12, 3) << 8;
4284226633Sdim  Val |= fieldFromInstruction32(Insn, 26, 1) << 11;
4285226633Sdim  Val |= sign1 << 12;
4286226633Sdim  Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val)));
4287226633Sdim
4288226633Sdim  return MCDisassembler::Success;
4289226633Sdim}
4290226633Sdim
4291234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
4292226633Sdim                                              uint64_t Address,
4293226633Sdim                                              const void *Decoder) {
4294226633Sdim  DecodeStatus S = MCDisassembler::Success;
4295226633Sdim
4296226633Sdim  // Shift of "asr #32" is not allowed in Thumb2 mode.
4297226633Sdim  if (Val == 0x20) S = MCDisassembler::SoftFail;
4298226633Sdim  Inst.addOperand(MCOperand::CreateImm(Val));
4299226633Sdim  return S;
4300226633Sdim}
4301226633Sdim
4302234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
4303234353Sdim                               uint64_t Address, const void *Decoder) {
4304234353Sdim  unsigned Rt   = fieldFromInstruction32(Insn, 12, 4);
4305234353Sdim  unsigned Rt2  = fieldFromInstruction32(Insn, 0,  4);
4306234353Sdim  unsigned Rn   = fieldFromInstruction32(Insn, 16, 4);
4307234353Sdim  unsigned pred = fieldFromInstruction32(Insn, 28, 4);
4308234353Sdim
4309234353Sdim  if (pred == 0xF)
4310234353Sdim    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
4311234353Sdim
4312234353Sdim  DecodeStatus S = MCDisassembler::Success;
4313234982Sdim
4314234982Sdim  if (Rt == Rn || Rn == Rt2)
4315234982Sdim    S = MCDisassembler::SoftFail;
4316234982Sdim
4317234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4318234353Sdim    return MCDisassembler::Fail;
4319234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
4320234353Sdim    return MCDisassembler::Fail;
4321234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4322234353Sdim    return MCDisassembler::Fail;
4323234353Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4324234353Sdim    return MCDisassembler::Fail;
4325234353Sdim
4326234353Sdim  return S;
4327234353Sdim}
4328234353Sdim
4329234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
4330234353Sdim                                uint64_t Address, const void *Decoder) {
4331234353Sdim  unsigned Vd = (fieldFromInstruction32(Insn, 12, 4) << 0);
4332234353Sdim  Vd |= (fieldFromInstruction32(Insn, 22, 1) << 4);
4333234353Sdim  unsigned Vm = (fieldFromInstruction32(Insn, 0, 4) << 0);
4334234353Sdim  Vm |= (fieldFromInstruction32(Insn, 5, 1) << 4);
4335234353Sdim  unsigned imm = fieldFromInstruction32(Insn, 16, 6);
4336234353Sdim  unsigned cmode = fieldFromInstruction32(Insn, 8, 4);
4337234353Sdim
4338234353Sdim  DecodeStatus S = MCDisassembler::Success;
4339234353Sdim
4340234353Sdim  // VMOVv2f32 is ambiguous with these decodings.
4341234353Sdim  if (!(imm & 0x38) && cmode == 0xF) {
4342234353Sdim    Inst.setOpcode(ARM::VMOVv2f32);
4343234353Sdim    return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
4344234353Sdim  }
4345234353Sdim
4346234353Sdim  if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail);
4347234353Sdim
4348234353Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
4349234353Sdim    return MCDisassembler::Fail;
4350234353Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
4351234353Sdim    return MCDisassembler::Fail;
4352234353Sdim  Inst.addOperand(MCOperand::CreateImm(64 - imm));
4353234353Sdim
4354234353Sdim  return S;
4355234353Sdim}
4356234353Sdim
4357234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
4358234353Sdim                                uint64_t Address, const void *Decoder) {
4359234353Sdim  unsigned Vd = (fieldFromInstruction32(Insn, 12, 4) << 0);
4360234353Sdim  Vd |= (fieldFromInstruction32(Insn, 22, 1) << 4);
4361234353Sdim  unsigned Vm = (fieldFromInstruction32(Insn, 0, 4) << 0);
4362234353Sdim  Vm |= (fieldFromInstruction32(Insn, 5, 1) << 4);
4363234353Sdim  unsigned imm = fieldFromInstruction32(Insn, 16, 6);
4364234353Sdim  unsigned cmode = fieldFromInstruction32(Insn, 8, 4);
4365234353Sdim
4366234353Sdim  DecodeStatus S = MCDisassembler::Success;
4367234353Sdim
4368234353Sdim  // VMOVv4f32 is ambiguous with these decodings.
4369234353Sdim  if (!(imm & 0x38) && cmode == 0xF) {
4370234353Sdim    Inst.setOpcode(ARM::VMOVv4f32);
4371234353Sdim    return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
4372234353Sdim  }
4373234353Sdim
4374234353Sdim  if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail);
4375234353Sdim
4376234353Sdim  if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
4377234353Sdim    return MCDisassembler::Fail;
4378234353Sdim  if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
4379234353Sdim    return MCDisassembler::Fail;
4380234353Sdim  Inst.addOperand(MCOperand::CreateImm(64 - imm));
4381234353Sdim
4382234353Sdim  return S;
4383234353Sdim}
4384234353Sdim
4385234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
4386234353Sdim                                uint64_t Address, const void *Decoder) {
4387234353Sdim  DecodeStatus S = MCDisassembler::Success;
4388234353Sdim
4389234353Sdim  unsigned Rn = fieldFromInstruction32(Val, 16, 4);
4390234353Sdim  unsigned Rt = fieldFromInstruction32(Val, 12, 4);
4391234353Sdim  unsigned Rm = fieldFromInstruction32(Val, 0, 4);
4392234353Sdim  Rm |= (fieldFromInstruction32(Val, 23, 1) << 4);
4393234353Sdim  unsigned Cond = fieldFromInstruction32(Val, 28, 4);
4394234353Sdim
4395234353Sdim  if (fieldFromInstruction32(Val, 8, 4) != 0 || Rn == Rt)
4396234353Sdim    S = MCDisassembler::SoftFail;
4397234353Sdim
4398234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4399234353Sdim    return MCDisassembler::Fail;
4400234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4401234353Sdim    return MCDisassembler::Fail;
4402234353Sdim  if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
4403234353Sdim    return MCDisassembler::Fail;
4404234353Sdim  if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
4405234353Sdim    return MCDisassembler::Fail;
4406234353Sdim  if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
4407234353Sdim    return MCDisassembler::Fail;
4408234353Sdim
4409234353Sdim  return S;
4410234353Sdim}
4411234353Sdim
4412234982Sdimstatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
4413234982Sdim                                uint64_t Address, const void *Decoder) {
4414234982Sdim
4415234982Sdim  DecodeStatus S = MCDisassembler::Success;
4416234982Sdim
4417234982Sdim  unsigned CRm = fieldFromInstruction32(Val, 0, 4);
4418234982Sdim  unsigned opc1 = fieldFromInstruction32(Val, 4, 4);
4419234982Sdim  unsigned cop = fieldFromInstruction32(Val, 8, 4);
4420234982Sdim  unsigned Rt = fieldFromInstruction32(Val, 12, 4);
4421234982Sdim  unsigned Rt2 = fieldFromInstruction32(Val, 16, 4);
4422234982Sdim
4423234982Sdim  if ((cop & ~0x1) == 0xa)
4424234982Sdim    return MCDisassembler::Fail;
4425234982Sdim
4426234982Sdim  if (Rt == Rt2)
4427234982Sdim    S = MCDisassembler::SoftFail;
4428234982Sdim
4429234982Sdim  Inst.addOperand(MCOperand::CreateImm(cop));
4430234982Sdim  Inst.addOperand(MCOperand::CreateImm(opc1));
4431234982Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4432234982Sdim    return MCDisassembler::Fail;
4433234982Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
4434234982Sdim    return MCDisassembler::Fail;
4435234982Sdim  Inst.addOperand(MCOperand::CreateImm(CRm));
4436234982Sdim
4437234982Sdim  return S;
4438234982Sdim}
4439234982Sdim
4440