1327952Sdim//===- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA ---------------===//
2206124Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6206124Srdivacky//
7206124Srdivacky//===----------------------------------------------------------------------===//
8206124Srdivacky
9353358Sdim#include "ARMBaseInstrInfo.h"
10226633Sdim#include "MCTargetDesc/ARMAddressingModes.h"
11249423Sdim#include "MCTargetDesc/ARMBaseInfo.h"
12321369Sdim#include "MCTargetDesc/ARMMCTargetDesc.h"
13353358Sdim#include "TargetInfo/ARMTargetInfo.h"
14327952Sdim#include "Utils/ARMBaseInfo.h"
15249423Sdim#include "llvm/MC/MCContext.h"
16321369Sdim#include "llvm/MC/MCDisassembler/MCDisassembler.h"
17249423Sdim#include "llvm/MC/MCFixedLenDisassembler.h"
18206124Srdivacky#include "llvm/MC/MCInst.h"
19234353Sdim#include "llvm/MC/MCInstrDesc.h"
20234353Sdim#include "llvm/MC/MCSubtargetInfo.h"
21321369Sdim#include "llvm/MC/SubtargetFeature.h"
22321369Sdim#include "llvm/Support/Compiler.h"
23206124Srdivacky#include "llvm/Support/ErrorHandling.h"
24321369Sdim#include "llvm/Support/MathExtras.h"
25226633Sdim#include "llvm/Support/TargetRegistry.h"
26206124Srdivacky#include "llvm/Support/raw_ostream.h"
27321369Sdim#include <algorithm>
28321369Sdim#include <cassert>
29321369Sdim#include <cstdint>
30239462Sdim#include <vector>
31206124Srdivacky
32226633Sdimusing namespace llvm;
33212904Sdim
34276479Sdim#define DEBUG_TYPE "arm-disassembler"
35276479Sdim
36327952Sdimusing DecodeStatus = MCDisassembler::DecodeStatus;
37206124Srdivacky
38226633Sdimnamespace {
39321369Sdim
40239462Sdim  // Handles the condition code status of instructions in IT blocks
41239462Sdim  class ITStatus
42239462Sdim  {
43239462Sdim    public:
44239462Sdim      // Returns the condition code for instruction in IT block
45239462Sdim      unsigned getITCC() {
46239462Sdim        unsigned CC = ARMCC::AL;
47239462Sdim        if (instrInITBlock())
48239462Sdim          CC = ITStates.back();
49239462Sdim        return CC;
50239462Sdim      }
51239462Sdim
52239462Sdim      // Advances the IT block state to the next T or E
53239462Sdim      void advanceITState() {
54239462Sdim        ITStates.pop_back();
55239462Sdim      }
56239462Sdim
57239462Sdim      // Returns true if the current instruction is in an IT block
58239462Sdim      bool instrInITBlock() {
59239462Sdim        return !ITStates.empty();
60239462Sdim      }
61239462Sdim
62239462Sdim      // Returns true if current instruction is the last instruction in an IT block
63239462Sdim      bool instrLastInITBlock() {
64239462Sdim        return ITStates.size() == 1;
65239462Sdim      }
66239462Sdim
67353358Sdim      // Called when decoding an IT instruction. Sets the IT state for
68353358Sdim      // the following instructions that for the IT block. Firstcond
69353358Sdim      // corresponds to the field in the IT instruction encoding; Mask
70353358Sdim      // is in the MCOperand format in which 1 means 'else' and 0 'then'.
71239462Sdim      void setITState(char Firstcond, char Mask) {
72239462Sdim        // (3 - the number of trailing zeros) is the number of then / else.
73261991Sdim        unsigned NumTZ = countTrailingZeros<uint8_t>(Mask);
74239462Sdim        unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
75239462Sdim        assert(NumTZ <= 3 && "Invalid IT mask!");
76239462Sdim        // push condition codes onto the stack the correct order for the pops
77239462Sdim        for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
78353358Sdim          unsigned Else = (Mask >> Pos) & 1;
79353358Sdim          ITStates.push_back(CCBits ^ Else);
80239462Sdim        }
81239462Sdim        ITStates.push_back(CCBits);
82239462Sdim      }
83239462Sdim
84239462Sdim    private:
85239462Sdim      std::vector<unsigned char> ITStates;
86239462Sdim  };
87239462Sdim
88353358Sdim  class VPTStatus
89353358Sdim  {
90353358Sdim    public:
91353358Sdim      unsigned getVPTPred() {
92353358Sdim        unsigned Pred = ARMVCC::None;
93353358Sdim        if (instrInVPTBlock())
94353358Sdim          Pred = VPTStates.back();
95353358Sdim        return Pred;
96353358Sdim      }
97353358Sdim
98353358Sdim      void advanceVPTState() {
99353358Sdim        VPTStates.pop_back();
100353358Sdim      }
101353358Sdim
102353358Sdim      bool instrInVPTBlock() {
103353358Sdim        return !VPTStates.empty();
104353358Sdim      }
105353358Sdim
106353358Sdim      bool instrLastInVPTBlock() {
107353358Sdim        return VPTStates.size() == 1;
108353358Sdim      }
109353358Sdim
110353358Sdim      void setVPTState(char Mask) {
111353358Sdim        // (3 - the number of trailing zeros) is the number of then / else.
112353358Sdim        unsigned NumTZ = countTrailingZeros<uint8_t>(Mask);
113353358Sdim        assert(NumTZ <= 3 && "Invalid VPT mask!");
114353358Sdim        // push predicates onto the stack the correct order for the pops
115353358Sdim        for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
116353358Sdim          bool T = ((Mask >> Pos) & 1) == 0;
117353358Sdim          if (T)
118353358Sdim            VPTStates.push_back(ARMVCC::Then);
119353358Sdim          else
120353358Sdim            VPTStates.push_back(ARMVCC::Else);
121353358Sdim        }
122353358Sdim        VPTStates.push_back(ARMVCC::Then);
123353358Sdim      }
124353358Sdim
125353358Sdim    private:
126353358Sdim      SmallVector<unsigned char, 4> VPTStates;
127353358Sdim  };
128353358Sdim
129280031Sdim/// ARM disassembler for all ARM platforms.
130226633Sdimclass ARMDisassembler : public MCDisassembler {
131226633Sdimpublic:
132276479Sdim  ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
133276479Sdim    MCDisassembler(STI, Ctx) {
134226633Sdim  }
135226633Sdim
136321369Sdim  ~ARMDisassembler() override = default;
137226633Sdim
138280031Sdim  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
139280031Sdim                              ArrayRef<uint8_t> Bytes, uint64_t Address,
140280031Sdim                              raw_ostream &CStream) const override;
141226633Sdim
142353358Sdimprivate:
143353358Sdim  DecodeStatus getARMInstruction(MCInst &Instr, uint64_t &Size,
144353358Sdim                                 ArrayRef<uint8_t> Bytes, uint64_t Address,
145353358Sdim                                 raw_ostream &CStream) const;
146226633Sdim
147353358Sdim  DecodeStatus getThumbInstruction(MCInst &Instr, uint64_t &Size,
148353358Sdim                                   ArrayRef<uint8_t> Bytes, uint64_t Address,
149353358Sdim                                   raw_ostream &CStream) const;
150226633Sdim
151239462Sdim  mutable ITStatus ITBlock;
152353358Sdim  mutable VPTStatus VPTBlock;
153327952Sdim
154226633Sdim  DecodeStatus AddThumbPredicate(MCInst&) const;
155353358Sdim  void UpdateThumbVFPPredicate(DecodeStatus &, MCInst&) const;
156226633Sdim};
157226633Sdim
158321369Sdim} // end anonymous namespace
159321369Sdim
160226633Sdimstatic bool Check(DecodeStatus &Out, DecodeStatus In) {
161226633Sdim  switch (In) {
162226633Sdim    case MCDisassembler::Success:
163226633Sdim      // Out stays the same.
164226633Sdim      return true;
165226633Sdim    case MCDisassembler::SoftFail:
166226633Sdim      Out = In;
167226633Sdim      return true;
168226633Sdim    case MCDisassembler::Fail:
169226633Sdim      Out = In;
170226633Sdim      return false;
171226633Sdim  }
172234353Sdim  llvm_unreachable("Invalid DecodeStatus!");
173226633Sdim}
174226633Sdim
175226633Sdim// Forward declare these because the autogenerated code will reference them.
176226633Sdim// Definitions are further down.
177234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
178226633Sdim                                   uint64_t Address, const void *Decoder);
179353358Sdimstatic DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo,
180353358Sdim                                   uint64_t Address, const void *Decoder);
181353358Sdimstatic DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo,
182353358Sdim                                   uint64_t Address, const void *Decoder);
183353358Sdimstatic DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo,
184353358Sdim                                   uint64_t Address, const void *Decoder);
185234353Sdimstatic DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst,
186226633Sdim                                               unsigned RegNo, uint64_t Address,
187226633Sdim                                               const void *Decoder);
188261991Sdimstatic DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst,
189261991Sdim                                               unsigned RegNo, uint64_t Address,
190261991Sdim                                               const void *Decoder);
191353358Sdimstatic DecodeStatus DecodeGPRwithZRRegisterClass(MCInst &Inst,
192353358Sdim                                               unsigned RegNo, uint64_t Address,
193353358Sdim                                               const void *Decoder);
194353358Sdimstatic DecodeStatus DecodeGPRwithZRnospRegisterClass(
195353358Sdim    MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder);
196234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
197226633Sdim                                   uint64_t Address, const void *Decoder);
198234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
199226633Sdim                                   uint64_t Address, const void *Decoder);
200234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
201226633Sdim                                   uint64_t Address, const void *Decoder);
202261991Sdimstatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
203261991Sdim                                   uint64_t Address, const void *Decoder);
204360784Sdimstatic DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
205360784Sdim                                             uint64_t Address,
206360784Sdim                                             const void *Decoder);
207341825Sdimstatic DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
208341825Sdim                                   uint64_t Address, const void *Decoder);
209234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
210226633Sdim                                   uint64_t Address, const void *Decoder);
211234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
212226633Sdim                                   uint64_t Address, const void *Decoder);
213234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
214226633Sdim                                   uint64_t Address, const void *Decoder);
215353358Sdimstatic DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
216353358Sdim                                   uint64_t Address, const void *Decoder);
217234353Sdimstatic DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
218226633Sdim                                                unsigned RegNo,
219226633Sdim                                                uint64_t Address,
220226633Sdim                                                const void *Decoder);
221234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
222226633Sdim                                   uint64_t Address, const void *Decoder);
223353358Sdimstatic DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
224353358Sdim                                   uint64_t Address, const void *Decoder);
225353358Sdimstatic DecodeStatus DecodeQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
226353358Sdim                                   uint64_t Address, const void *Decoder);
227353358Sdimstatic DecodeStatus DecodeQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
228353358Sdim                                   uint64_t Address, const void *Decoder);
229234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
230234353Sdim                                   uint64_t Address, const void *Decoder);
231234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
232234353Sdim                               unsigned RegNo, uint64_t Address,
233234353Sdim                               const void *Decoder);
234226633Sdim
235234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
236226633Sdim                               uint64_t Address, const void *Decoder);
237234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
238226633Sdim                               uint64_t Address, const void *Decoder);
239234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
240226633Sdim                               uint64_t Address, const void *Decoder);
241234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
242226633Sdim                               uint64_t Address, const void *Decoder);
243234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
244226633Sdim                               uint64_t Address, const void *Decoder);
245226633Sdim
246234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
247226633Sdim                               uint64_t Address, const void *Decoder);
248234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
249226633Sdim                               uint64_t Address, const void *Decoder);
250234353Sdimstatic DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst,
251226633Sdim                                                  unsigned Insn,
252226633Sdim                                                  uint64_t Address,
253226633Sdim                                                  const void *Decoder);
254234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
255226633Sdim                               uint64_t Address, const void *Decoder);
256234353Sdimstatic DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn,
257226633Sdim                               uint64_t Address, const void *Decoder);
258234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
259226633Sdim                               uint64_t Address, const void *Decoder);
260234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
261226633Sdim                               uint64_t Address, const void *Decoder);
262226633Sdim
263234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst,
264226633Sdim                                                  unsigned Insn,
265226633Sdim                                                  uint64_t Adddress,
266226633Sdim                                                  const void *Decoder);
267234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
268226633Sdim                               uint64_t Address, const void *Decoder);
269234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
270226633Sdim                               uint64_t Address, const void *Decoder);
271234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
272226633Sdim                               uint64_t Address, const void *Decoder);
273309124Sdimstatic DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
274309124Sdim                               uint64_t Address, const void *Decoder);
275234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
276226633Sdim                               uint64_t Address, const void *Decoder);
277288943Sdimstatic DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
278288943Sdim                               uint64_t Address, const void *Decoder);
279288943Sdimstatic DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
280288943Sdim                               uint64_t Address, const void *Decoder);
281234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
282226633Sdim                               uint64_t Address, const void *Decoder);
283234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
284226633Sdim                               uint64_t Address, const void *Decoder);
285234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
286226633Sdim                               uint64_t Address, const void *Decoder);
287309124Sdimstatic DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
288309124Sdim                               uint64_t Address, const void *Decoder);
289234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
290226633Sdim                               uint64_t Address, const void *Decoder);
291234353Sdimstatic DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
292226633Sdim                               uint64_t Address, const void *Decoder);
293234353Sdimstatic DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn,
294226633Sdim                               uint64_t Address, const void *Decoder);
295234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
296226633Sdim                               uint64_t Address, const void *Decoder);
297261991Sdimstatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val,
298261991Sdim                               uint64_t Address, const void *Decoder);
299261991Sdimstatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val,
300261991Sdim                               uint64_t Address, const void *Decoder);
301261991Sdimstatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val,
302261991Sdim                               uint64_t Address, const void *Decoder);
303261991Sdimstatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val,
304261991Sdim                               uint64_t Address, const void *Decoder);
305234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
306226633Sdim                               uint64_t Address, const void *Decoder);
307234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
308226633Sdim                               uint64_t Address, const void *Decoder);
309234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
310226633Sdim                               uint64_t Address, const void *Decoder);
311234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
312226633Sdim                               uint64_t Address, const void *Decoder);
313234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
314226633Sdim                               uint64_t Address, const void *Decoder);
315234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
316226633Sdim                               uint64_t Address, const void *Decoder);
317360784Sdimstatic DecodeStatus DecodeVMOVModImmInstruction(MCInst &Inst,unsigned Val,
318226633Sdim                               uint64_t Address, const void *Decoder);
319353358Sdimstatic DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst,unsigned Val,
320353358Sdim                               uint64_t Address, const void *Decoder);
321353358Sdimstatic DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
322353358Sdim                               uint64_t Address, const void *Decoder);
323234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
324226633Sdim                               uint64_t Address, const void *Decoder);
325234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
326226633Sdim                               uint64_t Address, const void *Decoder);
327234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
328226633Sdim                               uint64_t Address, const void *Decoder);
329234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
330226633Sdim                               uint64_t Address, const void *Decoder);
331234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
332226633Sdim                               uint64_t Address, const void *Decoder);
333234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
334226633Sdim                               uint64_t Address, const void *Decoder);
335234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
336226633Sdim                               uint64_t Address, const void *Decoder);
337353358Sdimstatic DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn,
338353358Sdim                               uint64_t Address, const void *Decoder);
339353358Sdimtemplate<int shift>
340353358Sdimstatic DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn,
341353358Sdim                               uint64_t Address, const void *Decoder);
342234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
343226633Sdim                               uint64_t Address, const void *Decoder);
344234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
345226633Sdim                               uint64_t Address, const void *Decoder);
346261991Sdimstatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
347261991Sdim                               uint64_t Address, const void *Decoder);
348234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
349226633Sdim                               uint64_t Address, const void *Decoder);
350280031Sdimstatic DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Insn,
351280031Sdim                               uint64_t Address, const void *Decoder);
352234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
353226633Sdim                               uint64_t Address, const void *Decoder);
354234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
355226633Sdim                               uint64_t Address, const void *Decoder);
356234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
357226633Sdim                               uint64_t Address, const void *Decoder);
358234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
359226633Sdim                               uint64_t Address, const void *Decoder);
360234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
361226633Sdim                               uint64_t Address, const void *Decoder);
362234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
363226633Sdim                               uint64_t Address, const void *Decoder);
364234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
365226633Sdim                               uint64_t Address, const void *Decoder);
366234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
367226633Sdim                               uint64_t Address, const void *Decoder);
368234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
369226633Sdim                               uint64_t Address, const void *Decoder);
370234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
371226633Sdim                               uint64_t Address, const void *Decoder);
372234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
373226633Sdim                               uint64_t Address, const void *Decoder);
374234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
375226633Sdim                               uint64_t Address, const void *Decoder);
376234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
377226633Sdim                               uint64_t Address, const void *Decoder);
378234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
379226633Sdim                               uint64_t Address, const void *Decoder);
380234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
381226633Sdim                               uint64_t Address, const void *Decoder);
382234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
383226633Sdim                               uint64_t Address, const void *Decoder);
384234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
385234353Sdim                               uint64_t Address, const void *Decoder);
386234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
387234353Sdim                                uint64_t Address, const void *Decoder);
388234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
389234353Sdim                                uint64_t Address, const void *Decoder);
390353358Sdimstatic DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Insn,
391353358Sdim                                         uint64_t Address, const void *Decoder);
392327952Sdimstatic DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst,
393327952Sdim                                                       unsigned Val,
394327952Sdim                                                       uint64_t Address,
395327952Sdim                                                       const void *Decoder);
396226633Sdim
397234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
398226633Sdim                               uint64_t Address, const void *Decoder);
399234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
400226633Sdim                               uint64_t Address, const void *Decoder);
401234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
402226633Sdim                               uint64_t Address, const void *Decoder);
403234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
404226633Sdim                               uint64_t Address, const void *Decoder);
405234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
406226633Sdim                               uint64_t Address, const void *Decoder);
407234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
408226633Sdim                               uint64_t Address, const void *Decoder);
409234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
410226633Sdim                               uint64_t Address, const void *Decoder);
411234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
412226633Sdim                               uint64_t Address, const void *Decoder);
413234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
414226633Sdim                               uint64_t Address, const void *Decoder);
415234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
416226633Sdim                               uint64_t Address, const void *Decoder);
417261991Sdimstatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
418261991Sdim                               uint64_t Address, const void* Decoder);
419261991Sdimstatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
420261991Sdim                               uint64_t Address, const void* Decoder);
421261991Sdimstatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
422261991Sdim                               uint64_t Address, const void* Decoder);
423261991Sdimstatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
424261991Sdim                               uint64_t Address, const void* Decoder);
425234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
426226633Sdim                               uint64_t Address, const void *Decoder);
427353358Sdimstatic DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val,
428353358Sdim                               uint64_t Address, const void *Decoder);
429234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
430226633Sdim                               uint64_t Address, const void *Decoder);
431353358Sdimstatic DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val,
432353358Sdim                                           uint64_t Address,
433353358Sdim                                           const void *Decoder);
434234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
435226633Sdim                               uint64_t Address, const void *Decoder);
436234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
437226633Sdim                               uint64_t Address, const void *Decoder);
438353358Sdimtemplate<int shift>
439353358Sdimstatic DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val,
440353358Sdim                               uint64_t Address, const void *Decoder);
441234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
442226633Sdim                               uint64_t Address, const void *Decoder);
443353358Sdimtemplate<int shift>
444353358Sdimstatic DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val,
445353358Sdim                               uint64_t Address, const void *Decoder);
446353358Sdimtemplate<int shift, int WriteBack>
447353358Sdimstatic DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val,
448353358Sdim                               uint64_t Address, const void *Decoder);
449234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
450226633Sdim                               uint64_t Address, const void *Decoder);
451234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
452226633Sdim                                uint64_t Address, const void *Decoder);
453234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
454226633Sdim                                uint64_t Address, const void *Decoder);
455261991Sdimstatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
456261991Sdim                                uint64_t Address, const void *Decoder);
457234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
458226633Sdim                                uint64_t Address, const void *Decoder);
459234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
460226633Sdim                                uint64_t Address, const void *Decoder);
461234353Sdimstatic DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
462226633Sdim                                uint64_t Address, const void *Decoder);
463234353Sdimstatic DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
464226633Sdim                                uint64_t Address, const void *Decoder);
465234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
466226633Sdim                                uint64_t Address, const void *Decoder);
467234353Sdimstatic DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val,
468226633Sdim                                uint64_t Address, const void *Decoder);
469234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
470226633Sdim                                uint64_t Address, const void *Decoder);
471234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Val,
472226633Sdim                                uint64_t Address, const void *Decoder);
473234353Sdimstatic DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn,
474226633Sdim                               uint64_t Address, const void *Decoder);
475234353Sdimstatic DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn,
476226633Sdim                               uint64_t Address, const void *Decoder);
477234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val,
478226633Sdim                                uint64_t Address, const void *Decoder);
479234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
480226633Sdim                                uint64_t Address, const void *Decoder);
481234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
482226633Sdim                                uint64_t Address, const void *Decoder);
483226633Sdim
484234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
485234353Sdim                                uint64_t Address, const void *Decoder);
486321369Sdimstatic DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
487309124Sdim                                            uint64_t Address, const void *Decoder);
488327952Sdimstatic DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
489327952Sdim                                         uint64_t Address, const void *Decoder);
490321369Sdim
491353358Sdimtemplate <bool isSigned, bool isNeg, bool zeroPermitted, int size>
492353358Sdimstatic DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned val,
493353358Sdim                                         uint64_t Address, const void *Decoder);
494353358Sdimstatic DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned val,
495353358Sdim                                               uint64_t Address,
496353358Sdim                                               const void *Decoder);
497353358Sdimstatic DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val,
498353358Sdim                                          uint64_t Address,
499353358Sdim                                          const void *Decoder);
500353358Sdimstatic DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address,
501353358Sdim                                 const void *Decoder);
502353358Sdimstatic DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val,
503353358Sdim                                           uint64_t Address,
504353358Sdim                                           const void *Decoder);
505353358Sdimstatic DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
506353358Sdim                                  const void *Decoder);
507353358Sdimstatic DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
508353358Sdim                                         uint64_t Address, const void *Decoder);
509353358Sdimstatic DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned Val,
510353358Sdim                                        uint64_t Address, const void *Decoder);
511353358Sdimstatic DecodeStatus DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val,
512353358Sdim                                                     uint64_t Address,
513353358Sdim                                                     const void *Decoder);
514353358Sdimstatic DecodeStatus DecodeRestrictedSPredicateOperand(MCInst &Inst, unsigned Val,
515353358Sdim                                                     uint64_t Address,
516353358Sdim                                                     const void *Decoder);
517353358Sdimstatic DecodeStatus DecodeRestrictedUPredicateOperand(MCInst &Inst, unsigned Val,
518353358Sdim                                                     uint64_t Address,
519353358Sdim                                                     const void *Decoder);
520353358Sdimstatic DecodeStatus DecodeRestrictedFPPredicateOperand(MCInst &Inst,
521353358Sdim                                                       unsigned Val,
522353358Sdim                                                       uint64_t Address,
523353358Sdim                                                       const void *Decoder);
524353358Sdimtemplate<bool Writeback>
525353358Sdimstatic DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Insn,
526353358Sdim                                          uint64_t Address,
527353358Sdim                                          const void *Decoder);
528353358Sdimtemplate<int shift>
529353358Sdimstatic DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val,
530353358Sdim                                        uint64_t Address, const void *Decoder);
531353358Sdimtemplate<int shift>
532353358Sdimstatic DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val,
533353358Sdim                                        uint64_t Address, const void *Decoder);
534353358Sdimtemplate<int shift>
535353358Sdimstatic DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val,
536353358Sdim                                        uint64_t Address, const void *Decoder);
537353358Sdimtemplate<unsigned MinLog, unsigned MaxLog>
538353358Sdimstatic DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
539353358Sdim                                          uint64_t Address,
540353358Sdim                                          const void *Decoder);
541353358Sdimtemplate <int shift>
542353358Sdimstatic DecodeStatus DecodeExpandedImmOperand(MCInst &Inst, unsigned Val,
543353358Sdim                                             uint64_t Address,
544353358Sdim                                             const void *Decoder);
545353358Sdimtemplate<unsigned start>
546353358Sdimstatic DecodeStatus DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val,
547353358Sdim                                                    uint64_t Address,
548353358Sdim                                                    const void *Decoder);
549353358Sdimstatic DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn,
550353358Sdim                                         uint64_t Address,
551353358Sdim                                         const void *Decoder);
552353358Sdimstatic DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn,
553353358Sdim                                         uint64_t Address,
554353358Sdim                                         const void *Decoder);
555353358Sdimstatic DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
556353358Sdim                                      uint64_t Address, const void *Decoder);
557353358Sdimtypedef DecodeStatus OperandDecoder(MCInst &Inst, unsigned Val,
558353358Sdim                                    uint64_t Address, const void *Decoder);
559353358Sdimtemplate<bool scalar, OperandDecoder predicate_decoder>
560353358Sdimstatic DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn,
561353358Sdim                                  uint64_t Address, const void *Decoder);
562353358Sdimstatic DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn,
563353358Sdim                                  uint64_t Address, const void *Decoder);
564360784Sdimstatic DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
565360784Sdim                                   uint64_t Address, const void *Decoder);
566353358Sdimstatic DecodeStatus DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn,
567353358Sdim                                                  uint64_t Address,
568353358Sdim                                                  const void *Decoder);
569360784Sdimstatic DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
570360784Sdim                                        uint64_t Address, const void *Decoder);
571360784Sdim
572226633Sdim#include "ARMGenDisassemblerTables.inc"
573206124Srdivacky
574276479Sdimstatic MCDisassembler *createARMDisassembler(const Target &T,
575276479Sdim                                             const MCSubtargetInfo &STI,
576276479Sdim                                             MCContext &Ctx) {
577276479Sdim  return new ARMDisassembler(STI, Ctx);
578226633Sdim}
579207618Srdivacky
580280031Sdim// Post-decoding checks
581280031Sdimstatic DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,
582360784Sdim                                            uint64_t Address, raw_ostream &CS,
583280031Sdim                                            uint32_t Insn,
584321369Sdim                                            DecodeStatus Result) {
585280031Sdim  switch (MI.getOpcode()) {
586280031Sdim    case ARM::HVC: {
587280031Sdim      // HVC is undefined if condition = 0xf otherwise upredictable
588280031Sdim      // if condition != 0xe
589280031Sdim      uint32_t Cond = (Insn >> 28) & 0xF;
590280031Sdim      if (Cond == 0xF)
591280031Sdim        return MCDisassembler::Fail;
592280031Sdim      if (Cond != 0xE)
593280031Sdim        return MCDisassembler::SoftFail;
594280031Sdim      return Result;
595280031Sdim    }
596353358Sdim    case ARM::t2ADDri:
597353358Sdim    case ARM::t2ADDri12:
598353358Sdim    case ARM::t2ADDrr:
599353358Sdim    case ARM::t2ADDrs:
600353358Sdim    case ARM::t2SUBri:
601353358Sdim    case ARM::t2SUBri12:
602353358Sdim    case ARM::t2SUBrr:
603353358Sdim    case ARM::t2SUBrs:
604353358Sdim      if (MI.getOperand(0).getReg() == ARM::SP &&
605353358Sdim          MI.getOperand(1).getReg() != ARM::SP)
606353358Sdim        return MCDisassembler::SoftFail;
607353358Sdim      return Result;
608280031Sdim    default: return Result;
609280031Sdim  }
610280031Sdim}
611280031Sdim
612226633SdimDecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
613280031Sdim                                             ArrayRef<uint8_t> Bytes,
614360784Sdim                                             uint64_t Address,
615280031Sdim                                             raw_ostream &CS) const {
616353358Sdim  if (STI.getFeatureBits()[ARM::ModeThumb])
617360784Sdim    return getThumbInstruction(MI, Size, Bytes, Address, CS);
618360784Sdim  return getARMInstruction(MI, Size, Bytes, Address, CS);
619353358Sdim}
620353358Sdim
621353358SdimDecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size,
622353358Sdim                                                ArrayRef<uint8_t> Bytes,
623353358Sdim                                                uint64_t Address,
624353358Sdim                                                raw_ostream &CS) const {
625280031Sdim  CommentStream = &CS;
626226633Sdim
627288943Sdim  assert(!STI.getFeatureBits()[ARM::ModeThumb] &&
628280031Sdim         "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
629280031Sdim         "mode!");
630226633Sdim
631226633Sdim  // We want to read exactly 4 bytes of data.
632280031Sdim  if (Bytes.size() < 4) {
633226633Sdim    Size = 0;
634226633Sdim    return MCDisassembler::Fail;
635206124Srdivacky  }
636226633Sdim
637226633Sdim  // Encoded as a small-endian 32-bit word in the stream.
638280031Sdim  uint32_t Insn =
639280031Sdim      (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
640226633Sdim
641226633Sdim  // Calling the auto-generated decoder function.
642280031Sdim  DecodeStatus Result =
643280031Sdim      decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI);
644280031Sdim  if (Result != MCDisassembler::Fail) {
645226633Sdim    Size = 4;
646360784Sdim    return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
647226633Sdim  }
648226633Sdim
649321369Sdim  struct DecodeTable {
650321369Sdim    const uint8_t *P;
651321369Sdim    bool DecodePred;
652321369Sdim  };
653226633Sdim
654321369Sdim  const DecodeTable Tables[] = {
655321369Sdim      {DecoderTableVFP32, false},      {DecoderTableVFPV832, false},
656321369Sdim      {DecoderTableNEONData32, true},  {DecoderTableNEONLoadStore32, true},
657321369Sdim      {DecoderTableNEONDup32, true},   {DecoderTablev8NEON32, false},
658321369Sdim      {DecoderTablev8Crypto32, false},
659321369Sdim  };
660261991Sdim
661321369Sdim  for (auto Table : Tables) {
662321369Sdim    Result = decodeInstruction(Table.P, MI, Insn, Address, this, STI);
663321369Sdim    if (Result != MCDisassembler::Fail) {
664321369Sdim      Size = 4;
665321369Sdim      // Add a fake predicate operand, because we share these instruction
666321369Sdim      // definitions with Thumb2 where these instructions are predicable.
667321369Sdim      if (Table.DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this))
668321369Sdim        return MCDisassembler::Fail;
669321369Sdim      return Result;
670321369Sdim    }
671226633Sdim  }
672226633Sdim
673327952Sdim  Result =
674327952Sdim      decodeInstruction(DecoderTableCoProc32, MI, Insn, Address, this, STI);
675327952Sdim  if (Result != MCDisassembler::Fail) {
676327952Sdim    Size = 4;
677360784Sdim    return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
678327952Sdim  }
679327952Sdim
680321369Sdim  Size = 4;
681226633Sdim  return MCDisassembler::Fail;
682206124Srdivacky}
683206124Srdivacky
684226633Sdimnamespace llvm {
685321369Sdim
686234353Sdimextern const MCInstrDesc ARMInsts[];
687206124Srdivacky
688321369Sdim} // end namespace llvm
689321369Sdim
690226633Sdim/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
691226633Sdim/// immediate Value in the MCInst.  The immediate Value has had any PC
692226633Sdim/// adjustment made by the caller.  If the instruction is a branch instruction
693226633Sdim/// then isBranch is true, else false.  If the getOpInfo() function was set as
694226633Sdim/// part of the setupForSymbolicDisassembly() call then that function is called
695226633Sdim/// to get any symbolic information at the Address for this instruction.  If
696226633Sdim/// that returns non-zero then the symbolic information it returns is used to
697226633Sdim/// create an MCExpr and that is added as an operand to the MCInst.  If
698226633Sdim/// getOpInfo() returns zero and isBranch is true then a symbol look up for
699226633Sdim/// Value is done and if a symbol is found an MCExpr is created with that, else
700226633Sdim/// an MCExpr with Value is created.  This function returns true if it adds an
701226633Sdim/// operand to the MCInst and false otherwise.
702226633Sdimstatic bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
703226633Sdim                                     bool isBranch, uint64_t InstSize,
704226633Sdim                                     MCInst &MI, const void *Decoder) {
705226633Sdim  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
706261991Sdim  // FIXME: Does it make sense for value to be negative?
707261991Sdim  return Dis->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address, isBranch,
708261991Sdim                                       /* Offset */ 0, InstSize);
709226633Sdim}
710226633Sdim
711226633Sdim/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
712226633Sdim/// referenced by a load instruction with the base register that is the Pc.
713226633Sdim/// These can often be values in a literal pool near the Address of the
714226633Sdim/// instruction.  The Address of the instruction and its immediate Value are
715226633Sdim/// used as a possible literal pool entry.  The SymbolLookUp call back will
716239462Sdim/// return the name of a symbol referenced by the literal pool's entry if
717226633Sdim/// the referenced address is that of a symbol.  Or it will return a pointer to
718226633Sdim/// a literal 'C' string if the referenced address of the literal pool's entry
719226633Sdim/// is an address into a section with 'C' string literals.
720226633Sdimstatic void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
721234353Sdim                                            const void *Decoder) {
722226633Sdim  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
723261991Sdim  Dis->tryAddingPcLoadReferenceComment(Value, Address);
724226633Sdim}
725206124Srdivacky
726226633Sdim// Thumb1 instructions don't have explicit S bits.  Rather, they
727226633Sdim// implicitly set CPSR.  Since it's not represented in the encoding, the
728226633Sdim// auto-generated decoder won't inject the CPSR operand.  We need to fix
729226633Sdim// that as a post-pass.
730226633Sdimstatic void AddThumb1SBit(MCInst &MI, bool InITBlock) {
731226633Sdim  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
732226633Sdim  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
733226633Sdim  MCInst::iterator I = MI.begin();
734226633Sdim  for (unsigned i = 0; i < NumOps; ++i, ++I) {
735226633Sdim    if (I == MI.end()) break;
736226633Sdim    if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
737226633Sdim      if (i > 0 && OpInfo[i-1].isPredicate()) continue;
738288943Sdim      MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
739226633Sdim      return;
740226633Sdim    }
741226633Sdim  }
742206124Srdivacky
743288943Sdim  MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
744226633Sdim}
745206124Srdivacky
746353358Sdimstatic bool isVectorPredicable(unsigned Opcode) {
747353358Sdim  const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
748353358Sdim  unsigned short NumOps = ARMInsts[Opcode].NumOperands;
749353358Sdim  for (unsigned i = 0; i < NumOps; ++i) {
750353358Sdim    if (ARM::isVpred(OpInfo[i].OperandType))
751353358Sdim      return true;
752353358Sdim  }
753353358Sdim  return false;
754353358Sdim}
755353358Sdim
756226633Sdim// Most Thumb instructions don't have explicit predicates in the
757226633Sdim// encoding, but rather get their predicates from IT context.  We need
758226633Sdim// to fix up the predicate operands using this context information as a
759226633Sdim// post-pass.
760226633SdimMCDisassembler::DecodeStatus
761353358SdimARMDisassembler::AddThumbPredicate(MCInst &MI) const {
762226633Sdim  MCDisassembler::DecodeStatus S = Success;
763206124Srdivacky
764309124Sdim  const FeatureBitset &FeatureBits = getSubtargetInfo().getFeatureBits();
765309124Sdim
766226633Sdim  // A few instructions actually have predicates encoded in them.  Don't
767226633Sdim  // try to overwrite it if we're seeing one of those.
768226633Sdim  switch (MI.getOpcode()) {
769226633Sdim    case ARM::tBcc:
770226633Sdim    case ARM::t2Bcc:
771226633Sdim    case ARM::tCBZ:
772226633Sdim    case ARM::tCBNZ:
773226633Sdim    case ARM::tCPS:
774226633Sdim    case ARM::t2CPS3p:
775226633Sdim    case ARM::t2CPS2p:
776226633Sdim    case ARM::t2CPS1p:
777353358Sdim    case ARM::t2CSEL:
778353358Sdim    case ARM::t2CSINC:
779353358Sdim    case ARM::t2CSINV:
780353358Sdim    case ARM::t2CSNEG:
781226633Sdim    case ARM::tMOVSr:
782226633Sdim    case ARM::tSETEND:
783226633Sdim      // Some instructions (mostly conditional branches) are not
784226633Sdim      // allowed in IT blocks.
785239462Sdim      if (ITBlock.instrInITBlock())
786226633Sdim        S = SoftFail;
787226633Sdim      else
788226633Sdim        return Success;
789226633Sdim      break;
790309124Sdim    case ARM::t2HINT:
791309124Sdim      if (MI.getOperand(0).getImm() == 0x10 && (FeatureBits[ARM::FeatureRAS]) != 0)
792309124Sdim        S = SoftFail;
793309124Sdim      break;
794226633Sdim    case ARM::tB:
795226633Sdim    case ARM::t2B:
796226633Sdim    case ARM::t2TBB:
797226633Sdim    case ARM::t2TBH:
798226633Sdim      // Some instructions (mostly unconditional branches) can
799226633Sdim      // only appears at the end of, or outside of, an IT.
800239462Sdim      if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
801226633Sdim        S = SoftFail;
802226633Sdim      break;
803226633Sdim    default:
804226633Sdim      break;
805226633Sdim  }
806226633Sdim
807353358Sdim  // Warn on non-VPT predicable instruction in a VPT block and a VPT
808353358Sdim  // predicable instruction in an IT block
809353358Sdim  if ((!isVectorPredicable(MI.getOpcode()) && VPTBlock.instrInVPTBlock()) ||
810353358Sdim       (isVectorPredicable(MI.getOpcode()) && ITBlock.instrInITBlock()))
811353358Sdim    S = SoftFail;
812353358Sdim
813353358Sdim  // If we're in an IT/VPT block, base the predicate on that.  Otherwise,
814226633Sdim  // assume a predicate of AL.
815353358Sdim  unsigned CC = ARMCC::AL;
816353358Sdim  unsigned VCC = ARMVCC::None;
817353358Sdim  if (ITBlock.instrInITBlock()) {
818353358Sdim    CC = ITBlock.getITCC();
819239462Sdim    ITBlock.advanceITState();
820353358Sdim  } else if (VPTBlock.instrInVPTBlock()) {
821353358Sdim    VCC = VPTBlock.getVPTPred();
822353358Sdim    VPTBlock.advanceVPTState();
823353358Sdim  }
824226633Sdim
825226633Sdim  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
826226633Sdim  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
827353358Sdim
828353358Sdim  MCInst::iterator CCI = MI.begin();
829353358Sdim  for (unsigned i = 0; i < NumOps; ++i, ++CCI) {
830353358Sdim    if (OpInfo[i].isPredicate() || CCI == MI.end()) break;
831353358Sdim  }
832353358Sdim
833353358Sdim  if (ARMInsts[MI.getOpcode()].isPredicable()) {
834353358Sdim    CCI = MI.insert(CCI, MCOperand::createImm(CC));
835353358Sdim    ++CCI;
836353358Sdim    if (CC == ARMCC::AL)
837353358Sdim      MI.insert(CCI, MCOperand::createReg(0));
838353358Sdim    else
839353358Sdim      MI.insert(CCI, MCOperand::createReg(ARM::CPSR));
840353358Sdim  } else if (CC != ARMCC::AL) {
841353358Sdim    Check(S, SoftFail);
842353358Sdim  }
843353358Sdim
844353358Sdim  MCInst::iterator VCCI = MI.begin();
845353358Sdim  unsigned VCCPos;
846353358Sdim  for (VCCPos = 0; VCCPos < NumOps; ++VCCPos, ++VCCI) {
847353358Sdim    if (ARM::isVpred(OpInfo[VCCPos].OperandType) || VCCI == MI.end()) break;
848353358Sdim  }
849353358Sdim
850353358Sdim  if (isVectorPredicable(MI.getOpcode())) {
851353358Sdim    VCCI = MI.insert(VCCI, MCOperand::createImm(VCC));
852353358Sdim    ++VCCI;
853353358Sdim    if (VCC == ARMVCC::None)
854353358Sdim      MI.insert(VCCI, MCOperand::createReg(0));
855353358Sdim    else
856353358Sdim      MI.insert(VCCI, MCOperand::createReg(ARM::P0));
857353358Sdim    if (OpInfo[VCCPos].OperandType == ARM::OPERAND_VPRED_R) {
858353358Sdim      int TiedOp = ARMInsts[MI.getOpcode()].getOperandConstraint(
859353358Sdim        VCCPos + 2, MCOI::TIED_TO);
860353358Sdim      assert(TiedOp >= 0 &&
861353358Sdim             "Inactive register in vpred_r is not tied to an output!");
862353358Sdim      MI.insert(VCCI, MI.getOperand(TiedOp));
863226633Sdim    }
864353358Sdim  } else if (VCC != ARMVCC::None) {
865353358Sdim    Check(S, SoftFail);
866226633Sdim  }
867226633Sdim
868226633Sdim  return S;
869226633Sdim}
870226633Sdim
871226633Sdim// Thumb VFP instructions are a special case.  Because we share their
872226633Sdim// encodings between ARM and Thumb modes, and they are predicable in ARM
873226633Sdim// mode, the auto-generated decoder will give them an (incorrect)
874226633Sdim// predicate operand.  We need to rewrite these operands based on the IT
875226633Sdim// context as a post-pass.
876353358Sdimvoid ARMDisassembler::UpdateThumbVFPPredicate(
877353358Sdim  DecodeStatus &S, MCInst &MI) const {
878226633Sdim  unsigned CC;
879239462Sdim  CC = ITBlock.getITCC();
880341825Sdim  if (CC == 0xF)
881341825Sdim    CC = ARMCC::AL;
882239462Sdim  if (ITBlock.instrInITBlock())
883239462Sdim    ITBlock.advanceITState();
884353358Sdim  else if (VPTBlock.instrInVPTBlock()) {
885353358Sdim    CC = VPTBlock.getVPTPred();
886353358Sdim    VPTBlock.advanceVPTState();
887353358Sdim  }
888226633Sdim
889226633Sdim  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
890226633Sdim  MCInst::iterator I = MI.begin();
891226633Sdim  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
892226633Sdim  for (unsigned i = 0; i < NumOps; ++i, ++I) {
893226633Sdim    if (OpInfo[i].isPredicate() ) {
894353358Sdim      if (CC != ARMCC::AL && !ARMInsts[MI.getOpcode()].isPredicable())
895353358Sdim        Check(S, SoftFail);
896226633Sdim      I->setImm(CC);
897226633Sdim      ++I;
898226633Sdim      if (CC == ARMCC::AL)
899226633Sdim        I->setReg(0);
900226633Sdim      else
901226633Sdim        I->setReg(ARM::CPSR);
902226633Sdim      return;
903226633Sdim    }
904226633Sdim  }
905226633Sdim}
906226633Sdim
907353358SdimDecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
908353358Sdim                                                  ArrayRef<uint8_t> Bytes,
909353358Sdim                                                  uint64_t Address,
910353358Sdim                                                  raw_ostream &CS) const {
911280031Sdim  CommentStream = &CS;
912226633Sdim
913288943Sdim  assert(STI.getFeatureBits()[ARM::ModeThumb] &&
914226633Sdim         "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
915226633Sdim
916226633Sdim  // We want to read exactly 2 bytes of data.
917280031Sdim  if (Bytes.size() < 2) {
918226633Sdim    Size = 0;
919226633Sdim    return MCDisassembler::Fail;
920226633Sdim  }
921226633Sdim
922280031Sdim  uint16_t Insn16 = (Bytes[1] << 8) | Bytes[0];
923280031Sdim  DecodeStatus Result =
924280031Sdim      decodeInstruction(DecoderTableThumb16, MI, Insn16, Address, this, STI);
925280031Sdim  if (Result != MCDisassembler::Fail) {
926226633Sdim    Size = 2;
927280031Sdim    Check(Result, AddThumbPredicate(MI));
928280031Sdim    return Result;
929226633Sdim  }
930226633Sdim
931280031Sdim  Result = decodeInstruction(DecoderTableThumbSBit16, MI, Insn16, Address, this,
932280031Sdim                             STI);
933280031Sdim  if (Result) {
934226633Sdim    Size = 2;
935239462Sdim    bool InITBlock = ITBlock.instrInITBlock();
936280031Sdim    Check(Result, AddThumbPredicate(MI));
937226633Sdim    AddThumb1SBit(MI, InITBlock);
938280031Sdim    return Result;
939226633Sdim  }
940226633Sdim
941280031Sdim  Result =
942280031Sdim      decodeInstruction(DecoderTableThumb216, MI, Insn16, Address, this, STI);
943280031Sdim  if (Result != MCDisassembler::Fail) {
944226633Sdim    Size = 2;
945226633Sdim
946226633Sdim    // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
947226633Sdim    // the Thumb predicate.
948239462Sdim    if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
949280031Sdim      Result = MCDisassembler::SoftFail;
950226633Sdim
951280031Sdim    Check(Result, AddThumbPredicate(MI));
952226633Sdim
953226633Sdim    // If we find an IT instruction, we need to parse its condition
954226633Sdim    // code and mask operands so that we can apply them correctly
955226633Sdim    // to the subsequent instructions.
956226633Sdim    if (MI.getOpcode() == ARM::t2IT) {
957239462Sdim      unsigned Firstcond = MI.getOperand(0).getImm();
958226633Sdim      unsigned Mask = MI.getOperand(1).getImm();
959239462Sdim      ITBlock.setITState(Firstcond, Mask);
960341825Sdim
961341825Sdim      // An IT instruction that would give a 'NV' predicate is unpredictable.
962341825Sdim      if (Firstcond == ARMCC::AL && !isPowerOf2_32(Mask))
963341825Sdim        CS << "unpredictable IT predicate sequence";
964226633Sdim    }
965226633Sdim
966280031Sdim    return Result;
967226633Sdim  }
968226633Sdim
969226633Sdim  // We want to read exactly 4 bytes of data.
970280031Sdim  if (Bytes.size() < 4) {
971226633Sdim    Size = 0;
972226633Sdim    return MCDisassembler::Fail;
973226633Sdim  }
974226633Sdim
975280031Sdim  uint32_t Insn32 =
976280031Sdim      (Bytes[3] << 8) | (Bytes[2] << 0) | (Bytes[1] << 24) | (Bytes[0] << 16);
977353358Sdim
978280031Sdim  Result =
979353358Sdim      decodeInstruction(DecoderTableMVE32, MI, Insn32, Address, this, STI);
980353358Sdim  if (Result != MCDisassembler::Fail) {
981353358Sdim    Size = 4;
982353358Sdim
983353358Sdim    // Nested VPT blocks are UNPREDICTABLE. Must be checked before we add
984353358Sdim    // the VPT predicate.
985353358Sdim    if (isVPTOpcode(MI.getOpcode()) && VPTBlock.instrInVPTBlock())
986353358Sdim      Result = MCDisassembler::SoftFail;
987353358Sdim
988353358Sdim    Check(Result, AddThumbPredicate(MI));
989353358Sdim
990353358Sdim    if (isVPTOpcode(MI.getOpcode())) {
991353358Sdim      unsigned Mask = MI.getOperand(0).getImm();
992353358Sdim      VPTBlock.setVPTState(Mask);
993353358Sdim    }
994353358Sdim
995353358Sdim    return Result;
996353358Sdim  }
997353358Sdim
998353358Sdim  Result =
999280031Sdim      decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
1000280031Sdim  if (Result != MCDisassembler::Fail) {
1001226633Sdim    Size = 4;
1002239462Sdim    bool InITBlock = ITBlock.instrInITBlock();
1003280031Sdim    Check(Result, AddThumbPredicate(MI));
1004226633Sdim    AddThumb1SBit(MI, InITBlock);
1005280031Sdim    return Result;
1006226633Sdim  }
1007226633Sdim
1008280031Sdim  Result =
1009280031Sdim      decodeInstruction(DecoderTableThumb232, MI, Insn32, Address, this, STI);
1010280031Sdim  if (Result != MCDisassembler::Fail) {
1011226633Sdim    Size = 4;
1012280031Sdim    Check(Result, AddThumbPredicate(MI));
1013360784Sdim    return checkDecodedInstruction(MI, Size, Address, CS, Insn32, Result);
1014226633Sdim  }
1015226633Sdim
1016280031Sdim  if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
1017280031Sdim    Result =
1018280031Sdim        decodeInstruction(DecoderTableVFP32, MI, Insn32, Address, this, STI);
1019280031Sdim    if (Result != MCDisassembler::Fail) {
1020261991Sdim      Size = 4;
1021353358Sdim      UpdateThumbVFPPredicate(Result, MI);
1022280031Sdim      return Result;
1023261991Sdim    }
1024226633Sdim  }
1025226633Sdim
1026280031Sdim  Result =
1027280031Sdim      decodeInstruction(DecoderTableVFPV832, MI, Insn32, Address, this, STI);
1028280031Sdim  if (Result != MCDisassembler::Fail) {
1029226633Sdim    Size = 4;
1030280031Sdim    return Result;
1031226633Sdim  }
1032226633Sdim
1033280031Sdim  if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
1034280031Sdim    Result = decodeInstruction(DecoderTableNEONDup32, MI, Insn32, Address, this,
1035280031Sdim                               STI);
1036280031Sdim    if (Result != MCDisassembler::Fail) {
1037261991Sdim      Size = 4;
1038280031Sdim      Check(Result, AddThumbPredicate(MI));
1039280031Sdim      return Result;
1040261991Sdim    }
1041261991Sdim  }
1042261991Sdim
1043280031Sdim  if (fieldFromInstruction(Insn32, 24, 8) == 0xF9) {
1044280031Sdim    uint32_t NEONLdStInsn = Insn32;
1045226633Sdim    NEONLdStInsn &= 0xF0FFFFFF;
1046226633Sdim    NEONLdStInsn |= 0x04000000;
1047280031Sdim    Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
1048239462Sdim                               Address, this, STI);
1049280031Sdim    if (Result != MCDisassembler::Fail) {
1050226633Sdim      Size = 4;
1051280031Sdim      Check(Result, AddThumbPredicate(MI));
1052280031Sdim      return Result;
1053226633Sdim    }
1054226633Sdim  }
1055226633Sdim
1056280031Sdim  if (fieldFromInstruction(Insn32, 24, 4) == 0xF) {
1057280031Sdim    uint32_t NEONDataInsn = Insn32;
1058226633Sdim    NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
1059226633Sdim    NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
1060226633Sdim    NEONDataInsn |= 0x12000000; // Set bits 28 and 25
1061280031Sdim    Result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
1062239462Sdim                               Address, this, STI);
1063280031Sdim    if (Result != MCDisassembler::Fail) {
1064226633Sdim      Size = 4;
1065280031Sdim      Check(Result, AddThumbPredicate(MI));
1066280031Sdim      return Result;
1067226633Sdim    }
1068261991Sdim
1069280031Sdim    uint32_t NEONCryptoInsn = Insn32;
1070261991Sdim    NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
1071261991Sdim    NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
1072261991Sdim    NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
1073280031Sdim    Result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
1074261991Sdim                               Address, this, STI);
1075280031Sdim    if (Result != MCDisassembler::Fail) {
1076261991Sdim      Size = 4;
1077280031Sdim      return Result;
1078261991Sdim    }
1079261991Sdim
1080280031Sdim    uint32_t NEONv8Insn = Insn32;
1081261991Sdim    NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
1082280031Sdim    Result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
1083261991Sdim                               this, STI);
1084280031Sdim    if (Result != MCDisassembler::Fail) {
1085261991Sdim      Size = 4;
1086280031Sdim      return Result;
1087261991Sdim    }
1088226633Sdim  }
1089226633Sdim
1090327952Sdim  Result =
1091327952Sdim      decodeInstruction(DecoderTableThumb2CoProc32, MI, Insn32, Address, this, STI);
1092327952Sdim  if (Result != MCDisassembler::Fail) {
1093327952Sdim    Size = 4;
1094327952Sdim    Check(Result, AddThumbPredicate(MI));
1095327952Sdim    return Result;
1096327952Sdim  }
1097327952Sdim
1098226633Sdim  Size = 0;
1099226633Sdim  return MCDisassembler::Fail;
1100226633Sdim}
1101226633Sdim
1102360784Sdimextern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMDisassembler() {
1103314564Sdim  TargetRegistry::RegisterMCDisassembler(getTheARMLETarget(),
1104226633Sdim                                         createARMDisassembler);
1105314564Sdim  TargetRegistry::RegisterMCDisassembler(getTheARMBETarget(),
1106276479Sdim                                         createARMDisassembler);
1107314564Sdim  TargetRegistry::RegisterMCDisassembler(getTheThumbLETarget(),
1108353358Sdim                                         createARMDisassembler);
1109314564Sdim  TargetRegistry::RegisterMCDisassembler(getTheThumbBETarget(),
1110353358Sdim                                         createARMDisassembler);
1111226633Sdim}
1112226633Sdim
1113234353Sdimstatic const uint16_t GPRDecoderTable[] = {
1114226633Sdim  ARM::R0, ARM::R1, ARM::R2, ARM::R3,
1115226633Sdim  ARM::R4, ARM::R5, ARM::R6, ARM::R7,
1116226633Sdim  ARM::R8, ARM::R9, ARM::R10, ARM::R11,
1117226633Sdim  ARM::R12, ARM::SP, ARM::LR, ARM::PC
1118226633Sdim};
1119226633Sdim
1120353358Sdimstatic const uint16_t CLRMGPRDecoderTable[] = {
1121353358Sdim  ARM::R0, ARM::R1, ARM::R2, ARM::R3,
1122353358Sdim  ARM::R4, ARM::R5, ARM::R6, ARM::R7,
1123353358Sdim  ARM::R8, ARM::R9, ARM::R10, ARM::R11,
1124353358Sdim  ARM::R12, 0, ARM::LR, ARM::APSR
1125353358Sdim};
1126353358Sdim
1127234353Sdimstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1128226633Sdim                                   uint64_t Address, const void *Decoder) {
1129226633Sdim  if (RegNo > 15)
1130226633Sdim    return MCDisassembler::Fail;
1131226633Sdim
1132226633Sdim  unsigned Register = GPRDecoderTable[RegNo];
1133288943Sdim  Inst.addOperand(MCOperand::createReg(Register));
1134226633Sdim  return MCDisassembler::Success;
1135226633Sdim}
1136226633Sdim
1137353358Sdimstatic DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1138353358Sdim                                               uint64_t Address,
1139353358Sdim                                               const void *Decoder) {
1140353358Sdim  if (RegNo > 15)
1141353358Sdim    return MCDisassembler::Fail;
1142353358Sdim
1143353358Sdim  unsigned Register = CLRMGPRDecoderTable[RegNo];
1144353358Sdim  if (Register == 0)
1145353358Sdim    return MCDisassembler::Fail;
1146353358Sdim
1147353358Sdim  Inst.addOperand(MCOperand::createReg(Register));
1148353358Sdim  return MCDisassembler::Success;
1149353358Sdim}
1150353358Sdim
1151226633Sdimstatic DecodeStatus
1152234353SdimDecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
1153226633Sdim                           uint64_t Address, const void *Decoder) {
1154234353Sdim  DecodeStatus S = MCDisassembler::Success;
1155296417Sdim
1156341825Sdim  if (RegNo == 15)
1157234353Sdim    S = MCDisassembler::SoftFail;
1158234353Sdim
1159234353Sdim  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1160234353Sdim
1161234353Sdim  return S;
1162226633Sdim}
1163226633Sdim
1164261991Sdimstatic DecodeStatus
1165261991SdimDecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo,
1166261991Sdim                               uint64_t Address, const void *Decoder) {
1167261991Sdim  DecodeStatus S = MCDisassembler::Success;
1168261991Sdim
1169261991Sdim  if (RegNo == 15)
1170261991Sdim  {
1171288943Sdim    Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
1172261991Sdim    return MCDisassembler::Success;
1173261991Sdim  }
1174261991Sdim
1175261991Sdim  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1176261991Sdim  return S;
1177261991Sdim}
1178261991Sdim
1179353358Sdimstatic DecodeStatus
1180353358SdimDecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo,
1181353358Sdim                             uint64_t Address, const void *Decoder) {
1182353358Sdim  DecodeStatus S = MCDisassembler::Success;
1183353358Sdim
1184353358Sdim  if (RegNo == 15)
1185353358Sdim  {
1186353358Sdim    Inst.addOperand(MCOperand::createReg(ARM::ZR));
1187353358Sdim    return MCDisassembler::Success;
1188353358Sdim  }
1189353358Sdim
1190353358Sdim  if (RegNo == 13)
1191353358Sdim    Check(S, MCDisassembler::SoftFail);
1192353358Sdim
1193353358Sdim  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1194353358Sdim  return S;
1195353358Sdim}
1196353358Sdim
1197353358Sdimstatic DecodeStatus
1198353358SdimDecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo,
1199353358Sdim                                 uint64_t Address, const void *Decoder) {
1200353358Sdim  DecodeStatus S = MCDisassembler::Success;
1201353358Sdim  if (RegNo == 13)
1202353358Sdim    return MCDisassembler::Fail;
1203353358Sdim  Check(S, DecodeGPRwithZRRegisterClass(Inst, RegNo, Address, Decoder));
1204353358Sdim  return S;
1205353358Sdim}
1206353358Sdim
1207234353Sdimstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1208226633Sdim                                   uint64_t Address, const void *Decoder) {
1209226633Sdim  if (RegNo > 7)
1210226633Sdim    return MCDisassembler::Fail;
1211226633Sdim  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
1212226633Sdim}
1213226633Sdim
1214261991Sdimstatic const uint16_t GPRPairDecoderTable[] = {
1215261991Sdim  ARM::R0_R1, ARM::R2_R3,   ARM::R4_R5,  ARM::R6_R7,
1216261991Sdim  ARM::R8_R9, ARM::R10_R11, ARM::R12_SP
1217261991Sdim};
1218261991Sdim
1219261991Sdimstatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
1220261991Sdim                                   uint64_t Address, const void *Decoder) {
1221261991Sdim  DecodeStatus S = MCDisassembler::Success;
1222261991Sdim
1223261991Sdim  if (RegNo > 13)
1224261991Sdim    return MCDisassembler::Fail;
1225261991Sdim
1226261991Sdim  if ((RegNo & 1) || RegNo == 0xe)
1227261991Sdim     S = MCDisassembler::SoftFail;
1228261991Sdim
1229261991Sdim  unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
1230288943Sdim  Inst.addOperand(MCOperand::createReg(RegisterPair));
1231261991Sdim  return S;
1232261991Sdim}
1233261991Sdim
1234360784Sdimstatic DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
1235360784Sdim                                             uint64_t Address,
1236360784Sdim                                             const void *Decoder) {
1237360784Sdim  if (RegNo != 13)
1238360784Sdim    return MCDisassembler::Fail;
1239360784Sdim
1240360784Sdim  unsigned Register = GPRDecoderTable[RegNo];
1241360784Sdim  Inst.addOperand(MCOperand::createReg(Register));
1242360784Sdim  return MCDisassembler::Success;
1243360784Sdim}
1244360784Sdim
1245234353Sdimstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1246226633Sdim                                   uint64_t Address, const void *Decoder) {
1247226633Sdim  unsigned Register = 0;
1248226633Sdim  switch (RegNo) {
1249226633Sdim    case 0:
1250226633Sdim      Register = ARM::R0;
1251206124Srdivacky      break;
1252226633Sdim    case 1:
1253226633Sdim      Register = ARM::R1;
1254226633Sdim      break;
1255226633Sdim    case 2:
1256226633Sdim      Register = ARM::R2;
1257226633Sdim      break;
1258206124Srdivacky    case 3:
1259226633Sdim      Register = ARM::R3;
1260206124Srdivacky      break;
1261226633Sdim    case 9:
1262226633Sdim      Register = ARM::R9;
1263226633Sdim      break;
1264226633Sdim    case 12:
1265226633Sdim      Register = ARM::R12;
1266226633Sdim      break;
1267206124Srdivacky    default:
1268226633Sdim      return MCDisassembler::Fail;
1269206124Srdivacky    }
1270226633Sdim
1271288943Sdim  Inst.addOperand(MCOperand::createReg(Register));
1272226633Sdim  return MCDisassembler::Success;
1273226633Sdim}
1274226633Sdim
1275234353Sdimstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1276226633Sdim                                   uint64_t Address, const void *Decoder) {
1277261991Sdim  DecodeStatus S = MCDisassembler::Success;
1278296417Sdim
1279296417Sdim  const FeatureBitset &featureBits =
1280296417Sdim    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
1281296417Sdim
1282296417Sdim  if ((RegNo == 13 && !featureBits[ARM::HasV8Ops]) || RegNo == 15)
1283261991Sdim    S = MCDisassembler::SoftFail;
1284296417Sdim
1285261991Sdim  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1286261991Sdim  return S;
1287226633Sdim}
1288226633Sdim
1289234353Sdimstatic const uint16_t SPRDecoderTable[] = {
1290226633Sdim     ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
1291226633Sdim     ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
1292226633Sdim     ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
1293226633Sdim    ARM::S12, ARM::S13, ARM::S14, ARM::S15,
1294226633Sdim    ARM::S16, ARM::S17, ARM::S18, ARM::S19,
1295226633Sdim    ARM::S20, ARM::S21, ARM::S22, ARM::S23,
1296226633Sdim    ARM::S24, ARM::S25, ARM::S26, ARM::S27,
1297226633Sdim    ARM::S28, ARM::S29, ARM::S30, ARM::S31
1298226633Sdim};
1299226633Sdim
1300234353Sdimstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
1301226633Sdim                                   uint64_t Address, const void *Decoder) {
1302226633Sdim  if (RegNo > 31)
1303226633Sdim    return MCDisassembler::Fail;
1304226633Sdim
1305226633Sdim  unsigned Register = SPRDecoderTable[RegNo];
1306288943Sdim  Inst.addOperand(MCOperand::createReg(Register));
1307226633Sdim  return MCDisassembler::Success;
1308226633Sdim}
1309226633Sdim
1310341825Sdimstatic DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
1311341825Sdim                                   uint64_t Address, const void *Decoder) {
1312341825Sdim  return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
1313341825Sdim}
1314341825Sdim
1315234353Sdimstatic const uint16_t DPRDecoderTable[] = {
1316226633Sdim     ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
1317226633Sdim     ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
1318226633Sdim     ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
1319226633Sdim    ARM::D12, ARM::D13, ARM::D14, ARM::D15,
1320226633Sdim    ARM::D16, ARM::D17, ARM::D18, ARM::D19,
1321226633Sdim    ARM::D20, ARM::D21, ARM::D22, ARM::D23,
1322226633Sdim    ARM::D24, ARM::D25, ARM::D26, ARM::D27,
1323226633Sdim    ARM::D28, ARM::D29, ARM::D30, ARM::D31
1324226633Sdim};
1325226633Sdim
1326234353Sdimstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
1327226633Sdim                                   uint64_t Address, const void *Decoder) {
1328288943Sdim  const FeatureBitset &featureBits =
1329288943Sdim    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
1330280031Sdim
1331353358Sdim  bool hasD32 = featureBits[ARM::FeatureD32];
1332288943Sdim
1333353358Sdim  if (RegNo > 31 || (!hasD32 && RegNo > 15))
1334226633Sdim    return MCDisassembler::Fail;
1335226633Sdim
1336226633Sdim  unsigned Register = DPRDecoderTable[RegNo];
1337288943Sdim  Inst.addOperand(MCOperand::createReg(Register));
1338226633Sdim  return MCDisassembler::Success;
1339226633Sdim}
1340226633Sdim
1341234353Sdimstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1342226633Sdim                                   uint64_t Address, const void *Decoder) {
1343226633Sdim  if (RegNo > 7)
1344226633Sdim    return MCDisassembler::Fail;
1345226633Sdim  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
1346226633Sdim}
1347226633Sdim
1348353358Sdimstatic DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1349353358Sdim                                   uint64_t Address, const void *Decoder) {
1350353358Sdim  if (RegNo > 15)
1351353358Sdim    return MCDisassembler::Fail;
1352353358Sdim  return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
1353353358Sdim}
1354353358Sdim
1355226633Sdimstatic DecodeStatus
1356234353SdimDecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
1357226633Sdim                            uint64_t Address, const void *Decoder) {
1358226633Sdim  if (RegNo > 15)
1359226633Sdim    return MCDisassembler::Fail;
1360226633Sdim  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
1361226633Sdim}
1362226633Sdim
1363234353Sdimstatic const uint16_t QPRDecoderTable[] = {
1364226633Sdim     ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
1365226633Sdim     ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
1366226633Sdim     ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
1367226633Sdim    ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
1368226633Sdim};
1369226633Sdim
1370234353Sdimstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
1371226633Sdim                                   uint64_t Address, const void *Decoder) {
1372261991Sdim  if (RegNo > 31 || (RegNo & 1) != 0)
1373226633Sdim    return MCDisassembler::Fail;
1374226633Sdim  RegNo >>= 1;
1375226633Sdim
1376226633Sdim  unsigned Register = QPRDecoderTable[RegNo];
1377288943Sdim  Inst.addOperand(MCOperand::createReg(Register));
1378226633Sdim  return MCDisassembler::Success;
1379226633Sdim}
1380226633Sdim
1381234353Sdimstatic const uint16_t DPairDecoderTable[] = {
1382234353Sdim  ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
1383234353Sdim  ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
1384234353Sdim  ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
1385234353Sdim  ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
1386234353Sdim  ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
1387234353Sdim  ARM::Q15
1388234353Sdim};
1389234353Sdim
1390234353Sdimstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
1391234353Sdim                                   uint64_t Address, const void *Decoder) {
1392234353Sdim  if (RegNo > 30)
1393234353Sdim    return MCDisassembler::Fail;
1394234353Sdim
1395234353Sdim  unsigned Register = DPairDecoderTable[RegNo];
1396288943Sdim  Inst.addOperand(MCOperand::createReg(Register));
1397234353Sdim  return MCDisassembler::Success;
1398234353Sdim}
1399234353Sdim
1400234353Sdimstatic const uint16_t DPairSpacedDecoderTable[] = {
1401234353Sdim  ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
1402234353Sdim  ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
1403234353Sdim  ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
1404234353Sdim  ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
1405234353Sdim  ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
1406234353Sdim  ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
1407234353Sdim  ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
1408234353Sdim  ARM::D28_D30, ARM::D29_D31
1409234353Sdim};
1410234353Sdim
1411234353Sdimstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
1412234353Sdim                                                   unsigned RegNo,
1413234353Sdim                                                   uint64_t Address,
1414234353Sdim                                                   const void *Decoder) {
1415234353Sdim  if (RegNo > 29)
1416234353Sdim    return MCDisassembler::Fail;
1417234353Sdim
1418234353Sdim  unsigned Register = DPairSpacedDecoderTable[RegNo];
1419288943Sdim  Inst.addOperand(MCOperand::createReg(Register));
1420234353Sdim  return MCDisassembler::Success;
1421234353Sdim}
1422234353Sdim
1423234353Sdimstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
1424226633Sdim                               uint64_t Address, const void *Decoder) {
1425353358Sdim  DecodeStatus S = MCDisassembler::Success;
1426226633Sdim  if (Val == 0xF) return MCDisassembler::Fail;
1427226633Sdim  // AL predicate is not allowed on Thumb1 branches.
1428226633Sdim  if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
1429226633Sdim    return MCDisassembler::Fail;
1430353358Sdim  if (Val != ARMCC::AL && !ARMInsts[Inst.getOpcode()].isPredicable())
1431353358Sdim    Check(S, MCDisassembler::SoftFail);
1432288943Sdim  Inst.addOperand(MCOperand::createImm(Val));
1433226633Sdim  if (Val == ARMCC::AL) {
1434288943Sdim    Inst.addOperand(MCOperand::createReg(0));
1435226633Sdim  } else
1436288943Sdim    Inst.addOperand(MCOperand::createReg(ARM::CPSR));
1437353358Sdim  return S;
1438226633Sdim}
1439226633Sdim
1440234353Sdimstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
1441226633Sdim                               uint64_t Address, const void *Decoder) {
1442226633Sdim  if (Val)
1443288943Sdim    Inst.addOperand(MCOperand::createReg(ARM::CPSR));
1444226633Sdim  else
1445288943Sdim    Inst.addOperand(MCOperand::createReg(0));
1446226633Sdim  return MCDisassembler::Success;
1447226633Sdim}
1448226633Sdim
1449234353Sdimstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
1450226633Sdim                               uint64_t Address, const void *Decoder) {
1451226633Sdim  DecodeStatus S = MCDisassembler::Success;
1452226633Sdim
1453239462Sdim  unsigned Rm = fieldFromInstruction(Val, 0, 4);
1454239462Sdim  unsigned type = fieldFromInstruction(Val, 5, 2);
1455239462Sdim  unsigned imm = fieldFromInstruction(Val, 7, 5);
1456226633Sdim
1457226633Sdim  // Register-immediate
1458296417Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
1459226633Sdim    return MCDisassembler::Fail;
1460226633Sdim
1461226633Sdim  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1462226633Sdim  switch (type) {
1463226633Sdim    case 0:
1464226633Sdim      Shift = ARM_AM::lsl;
1465226633Sdim      break;
1466226633Sdim    case 1:
1467226633Sdim      Shift = ARM_AM::lsr;
1468226633Sdim      break;
1469226633Sdim    case 2:
1470226633Sdim      Shift = ARM_AM::asr;
1471226633Sdim      break;
1472226633Sdim    case 3:
1473226633Sdim      Shift = ARM_AM::ror;
1474226633Sdim      break;
1475206124Srdivacky  }
1476206124Srdivacky
1477226633Sdim  if (Shift == ARM_AM::ror && imm == 0)
1478226633Sdim    Shift = ARM_AM::rrx;
1479226633Sdim
1480226633Sdim  unsigned Op = Shift | (imm << 3);
1481288943Sdim  Inst.addOperand(MCOperand::createImm(Op));
1482226633Sdim
1483226633Sdim  return S;
1484226633Sdim}
1485226633Sdim
1486234353Sdimstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
1487226633Sdim                               uint64_t Address, const void *Decoder) {
1488226633Sdim  DecodeStatus S = MCDisassembler::Success;
1489226633Sdim
1490239462Sdim  unsigned Rm = fieldFromInstruction(Val, 0, 4);
1491239462Sdim  unsigned type = fieldFromInstruction(Val, 5, 2);
1492239462Sdim  unsigned Rs = fieldFromInstruction(Val, 8, 4);
1493226633Sdim
1494226633Sdim  // Register-register
1495226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1496226633Sdim    return MCDisassembler::Fail;
1497226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
1498226633Sdim    return MCDisassembler::Fail;
1499226633Sdim
1500226633Sdim  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1501226633Sdim  switch (type) {
1502226633Sdim    case 0:
1503226633Sdim      Shift = ARM_AM::lsl;
1504206124Srdivacky      break;
1505226633Sdim    case 1:
1506226633Sdim      Shift = ARM_AM::lsr;
1507206124Srdivacky      break;
1508226633Sdim    case 2:
1509226633Sdim      Shift = ARM_AM::asr;
1510206124Srdivacky      break;
1511226633Sdim    case 3:
1512226633Sdim      Shift = ARM_AM::ror;
1513226633Sdim      break;
1514226633Sdim  }
1515226633Sdim
1516288943Sdim  Inst.addOperand(MCOperand::createImm(Shift));
1517226633Sdim
1518226633Sdim  return S;
1519226633Sdim}
1520226633Sdim
1521234353Sdimstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
1522226633Sdim                                 uint64_t Address, const void *Decoder) {
1523226633Sdim  DecodeStatus S = MCDisassembler::Success;
1524226633Sdim
1525261991Sdim  bool NeedDisjointWriteback = false;
1526261991Sdim  unsigned WritebackReg = 0;
1527353358Sdim  bool CLRM = false;
1528226633Sdim  switch (Inst.getOpcode()) {
1529261991Sdim  default:
1530261991Sdim    break;
1531261991Sdim  case ARM::LDMIA_UPD:
1532261991Sdim  case ARM::LDMDB_UPD:
1533261991Sdim  case ARM::LDMIB_UPD:
1534261991Sdim  case ARM::LDMDA_UPD:
1535261991Sdim  case ARM::t2LDMIA_UPD:
1536261991Sdim  case ARM::t2LDMDB_UPD:
1537261991Sdim  case ARM::t2STMIA_UPD:
1538261991Sdim  case ARM::t2STMDB_UPD:
1539261991Sdim    NeedDisjointWriteback = true;
1540261991Sdim    WritebackReg = Inst.getOperand(0).getReg();
1541261991Sdim    break;
1542353358Sdim  case ARM::t2CLRM:
1543353358Sdim    CLRM = true;
1544353358Sdim    break;
1545226633Sdim  }
1546226633Sdim
1547226633Sdim  // Empty register lists are not allowed.
1548261991Sdim  if (Val == 0) return MCDisassembler::Fail;
1549226633Sdim  for (unsigned i = 0; i < 16; ++i) {
1550226633Sdim    if (Val & (1 << i)) {
1551353358Sdim      if (CLRM) {
1552353358Sdim        if (!Check(S, DecodeCLRMGPRRegisterClass(Inst, i, Address, Decoder))) {
1553353358Sdim          return MCDisassembler::Fail;
1554353358Sdim        }
1555353358Sdim      } else {
1556353358Sdim        if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
1557353358Sdim          return MCDisassembler::Fail;
1558353358Sdim        // Writeback not allowed if Rn is in the target list.
1559353358Sdim        if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg())
1560353358Sdim          Check(S, MCDisassembler::SoftFail);
1561353358Sdim      }
1562206124Srdivacky    }
1563206124Srdivacky  }
1564206124Srdivacky
1565226633Sdim  return S;
1566226633Sdim}
1567226633Sdim
1568234353Sdimstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
1569226633Sdim                                 uint64_t Address, const void *Decoder) {
1570226633Sdim  DecodeStatus S = MCDisassembler::Success;
1571226633Sdim
1572239462Sdim  unsigned Vd = fieldFromInstruction(Val, 8, 5);
1573239462Sdim  unsigned regs = fieldFromInstruction(Val, 0, 8);
1574226633Sdim
1575261991Sdim  // In case of unpredictable encoding, tweak the operands.
1576261991Sdim  if (regs == 0 || (Vd + regs) > 32) {
1577261991Sdim    regs = Vd + regs > 32 ? 32 - Vd : regs;
1578261991Sdim    regs = std::max( 1u, regs);
1579261991Sdim    S = MCDisassembler::SoftFail;
1580261991Sdim  }
1581261991Sdim
1582226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
1583226633Sdim    return MCDisassembler::Fail;
1584226633Sdim  for (unsigned i = 0; i < (regs - 1); ++i) {
1585226633Sdim    if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1586226633Sdim      return MCDisassembler::Fail;
1587226633Sdim  }
1588226633Sdim
1589226633Sdim  return S;
1590226633Sdim}
1591226633Sdim
1592234353Sdimstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
1593226633Sdim                                 uint64_t Address, const void *Decoder) {
1594226633Sdim  DecodeStatus S = MCDisassembler::Success;
1595226633Sdim
1596239462Sdim  unsigned Vd = fieldFromInstruction(Val, 8, 5);
1597261991Sdim  unsigned regs = fieldFromInstruction(Val, 1, 7);
1598226633Sdim
1599261991Sdim  // In case of unpredictable encoding, tweak the operands.
1600261991Sdim  if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
1601261991Sdim    regs = Vd + regs > 32 ? 32 - Vd : regs;
1602261991Sdim    regs = std::max( 1u, regs);
1603261991Sdim    regs = std::min(16u, regs);
1604261991Sdim    S = MCDisassembler::SoftFail;
1605261991Sdim  }
1606239462Sdim
1607226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
1608226633Sdim      return MCDisassembler::Fail;
1609226633Sdim  for (unsigned i = 0; i < (regs - 1); ++i) {
1610226633Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1611226633Sdim      return MCDisassembler::Fail;
1612226633Sdim  }
1613226633Sdim
1614226633Sdim  return S;
1615226633Sdim}
1616226633Sdim
1617234353Sdimstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
1618226633Sdim                                      uint64_t Address, const void *Decoder) {
1619226633Sdim  // This operand encodes a mask of contiguous zeros between a specified MSB
1620226633Sdim  // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
1621226633Sdim  // the mask of all bits LSB-and-lower, and then xor them to create
1622226633Sdim  // the mask of that's all ones on [msb, lsb].  Finally we not it to
1623226633Sdim  // create the final mask.
1624239462Sdim  unsigned msb = fieldFromInstruction(Val, 5, 5);
1625239462Sdim  unsigned lsb = fieldFromInstruction(Val, 0, 5);
1626226633Sdim
1627226633Sdim  DecodeStatus S = MCDisassembler::Success;
1628249423Sdim  if (lsb > msb) {
1629249423Sdim    Check(S, MCDisassembler::SoftFail);
1630249423Sdim    // The check above will cause the warning for the "potentially undefined
1631249423Sdim    // instruction encoding" but we can't build a bad MCOperand value here
1632249423Sdim    // with a lsb > msb or else printing the MCInst will cause a crash.
1633249423Sdim    lsb = msb;
1634249423Sdim  }
1635226633Sdim
1636226633Sdim  uint32_t msb_mask = 0xFFFFFFFF;
1637226633Sdim  if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
1638226633Sdim  uint32_t lsb_mask = (1U << lsb) - 1;
1639226633Sdim
1640288943Sdim  Inst.addOperand(MCOperand::createImm(~(msb_mask ^ lsb_mask)));
1641226633Sdim  return S;
1642226633Sdim}
1643226633Sdim
1644234353Sdimstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
1645226633Sdim                                  uint64_t Address, const void *Decoder) {
1646226633Sdim  DecodeStatus S = MCDisassembler::Success;
1647226633Sdim
1648239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1649239462Sdim  unsigned CRd = fieldFromInstruction(Insn, 12, 4);
1650239462Sdim  unsigned coproc = fieldFromInstruction(Insn, 8, 4);
1651239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 8);
1652239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1653239462Sdim  unsigned U = fieldFromInstruction(Insn, 23, 1);
1654353358Sdim  const FeatureBitset &featureBits =
1655353358Sdim    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
1656226633Sdim
1657226633Sdim  switch (Inst.getOpcode()) {
1658226633Sdim    case ARM::LDC_OFFSET:
1659226633Sdim    case ARM::LDC_PRE:
1660226633Sdim    case ARM::LDC_POST:
1661226633Sdim    case ARM::LDC_OPTION:
1662226633Sdim    case ARM::LDCL_OFFSET:
1663226633Sdim    case ARM::LDCL_PRE:
1664226633Sdim    case ARM::LDCL_POST:
1665226633Sdim    case ARM::LDCL_OPTION:
1666226633Sdim    case ARM::STC_OFFSET:
1667226633Sdim    case ARM::STC_PRE:
1668226633Sdim    case ARM::STC_POST:
1669226633Sdim    case ARM::STC_OPTION:
1670226633Sdim    case ARM::STCL_OFFSET:
1671226633Sdim    case ARM::STCL_PRE:
1672226633Sdim    case ARM::STCL_POST:
1673226633Sdim    case ARM::STCL_OPTION:
1674226633Sdim    case ARM::t2LDC_OFFSET:
1675226633Sdim    case ARM::t2LDC_PRE:
1676226633Sdim    case ARM::t2LDC_POST:
1677226633Sdim    case ARM::t2LDC_OPTION:
1678226633Sdim    case ARM::t2LDCL_OFFSET:
1679226633Sdim    case ARM::t2LDCL_PRE:
1680226633Sdim    case ARM::t2LDCL_POST:
1681226633Sdim    case ARM::t2LDCL_OPTION:
1682226633Sdim    case ARM::t2STC_OFFSET:
1683226633Sdim    case ARM::t2STC_PRE:
1684226633Sdim    case ARM::t2STC_POST:
1685226633Sdim    case ARM::t2STC_OPTION:
1686226633Sdim    case ARM::t2STCL_OFFSET:
1687226633Sdim    case ARM::t2STCL_PRE:
1688226633Sdim    case ARM::t2STCL_POST:
1689226633Sdim    case ARM::t2STCL_OPTION:
1690353358Sdim    case ARM::t2LDC2_OFFSET:
1691353358Sdim    case ARM::t2LDC2L_OFFSET:
1692353358Sdim    case ARM::t2LDC2_PRE:
1693353358Sdim    case ARM::t2LDC2L_PRE:
1694353358Sdim    case ARM::t2STC2_OFFSET:
1695353358Sdim    case ARM::t2STC2L_OFFSET:
1696353358Sdim    case ARM::t2STC2_PRE:
1697353358Sdim    case ARM::t2STC2L_PRE:
1698353358Sdim    case ARM::LDC2_OFFSET:
1699353358Sdim    case ARM::LDC2L_OFFSET:
1700353358Sdim    case ARM::LDC2_PRE:
1701353358Sdim    case ARM::LDC2L_PRE:
1702353358Sdim    case ARM::STC2_OFFSET:
1703353358Sdim    case ARM::STC2L_OFFSET:
1704353358Sdim    case ARM::STC2_PRE:
1705353358Sdim    case ARM::STC2L_PRE:
1706353358Sdim    case ARM::t2LDC2_OPTION:
1707353358Sdim    case ARM::t2STC2_OPTION:
1708353358Sdim    case ARM::t2LDC2_POST:
1709353358Sdim    case ARM::t2LDC2L_POST:
1710353358Sdim    case ARM::t2STC2_POST:
1711353358Sdim    case ARM::t2STC2L_POST:
1712353358Sdim    case ARM::LDC2_POST:
1713353358Sdim    case ARM::LDC2L_POST:
1714353358Sdim    case ARM::STC2_POST:
1715353358Sdim    case ARM::STC2L_POST:
1716353358Sdim      if (coproc == 0xA || coproc == 0xB ||
1717353358Sdim          (featureBits[ARM::HasV8_1MMainlineOps] &&
1718353358Sdim           (coproc == 0x8 || coproc == 0x9 || coproc == 0xA || coproc == 0xB ||
1719353358Sdim            coproc == 0xE || coproc == 0xF)))
1720226633Sdim        return MCDisassembler::Fail;
1721206124Srdivacky      break;
1722226633Sdim    default:
1723226633Sdim      break;
1724226633Sdim  }
1725226633Sdim
1726288943Sdim  if (featureBits[ARM::HasV8Ops] && (coproc != 14))
1727261991Sdim    return MCDisassembler::Fail;
1728261991Sdim
1729288943Sdim  Inst.addOperand(MCOperand::createImm(coproc));
1730288943Sdim  Inst.addOperand(MCOperand::createImm(CRd));
1731226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1732226633Sdim    return MCDisassembler::Fail;
1733226633Sdim
1734226633Sdim  switch (Inst.getOpcode()) {
1735226633Sdim    case ARM::t2LDC2_OFFSET:
1736226633Sdim    case ARM::t2LDC2L_OFFSET:
1737226633Sdim    case ARM::t2LDC2_PRE:
1738226633Sdim    case ARM::t2LDC2L_PRE:
1739226633Sdim    case ARM::t2STC2_OFFSET:
1740226633Sdim    case ARM::t2STC2L_OFFSET:
1741226633Sdim    case ARM::t2STC2_PRE:
1742226633Sdim    case ARM::t2STC2L_PRE:
1743226633Sdim    case ARM::LDC2_OFFSET:
1744226633Sdim    case ARM::LDC2L_OFFSET:
1745226633Sdim    case ARM::LDC2_PRE:
1746226633Sdim    case ARM::LDC2L_PRE:
1747226633Sdim    case ARM::STC2_OFFSET:
1748226633Sdim    case ARM::STC2L_OFFSET:
1749226633Sdim    case ARM::STC2_PRE:
1750226633Sdim    case ARM::STC2L_PRE:
1751226633Sdim    case ARM::t2LDC_OFFSET:
1752226633Sdim    case ARM::t2LDCL_OFFSET:
1753226633Sdim    case ARM::t2LDC_PRE:
1754226633Sdim    case ARM::t2LDCL_PRE:
1755226633Sdim    case ARM::t2STC_OFFSET:
1756226633Sdim    case ARM::t2STCL_OFFSET:
1757226633Sdim    case ARM::t2STC_PRE:
1758226633Sdim    case ARM::t2STCL_PRE:
1759226633Sdim    case ARM::LDC_OFFSET:
1760226633Sdim    case ARM::LDCL_OFFSET:
1761226633Sdim    case ARM::LDC_PRE:
1762226633Sdim    case ARM::LDCL_PRE:
1763226633Sdim    case ARM::STC_OFFSET:
1764226633Sdim    case ARM::STCL_OFFSET:
1765226633Sdim    case ARM::STC_PRE:
1766226633Sdim    case ARM::STCL_PRE:
1767226633Sdim      imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
1768288943Sdim      Inst.addOperand(MCOperand::createImm(imm));
1769226633Sdim      break;
1770226633Sdim    case ARM::t2LDC2_POST:
1771226633Sdim    case ARM::t2LDC2L_POST:
1772226633Sdim    case ARM::t2STC2_POST:
1773226633Sdim    case ARM::t2STC2L_POST:
1774226633Sdim    case ARM::LDC2_POST:
1775226633Sdim    case ARM::LDC2L_POST:
1776226633Sdim    case ARM::STC2_POST:
1777226633Sdim    case ARM::STC2L_POST:
1778226633Sdim    case ARM::t2LDC_POST:
1779226633Sdim    case ARM::t2LDCL_POST:
1780226633Sdim    case ARM::t2STC_POST:
1781226633Sdim    case ARM::t2STCL_POST:
1782226633Sdim    case ARM::LDC_POST:
1783226633Sdim    case ARM::LDCL_POST:
1784226633Sdim    case ARM::STC_POST:
1785226633Sdim    case ARM::STCL_POST:
1786226633Sdim      imm |= U << 8;
1787314564Sdim      LLVM_FALLTHROUGH;
1788226633Sdim    default:
1789226633Sdim      // The 'option' variant doesn't encode 'U' in the immediate since
1790226633Sdim      // the immediate is unsigned [0,255].
1791288943Sdim      Inst.addOperand(MCOperand::createImm(imm));
1792226633Sdim      break;
1793226633Sdim  }
1794226633Sdim
1795226633Sdim  switch (Inst.getOpcode()) {
1796226633Sdim    case ARM::LDC_OFFSET:
1797226633Sdim    case ARM::LDC_PRE:
1798226633Sdim    case ARM::LDC_POST:
1799226633Sdim    case ARM::LDC_OPTION:
1800226633Sdim    case ARM::LDCL_OFFSET:
1801226633Sdim    case ARM::LDCL_PRE:
1802226633Sdim    case ARM::LDCL_POST:
1803226633Sdim    case ARM::LDCL_OPTION:
1804226633Sdim    case ARM::STC_OFFSET:
1805226633Sdim    case ARM::STC_PRE:
1806226633Sdim    case ARM::STC_POST:
1807226633Sdim    case ARM::STC_OPTION:
1808226633Sdim    case ARM::STCL_OFFSET:
1809226633Sdim    case ARM::STCL_PRE:
1810226633Sdim    case ARM::STCL_POST:
1811226633Sdim    case ARM::STCL_OPTION:
1812226633Sdim      if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1813226633Sdim        return MCDisassembler::Fail;
1814226633Sdim      break;
1815226633Sdim    default:
1816226633Sdim      break;
1817226633Sdim  }
1818226633Sdim
1819226633Sdim  return S;
1820226633Sdim}
1821226633Sdim
1822226633Sdimstatic DecodeStatus
1823234353SdimDecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn,
1824226633Sdim                              uint64_t Address, const void *Decoder) {
1825226633Sdim  DecodeStatus S = MCDisassembler::Success;
1826226633Sdim
1827239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1828239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1829239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1830239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
1831239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1832239462Sdim  unsigned reg = fieldFromInstruction(Insn, 25, 1);
1833239462Sdim  unsigned P = fieldFromInstruction(Insn, 24, 1);
1834239462Sdim  unsigned W = fieldFromInstruction(Insn, 21, 1);
1835226633Sdim
1836226633Sdim  // On stores, the writeback operand precedes Rt.
1837226633Sdim  switch (Inst.getOpcode()) {
1838226633Sdim    case ARM::STR_POST_IMM:
1839226633Sdim    case ARM::STR_POST_REG:
1840226633Sdim    case ARM::STRB_POST_IMM:
1841226633Sdim    case ARM::STRB_POST_REG:
1842226633Sdim    case ARM::STRT_POST_REG:
1843226633Sdim    case ARM::STRT_POST_IMM:
1844226633Sdim    case ARM::STRBT_POST_REG:
1845226633Sdim    case ARM::STRBT_POST_IMM:
1846226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1847226633Sdim        return MCDisassembler::Fail;
1848226633Sdim      break;
1849226633Sdim    default:
1850226633Sdim      break;
1851226633Sdim  }
1852226633Sdim
1853226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1854226633Sdim    return MCDisassembler::Fail;
1855226633Sdim
1856226633Sdim  // On loads, the writeback operand comes after Rt.
1857226633Sdim  switch (Inst.getOpcode()) {
1858226633Sdim    case ARM::LDR_POST_IMM:
1859226633Sdim    case ARM::LDR_POST_REG:
1860226633Sdim    case ARM::LDRB_POST_IMM:
1861226633Sdim    case ARM::LDRB_POST_REG:
1862226633Sdim    case ARM::LDRBT_POST_REG:
1863226633Sdim    case ARM::LDRBT_POST_IMM:
1864226633Sdim    case ARM::LDRT_POST_REG:
1865226633Sdim    case ARM::LDRT_POST_IMM:
1866226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1867226633Sdim        return MCDisassembler::Fail;
1868226633Sdim      break;
1869226633Sdim    default:
1870226633Sdim      break;
1871226633Sdim  }
1872226633Sdim
1873226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1874226633Sdim    return MCDisassembler::Fail;
1875226633Sdim
1876226633Sdim  ARM_AM::AddrOpc Op = ARM_AM::add;
1877239462Sdim  if (!fieldFromInstruction(Insn, 23, 1))
1878226633Sdim    Op = ARM_AM::sub;
1879226633Sdim
1880226633Sdim  bool writeback = (P == 0) || (W == 1);
1881226633Sdim  unsigned idx_mode = 0;
1882226633Sdim  if (P && writeback)
1883226633Sdim    idx_mode = ARMII::IndexModePre;
1884226633Sdim  else if (!P && writeback)
1885226633Sdim    idx_mode = ARMII::IndexModePost;
1886226633Sdim
1887226633Sdim  if (writeback && (Rn == 15 || Rn == Rt))
1888226633Sdim    S = MCDisassembler::SoftFail; // UNPREDICTABLE
1889226633Sdim
1890226633Sdim  if (reg) {
1891226633Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1892226633Sdim      return MCDisassembler::Fail;
1893226633Sdim    ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
1894239462Sdim    switch( fieldFromInstruction(Insn, 5, 2)) {
1895226633Sdim      case 0:
1896226633Sdim        Opc = ARM_AM::lsl;
1897226633Sdim        break;
1898226633Sdim      case 1:
1899226633Sdim        Opc = ARM_AM::lsr;
1900226633Sdim        break;
1901226633Sdim      case 2:
1902226633Sdim        Opc = ARM_AM::asr;
1903226633Sdim        break;
1904226633Sdim      case 3:
1905226633Sdim        Opc = ARM_AM::ror;
1906226633Sdim        break;
1907206124Srdivacky      default:
1908226633Sdim        return MCDisassembler::Fail;
1909226633Sdim    }
1910239462Sdim    unsigned amt = fieldFromInstruction(Insn, 7, 5);
1911243830Sdim    if (Opc == ARM_AM::ror && amt == 0)
1912243830Sdim      Opc = ARM_AM::rrx;
1913226633Sdim    unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
1914226633Sdim
1915288943Sdim    Inst.addOperand(MCOperand::createImm(imm));
1916226633Sdim  } else {
1917288943Sdim    Inst.addOperand(MCOperand::createReg(0));
1918226633Sdim    unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
1919288943Sdim    Inst.addOperand(MCOperand::createImm(tmp));
1920226633Sdim  }
1921226633Sdim
1922226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1923226633Sdim    return MCDisassembler::Fail;
1924226633Sdim
1925226633Sdim  return S;
1926226633Sdim}
1927226633Sdim
1928234353Sdimstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
1929226633Sdim                                  uint64_t Address, const void *Decoder) {
1930226633Sdim  DecodeStatus S = MCDisassembler::Success;
1931226633Sdim
1932239462Sdim  unsigned Rn = fieldFromInstruction(Val, 13, 4);
1933239462Sdim  unsigned Rm = fieldFromInstruction(Val,  0, 4);
1934239462Sdim  unsigned type = fieldFromInstruction(Val, 5, 2);
1935239462Sdim  unsigned imm = fieldFromInstruction(Val, 7, 5);
1936239462Sdim  unsigned U = fieldFromInstruction(Val, 12, 1);
1937226633Sdim
1938226633Sdim  ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
1939226633Sdim  switch (type) {
1940226633Sdim    case 0:
1941226633Sdim      ShOp = ARM_AM::lsl;
1942206124Srdivacky      break;
1943226633Sdim    case 1:
1944226633Sdim      ShOp = ARM_AM::lsr;
1945226633Sdim      break;
1946226633Sdim    case 2:
1947226633Sdim      ShOp = ARM_AM::asr;
1948226633Sdim      break;
1949226633Sdim    case 3:
1950226633Sdim      ShOp = ARM_AM::ror;
1951226633Sdim      break;
1952226633Sdim  }
1953226633Sdim
1954243830Sdim  if (ShOp == ARM_AM::ror && imm == 0)
1955243830Sdim    ShOp = ARM_AM::rrx;
1956243830Sdim
1957226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1958226633Sdim    return MCDisassembler::Fail;
1959226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1960226633Sdim    return MCDisassembler::Fail;
1961226633Sdim  unsigned shift;
1962226633Sdim  if (U)
1963226633Sdim    shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
1964226633Sdim  else
1965226633Sdim    shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
1966288943Sdim  Inst.addOperand(MCOperand::createImm(shift));
1967226633Sdim
1968226633Sdim  return S;
1969226633Sdim}
1970226633Sdim
1971226633Sdimstatic DecodeStatus
1972234353SdimDecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
1973226633Sdim                           uint64_t Address, const void *Decoder) {
1974226633Sdim  DecodeStatus S = MCDisassembler::Success;
1975226633Sdim
1976239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1977239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1978239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1979239462Sdim  unsigned type = fieldFromInstruction(Insn, 22, 1);
1980239462Sdim  unsigned imm = fieldFromInstruction(Insn, 8, 4);
1981239462Sdim  unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
1982239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1983239462Sdim  unsigned W = fieldFromInstruction(Insn, 21, 1);
1984239462Sdim  unsigned P = fieldFromInstruction(Insn, 24, 1);
1985234353Sdim  unsigned Rt2 = Rt + 1;
1986226633Sdim
1987226633Sdim  bool writeback = (W == 1) | (P == 0);
1988226633Sdim
1989226633Sdim  // For {LD,ST}RD, Rt must be even, else undefined.
1990226633Sdim  switch (Inst.getOpcode()) {
1991226633Sdim    case ARM::STRD:
1992226633Sdim    case ARM::STRD_PRE:
1993226633Sdim    case ARM::STRD_POST:
1994226633Sdim    case ARM::LDRD:
1995226633Sdim    case ARM::LDRD_PRE:
1996226633Sdim    case ARM::LDRD_POST:
1997234353Sdim      if (Rt & 0x1) S = MCDisassembler::SoftFail;
1998226633Sdim      break;
1999226633Sdim    default:
2000226633Sdim      break;
2001226633Sdim  }
2002234353Sdim  switch (Inst.getOpcode()) {
2003234353Sdim    case ARM::STRD:
2004234353Sdim    case ARM::STRD_PRE:
2005234353Sdim    case ARM::STRD_POST:
2006234353Sdim      if (P == 0 && W == 1)
2007234353Sdim        S = MCDisassembler::SoftFail;
2008296417Sdim
2009234353Sdim      if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
2010234353Sdim        S = MCDisassembler::SoftFail;
2011234353Sdim      if (type && Rm == 15)
2012234353Sdim        S = MCDisassembler::SoftFail;
2013234353Sdim      if (Rt2 == 15)
2014234353Sdim        S = MCDisassembler::SoftFail;
2015239462Sdim      if (!type && fieldFromInstruction(Insn, 8, 4))
2016234353Sdim        S = MCDisassembler::SoftFail;
2017234353Sdim      break;
2018234353Sdim    case ARM::STRH:
2019234353Sdim    case ARM::STRH_PRE:
2020234353Sdim    case ARM::STRH_POST:
2021234353Sdim      if (Rt == 15)
2022234353Sdim        S = MCDisassembler::SoftFail;
2023234353Sdim      if (writeback && (Rn == 15 || Rn == Rt))
2024234353Sdim        S = MCDisassembler::SoftFail;
2025234353Sdim      if (!type && Rm == 15)
2026234353Sdim        S = MCDisassembler::SoftFail;
2027234353Sdim      break;
2028234353Sdim    case ARM::LDRD:
2029234353Sdim    case ARM::LDRD_PRE:
2030234353Sdim    case ARM::LDRD_POST:
2031321369Sdim      if (type && Rn == 15) {
2032234353Sdim        if (Rt2 == 15)
2033234353Sdim          S = MCDisassembler::SoftFail;
2034234353Sdim        break;
2035234353Sdim      }
2036234353Sdim      if (P == 0 && W == 1)
2037234353Sdim        S = MCDisassembler::SoftFail;
2038234353Sdim      if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
2039234353Sdim        S = MCDisassembler::SoftFail;
2040234353Sdim      if (!type && writeback && Rn == 15)
2041234353Sdim        S = MCDisassembler::SoftFail;
2042234353Sdim      if (writeback && (Rn == Rt || Rn == Rt2))
2043234353Sdim        S = MCDisassembler::SoftFail;
2044234353Sdim      break;
2045234353Sdim    case ARM::LDRH:
2046234353Sdim    case ARM::LDRH_PRE:
2047234353Sdim    case ARM::LDRH_POST:
2048321369Sdim      if (type && Rn == 15) {
2049234353Sdim        if (Rt == 15)
2050234353Sdim          S = MCDisassembler::SoftFail;
2051234353Sdim        break;
2052234353Sdim      }
2053234353Sdim      if (Rt == 15)
2054234353Sdim        S = MCDisassembler::SoftFail;
2055234353Sdim      if (!type && Rm == 15)
2056234353Sdim        S = MCDisassembler::SoftFail;
2057234353Sdim      if (!type && writeback && (Rn == 15 || Rn == Rt))
2058234353Sdim        S = MCDisassembler::SoftFail;
2059234353Sdim      break;
2060234353Sdim    case ARM::LDRSH:
2061234353Sdim    case ARM::LDRSH_PRE:
2062234353Sdim    case ARM::LDRSH_POST:
2063234353Sdim    case ARM::LDRSB:
2064234353Sdim    case ARM::LDRSB_PRE:
2065234353Sdim    case ARM::LDRSB_POST:
2066321369Sdim      if (type && Rn == 15) {
2067234353Sdim        if (Rt == 15)
2068234353Sdim          S = MCDisassembler::SoftFail;
2069234353Sdim        break;
2070234353Sdim      }
2071234353Sdim      if (type && (Rt == 15 || (writeback && Rn == Rt)))
2072234353Sdim        S = MCDisassembler::SoftFail;
2073234353Sdim      if (!type && (Rt == 15 || Rm == 15))
2074234353Sdim        S = MCDisassembler::SoftFail;
2075234353Sdim      if (!type && writeback && (Rn == 15 || Rn == Rt))
2076234353Sdim        S = MCDisassembler::SoftFail;
2077234353Sdim      break;
2078234353Sdim    default:
2079234353Sdim      break;
2080234353Sdim  }
2081226633Sdim
2082226633Sdim  if (writeback) { // Writeback
2083226633Sdim    if (P)
2084226633Sdim      U |= ARMII::IndexModePre << 9;
2085226633Sdim    else
2086226633Sdim      U |= ARMII::IndexModePost << 9;
2087226633Sdim
2088226633Sdim    // On stores, the writeback operand precedes Rt.
2089226633Sdim    switch (Inst.getOpcode()) {
2090226633Sdim    case ARM::STRD:
2091226633Sdim    case ARM::STRD_PRE:
2092226633Sdim    case ARM::STRD_POST:
2093226633Sdim    case ARM::STRH:
2094226633Sdim    case ARM::STRH_PRE:
2095226633Sdim    case ARM::STRH_POST:
2096226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2097226633Sdim        return MCDisassembler::Fail;
2098226633Sdim      break;
2099226633Sdim    default:
2100226633Sdim      break;
2101226633Sdim    }
2102226633Sdim  }
2103226633Sdim
2104226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
2105226633Sdim    return MCDisassembler::Fail;
2106226633Sdim  switch (Inst.getOpcode()) {
2107226633Sdim    case ARM::STRD:
2108226633Sdim    case ARM::STRD_PRE:
2109226633Sdim    case ARM::STRD_POST:
2110226633Sdim    case ARM::LDRD:
2111226633Sdim    case ARM::LDRD_PRE:
2112226633Sdim    case ARM::LDRD_POST:
2113226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
2114226633Sdim        return MCDisassembler::Fail;
2115226633Sdim      break;
2116226633Sdim    default:
2117226633Sdim      break;
2118226633Sdim  }
2119226633Sdim
2120226633Sdim  if (writeback) {
2121226633Sdim    // On loads, the writeback operand comes after Rt.
2122226633Sdim    switch (Inst.getOpcode()) {
2123226633Sdim    case ARM::LDRD:
2124226633Sdim    case ARM::LDRD_PRE:
2125226633Sdim    case ARM::LDRD_POST:
2126226633Sdim    case ARM::LDRH:
2127226633Sdim    case ARM::LDRH_PRE:
2128226633Sdim    case ARM::LDRH_POST:
2129226633Sdim    case ARM::LDRSH:
2130226633Sdim    case ARM::LDRSH_PRE:
2131226633Sdim    case ARM::LDRSH_POST:
2132226633Sdim    case ARM::LDRSB:
2133226633Sdim    case ARM::LDRSB_PRE:
2134226633Sdim    case ARM::LDRSB_POST:
2135226633Sdim    case ARM::LDRHTr:
2136226633Sdim    case ARM::LDRSBTr:
2137226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2138226633Sdim        return MCDisassembler::Fail;
2139226633Sdim      break;
2140226633Sdim    default:
2141226633Sdim      break;
2142226633Sdim    }
2143226633Sdim  }
2144226633Sdim
2145226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2146226633Sdim    return MCDisassembler::Fail;
2147226633Sdim
2148226633Sdim  if (type) {
2149288943Sdim    Inst.addOperand(MCOperand::createReg(0));
2150288943Sdim    Inst.addOperand(MCOperand::createImm(U | (imm << 4) | Rm));
2151226633Sdim  } else {
2152226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2153226633Sdim    return MCDisassembler::Fail;
2154288943Sdim    Inst.addOperand(MCOperand::createImm(U));
2155226633Sdim  }
2156226633Sdim
2157226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2158226633Sdim    return MCDisassembler::Fail;
2159226633Sdim
2160226633Sdim  return S;
2161226633Sdim}
2162226633Sdim
2163234353Sdimstatic DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
2164226633Sdim                                 uint64_t Address, const void *Decoder) {
2165226633Sdim  DecodeStatus S = MCDisassembler::Success;
2166226633Sdim
2167239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2168239462Sdim  unsigned mode = fieldFromInstruction(Insn, 23, 2);
2169226633Sdim
2170226633Sdim  switch (mode) {
2171226633Sdim    case 0:
2172226633Sdim      mode = ARM_AM::da;
2173226633Sdim      break;
2174226633Sdim    case 1:
2175226633Sdim      mode = ARM_AM::ia;
2176226633Sdim      break;
2177226633Sdim    case 2:
2178226633Sdim      mode = ARM_AM::db;
2179226633Sdim      break;
2180226633Sdim    case 3:
2181226633Sdim      mode = ARM_AM::ib;
2182226633Sdim      break;
2183226633Sdim  }
2184226633Sdim
2185288943Sdim  Inst.addOperand(MCOperand::createImm(mode));
2186226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2187226633Sdim    return MCDisassembler::Fail;
2188226633Sdim
2189226633Sdim  return S;
2190226633Sdim}
2191226633Sdim
2192261991Sdimstatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
2193261991Sdim                               uint64_t Address, const void *Decoder) {
2194261991Sdim  DecodeStatus S = MCDisassembler::Success;
2195261991Sdim
2196261991Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2197261991Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2198261991Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2199261991Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2200261991Sdim
2201261991Sdim  if (pred == 0xF)
2202261991Sdim    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
2203261991Sdim
2204261991Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2205261991Sdim    return MCDisassembler::Fail;
2206261991Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
2207261991Sdim    return MCDisassembler::Fail;
2208261991Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2209261991Sdim    return MCDisassembler::Fail;
2210261991Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2211261991Sdim    return MCDisassembler::Fail;
2212261991Sdim  return S;
2213261991Sdim}
2214261991Sdim
2215234353Sdimstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst,
2216226633Sdim                                  unsigned Insn,
2217226633Sdim                                  uint64_t Address, const void *Decoder) {
2218226633Sdim  DecodeStatus S = MCDisassembler::Success;
2219226633Sdim
2220239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2221239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2222239462Sdim  unsigned reglist = fieldFromInstruction(Insn, 0, 16);
2223226633Sdim
2224226633Sdim  if (pred == 0xF) {
2225261991Sdim    // Ambiguous with RFE and SRS
2226226633Sdim    switch (Inst.getOpcode()) {
2227226633Sdim      case ARM::LDMDA:
2228226633Sdim        Inst.setOpcode(ARM::RFEDA);
2229226633Sdim        break;
2230226633Sdim      case ARM::LDMDA_UPD:
2231226633Sdim        Inst.setOpcode(ARM::RFEDA_UPD);
2232226633Sdim        break;
2233226633Sdim      case ARM::LDMDB:
2234226633Sdim        Inst.setOpcode(ARM::RFEDB);
2235226633Sdim        break;
2236226633Sdim      case ARM::LDMDB_UPD:
2237226633Sdim        Inst.setOpcode(ARM::RFEDB_UPD);
2238226633Sdim        break;
2239226633Sdim      case ARM::LDMIA:
2240226633Sdim        Inst.setOpcode(ARM::RFEIA);
2241226633Sdim        break;
2242226633Sdim      case ARM::LDMIA_UPD:
2243226633Sdim        Inst.setOpcode(ARM::RFEIA_UPD);
2244226633Sdim        break;
2245226633Sdim      case ARM::LDMIB:
2246226633Sdim        Inst.setOpcode(ARM::RFEIB);
2247226633Sdim        break;
2248226633Sdim      case ARM::LDMIB_UPD:
2249226633Sdim        Inst.setOpcode(ARM::RFEIB_UPD);
2250226633Sdim        break;
2251226633Sdim      case ARM::STMDA:
2252226633Sdim        Inst.setOpcode(ARM::SRSDA);
2253226633Sdim        break;
2254226633Sdim      case ARM::STMDA_UPD:
2255226633Sdim        Inst.setOpcode(ARM::SRSDA_UPD);
2256226633Sdim        break;
2257226633Sdim      case ARM::STMDB:
2258226633Sdim        Inst.setOpcode(ARM::SRSDB);
2259226633Sdim        break;
2260226633Sdim      case ARM::STMDB_UPD:
2261226633Sdim        Inst.setOpcode(ARM::SRSDB_UPD);
2262226633Sdim        break;
2263226633Sdim      case ARM::STMIA:
2264226633Sdim        Inst.setOpcode(ARM::SRSIA);
2265226633Sdim        break;
2266226633Sdim      case ARM::STMIA_UPD:
2267226633Sdim        Inst.setOpcode(ARM::SRSIA_UPD);
2268226633Sdim        break;
2269226633Sdim      case ARM::STMIB:
2270226633Sdim        Inst.setOpcode(ARM::SRSIB);
2271226633Sdim        break;
2272226633Sdim      case ARM::STMIB_UPD:
2273226633Sdim        Inst.setOpcode(ARM::SRSIB_UPD);
2274226633Sdim        break;
2275206124Srdivacky      default:
2276261991Sdim        return MCDisassembler::Fail;
2277226633Sdim    }
2278226633Sdim
2279226633Sdim    // For stores (which become SRS's, the only operand is the mode.
2280239462Sdim    if (fieldFromInstruction(Insn, 20, 1) == 0) {
2281261991Sdim      // Check SRS encoding constraints
2282261991Sdim      if (!(fieldFromInstruction(Insn, 22, 1) == 1 &&
2283261991Sdim            fieldFromInstruction(Insn, 20, 1) == 0))
2284261991Sdim        return MCDisassembler::Fail;
2285261991Sdim
2286226633Sdim      Inst.addOperand(
2287288943Sdim          MCOperand::createImm(fieldFromInstruction(Insn, 0, 4)));
2288226633Sdim      return S;
2289226633Sdim    }
2290226633Sdim
2291226633Sdim    return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
2292226633Sdim  }
2293226633Sdim
2294226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2295226633Sdim    return MCDisassembler::Fail;
2296226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2297226633Sdim    return MCDisassembler::Fail; // Tied
2298226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2299226633Sdim    return MCDisassembler::Fail;
2300226633Sdim  if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
2301226633Sdim    return MCDisassembler::Fail;
2302226633Sdim
2303226633Sdim  return S;
2304226633Sdim}
2305226633Sdim
2306309124Sdim// Check for UNPREDICTABLE predicated ESB instruction
2307309124Sdimstatic DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
2308309124Sdim                                 uint64_t Address, const void *Decoder) {
2309309124Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2310309124Sdim  unsigned imm8 = fieldFromInstruction(Insn, 0, 8);
2311309124Sdim  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
2312309124Sdim  const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
2313309124Sdim
2314309124Sdim  DecodeStatus S = MCDisassembler::Success;
2315309124Sdim
2316309124Sdim  Inst.addOperand(MCOperand::createImm(imm8));
2317309124Sdim
2318309124Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2319309124Sdim    return MCDisassembler::Fail;
2320309124Sdim
2321309124Sdim  // ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP,
2322309124Sdim  // so all predicates should be allowed.
2323309124Sdim  if (imm8 == 0x10 && pred != 0xe && ((FeatureBits[ARM::FeatureRAS]) != 0))
2324309124Sdim    S = MCDisassembler::SoftFail;
2325309124Sdim
2326309124Sdim  return S;
2327309124Sdim}
2328309124Sdim
2329234353Sdimstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
2330226633Sdim                                 uint64_t Address, const void *Decoder) {
2331239462Sdim  unsigned imod = fieldFromInstruction(Insn, 18, 2);
2332239462Sdim  unsigned M = fieldFromInstruction(Insn, 17, 1);
2333239462Sdim  unsigned iflags = fieldFromInstruction(Insn, 6, 3);
2334239462Sdim  unsigned mode = fieldFromInstruction(Insn, 0, 5);
2335226633Sdim
2336226633Sdim  DecodeStatus S = MCDisassembler::Success;
2337226633Sdim
2338261991Sdim  // This decoder is called from multiple location that do not check
2339261991Sdim  // the full encoding is valid before they do.
2340261991Sdim  if (fieldFromInstruction(Insn, 5, 1) != 0 ||
2341261991Sdim      fieldFromInstruction(Insn, 16, 1) != 0 ||
2342261991Sdim      fieldFromInstruction(Insn, 20, 8) != 0x10)
2343261991Sdim    return MCDisassembler::Fail;
2344261991Sdim
2345226633Sdim  // imod == '01' --> UNPREDICTABLE
2346226633Sdim  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
2347226633Sdim  // return failure here.  The '01' imod value is unprintable, so there's
2348226633Sdim  // nothing useful we could do even if we returned UNPREDICTABLE.
2349226633Sdim
2350226633Sdim  if (imod == 1) return MCDisassembler::Fail;
2351226633Sdim
2352226633Sdim  if (imod && M) {
2353226633Sdim    Inst.setOpcode(ARM::CPS3p);
2354288943Sdim    Inst.addOperand(MCOperand::createImm(imod));
2355288943Sdim    Inst.addOperand(MCOperand::createImm(iflags));
2356288943Sdim    Inst.addOperand(MCOperand::createImm(mode));
2357226633Sdim  } else if (imod && !M) {
2358226633Sdim    Inst.setOpcode(ARM::CPS2p);
2359288943Sdim    Inst.addOperand(MCOperand::createImm(imod));
2360288943Sdim    Inst.addOperand(MCOperand::createImm(iflags));
2361226633Sdim    if (mode) S = MCDisassembler::SoftFail;
2362226633Sdim  } else if (!imod && M) {
2363226633Sdim    Inst.setOpcode(ARM::CPS1p);
2364288943Sdim    Inst.addOperand(MCOperand::createImm(mode));
2365226633Sdim    if (iflags) S = MCDisassembler::SoftFail;
2366226633Sdim  } else {
2367226633Sdim    // imod == '00' && M == '0' --> UNPREDICTABLE
2368226633Sdim    Inst.setOpcode(ARM::CPS1p);
2369288943Sdim    Inst.addOperand(MCOperand::createImm(mode));
2370226633Sdim    S = MCDisassembler::SoftFail;
2371226633Sdim  }
2372226633Sdim
2373226633Sdim  return S;
2374226633Sdim}
2375226633Sdim
2376234353Sdimstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
2377226633Sdim                                 uint64_t Address, const void *Decoder) {
2378239462Sdim  unsigned imod = fieldFromInstruction(Insn, 9, 2);
2379239462Sdim  unsigned M = fieldFromInstruction(Insn, 8, 1);
2380239462Sdim  unsigned iflags = fieldFromInstruction(Insn, 5, 3);
2381239462Sdim  unsigned mode = fieldFromInstruction(Insn, 0, 5);
2382226633Sdim
2383226633Sdim  DecodeStatus S = MCDisassembler::Success;
2384226633Sdim
2385226633Sdim  // imod == '01' --> UNPREDICTABLE
2386226633Sdim  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
2387226633Sdim  // return failure here.  The '01' imod value is unprintable, so there's
2388226633Sdim  // nothing useful we could do even if we returned UNPREDICTABLE.
2389226633Sdim
2390226633Sdim  if (imod == 1) return MCDisassembler::Fail;
2391226633Sdim
2392226633Sdim  if (imod && M) {
2393226633Sdim    Inst.setOpcode(ARM::t2CPS3p);
2394288943Sdim    Inst.addOperand(MCOperand::createImm(imod));
2395288943Sdim    Inst.addOperand(MCOperand::createImm(iflags));
2396288943Sdim    Inst.addOperand(MCOperand::createImm(mode));
2397226633Sdim  } else if (imod && !M) {
2398226633Sdim    Inst.setOpcode(ARM::t2CPS2p);
2399288943Sdim    Inst.addOperand(MCOperand::createImm(imod));
2400288943Sdim    Inst.addOperand(MCOperand::createImm(iflags));
2401226633Sdim    if (mode) S = MCDisassembler::SoftFail;
2402226633Sdim  } else if (!imod && M) {
2403226633Sdim    Inst.setOpcode(ARM::t2CPS1p);
2404288943Sdim    Inst.addOperand(MCOperand::createImm(mode));
2405226633Sdim    if (iflags) S = MCDisassembler::SoftFail;
2406226633Sdim  } else {
2407251662Sdim    // imod == '00' && M == '0' --> this is a HINT instruction
2408251662Sdim    int imm = fieldFromInstruction(Insn, 0, 8);
2409251662Sdim    // HINT are defined only for immediate in [0..4]
2410251662Sdim    if(imm > 4) return MCDisassembler::Fail;
2411251662Sdim    Inst.setOpcode(ARM::t2HINT);
2412288943Sdim    Inst.addOperand(MCOperand::createImm(imm));
2413226633Sdim  }
2414226633Sdim
2415226633Sdim  return S;
2416226633Sdim}
2417226633Sdim
2418234353Sdimstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
2419226633Sdim                                 uint64_t Address, const void *Decoder) {
2420226633Sdim  DecodeStatus S = MCDisassembler::Success;
2421226633Sdim
2422239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 8, 4);
2423226633Sdim  unsigned imm = 0;
2424226633Sdim
2425239462Sdim  imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
2426239462Sdim  imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
2427239462Sdim  imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
2428239462Sdim  imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
2429226633Sdim
2430226633Sdim  if (Inst.getOpcode() == ARM::t2MOVTi16)
2431226633Sdim    if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
2432226633Sdim      return MCDisassembler::Fail;
2433226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
2434226633Sdim    return MCDisassembler::Fail;
2435226633Sdim
2436226633Sdim  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
2437288943Sdim    Inst.addOperand(MCOperand::createImm(imm));
2438226633Sdim
2439226633Sdim  return S;
2440226633Sdim}
2441226633Sdim
2442234353Sdimstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
2443226633Sdim                                 uint64_t Address, const void *Decoder) {
2444226633Sdim  DecodeStatus S = MCDisassembler::Success;
2445226633Sdim
2446239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2447239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2448226633Sdim  unsigned imm = 0;
2449226633Sdim
2450239462Sdim  imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
2451239462Sdim  imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
2452226633Sdim
2453226633Sdim  if (Inst.getOpcode() == ARM::MOVTi16)
2454251662Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2455226633Sdim      return MCDisassembler::Fail;
2456251662Sdim
2457251662Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2458226633Sdim    return MCDisassembler::Fail;
2459226633Sdim
2460226633Sdim  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
2461288943Sdim    Inst.addOperand(MCOperand::createImm(imm));
2462226633Sdim
2463226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2464226633Sdim    return MCDisassembler::Fail;
2465226633Sdim
2466226633Sdim  return S;
2467226633Sdim}
2468226633Sdim
2469234353Sdimstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
2470226633Sdim                                 uint64_t Address, const void *Decoder) {
2471226633Sdim  DecodeStatus S = MCDisassembler::Success;
2472226633Sdim
2473239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 16, 4);
2474239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 0, 4);
2475239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 8, 4);
2476239462Sdim  unsigned Ra = fieldFromInstruction(Insn, 12, 4);
2477239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2478226633Sdim
2479226633Sdim  if (pred == 0xF)
2480226633Sdim    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
2481226633Sdim
2482226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2483226633Sdim    return MCDisassembler::Fail;
2484226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2485226633Sdim    return MCDisassembler::Fail;
2486226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
2487226633Sdim    return MCDisassembler::Fail;
2488226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
2489226633Sdim    return MCDisassembler::Fail;
2490226633Sdim
2491226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2492226633Sdim    return MCDisassembler::Fail;
2493226633Sdim
2494226633Sdim  return S;
2495226633Sdim}
2496226633Sdim
2497288943Sdimstatic DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
2498288943Sdim                                  uint64_t Address, const void *Decoder) {
2499288943Sdim  DecodeStatus S = MCDisassembler::Success;
2500288943Sdim
2501288943Sdim  unsigned Pred = fieldFromInstruction(Insn, 28, 4);
2502288943Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2503288943Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2504288943Sdim
2505288943Sdim  if (Pred == 0xF)
2506288943Sdim    return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
2507288943Sdim
2508288943Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2509288943Sdim    return MCDisassembler::Fail;
2510288943Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2511288943Sdim    return MCDisassembler::Fail;
2512288943Sdim  if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
2513288943Sdim    return MCDisassembler::Fail;
2514288943Sdim
2515288943Sdim  return S;
2516288943Sdim}
2517288943Sdim
2518288943Sdimstatic DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
2519288943Sdim                                  uint64_t Address, const void *Decoder) {
2520288943Sdim  DecodeStatus S = MCDisassembler::Success;
2521288943Sdim
2522288943Sdim  unsigned Imm = fieldFromInstruction(Insn, 9, 1);
2523288943Sdim
2524288943Sdim  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
2525288943Sdim  const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
2526288943Sdim
2527341825Sdim  if (!FeatureBits[ARM::HasV8_1aOps] ||
2528288943Sdim      !FeatureBits[ARM::HasV8Ops])
2529288943Sdim    return MCDisassembler::Fail;
2530288943Sdim
2531288943Sdim  // Decoder can be called from DecodeTST, which does not check the full
2532288943Sdim  // encoding is valid.
2533288943Sdim  if (fieldFromInstruction(Insn, 20,12) != 0xf11 ||
2534288943Sdim      fieldFromInstruction(Insn, 4,4) != 0)
2535288943Sdim    return MCDisassembler::Fail;
2536288943Sdim  if (fieldFromInstruction(Insn, 10,10) != 0 ||
2537288943Sdim      fieldFromInstruction(Insn, 0,4) != 0)
2538288943Sdim    S = MCDisassembler::SoftFail;
2539288943Sdim
2540288943Sdim  Inst.setOpcode(ARM::SETPAN);
2541288943Sdim  Inst.addOperand(MCOperand::createImm(Imm));
2542288943Sdim
2543288943Sdim  return S;
2544288943Sdim}
2545288943Sdim
2546234353Sdimstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
2547226633Sdim                           uint64_t Address, const void *Decoder) {
2548226633Sdim  DecodeStatus S = MCDisassembler::Success;
2549226633Sdim
2550239462Sdim  unsigned add = fieldFromInstruction(Val, 12, 1);
2551239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 12);
2552239462Sdim  unsigned Rn = fieldFromInstruction(Val, 13, 4);
2553226633Sdim
2554226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2555226633Sdim    return MCDisassembler::Fail;
2556226633Sdim
2557226633Sdim  if (!add) imm *= -1;
2558226633Sdim  if (imm == 0 && !add) imm = INT32_MIN;
2559288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
2560226633Sdim  if (Rn == 15)
2561226633Sdim    tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
2562226633Sdim
2563226633Sdim  return S;
2564226633Sdim}
2565226633Sdim
2566234353Sdimstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
2567226633Sdim                                   uint64_t Address, const void *Decoder) {
2568226633Sdim  DecodeStatus S = MCDisassembler::Success;
2569226633Sdim
2570239462Sdim  unsigned Rn = fieldFromInstruction(Val, 9, 4);
2571309124Sdim  // U == 1 to add imm, 0 to subtract it.
2572239462Sdim  unsigned U = fieldFromInstruction(Val, 8, 1);
2573239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 8);
2574226633Sdim
2575226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2576226633Sdim    return MCDisassembler::Fail;
2577226633Sdim
2578226633Sdim  if (U)
2579288943Sdim    Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
2580226633Sdim  else
2581288943Sdim    Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
2582226633Sdim
2583226633Sdim  return S;
2584226633Sdim}
2585226633Sdim
2586309124Sdimstatic DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
2587309124Sdim                                   uint64_t Address, const void *Decoder) {
2588309124Sdim  DecodeStatus S = MCDisassembler::Success;
2589309124Sdim
2590309124Sdim  unsigned Rn = fieldFromInstruction(Val, 9, 4);
2591309124Sdim  // U == 1 to add imm, 0 to subtract it.
2592309124Sdim  unsigned U = fieldFromInstruction(Val, 8, 1);
2593309124Sdim  unsigned imm = fieldFromInstruction(Val, 0, 8);
2594309124Sdim
2595309124Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2596309124Sdim    return MCDisassembler::Fail;
2597309124Sdim
2598309124Sdim  if (U)
2599309124Sdim    Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::add, imm)));
2600309124Sdim  else
2601309124Sdim    Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::sub, imm)));
2602309124Sdim
2603309124Sdim  return S;
2604309124Sdim}
2605309124Sdim
2606234353Sdimstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
2607226633Sdim                                   uint64_t Address, const void *Decoder) {
2608226633Sdim  return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
2609226633Sdim}
2610226633Sdim
2611226633Sdimstatic DecodeStatus
2612234353SdimDecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2613234353Sdim                     uint64_t Address, const void *Decoder) {
2614243830Sdim  DecodeStatus Status = MCDisassembler::Success;
2615243830Sdim
2616243830Sdim  // Note the J1 and J2 values are from the encoded instruction.  So here
2617243830Sdim  // change them to I1 and I2 values via as documented:
2618243830Sdim  // I1 = NOT(J1 EOR S);
2619243830Sdim  // I2 = NOT(J2 EOR S);
2620243830Sdim  // and build the imm32 with one trailing zero as documented:
2621243830Sdim  // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
2622243830Sdim  unsigned S = fieldFromInstruction(Insn, 26, 1);
2623243830Sdim  unsigned J1 = fieldFromInstruction(Insn, 13, 1);
2624243830Sdim  unsigned J2 = fieldFromInstruction(Insn, 11, 1);
2625243830Sdim  unsigned I1 = !(J1 ^ S);
2626243830Sdim  unsigned I2 = !(J2 ^ S);
2627243830Sdim  unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
2628243830Sdim  unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
2629243830Sdim  unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
2630261991Sdim  int imm32 = SignExtend32<25>(tmp << 1);
2631243830Sdim  if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
2632234353Sdim                                true, 4, Inst, Decoder))
2633288943Sdim    Inst.addOperand(MCOperand::createImm(imm32));
2634243830Sdim
2635243830Sdim  return Status;
2636234353Sdim}
2637234353Sdim
2638234353Sdimstatic DecodeStatus
2639234353SdimDecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
2640226633Sdim                           uint64_t Address, const void *Decoder) {
2641226633Sdim  DecodeStatus S = MCDisassembler::Success;
2642226633Sdim
2643239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2644239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
2645226633Sdim
2646226633Sdim  if (pred == 0xF) {
2647226633Sdim    Inst.setOpcode(ARM::BLXi);
2648239462Sdim    imm |= fieldFromInstruction(Insn, 24, 1) << 1;
2649234353Sdim    if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2650234353Sdim                                  true, 4, Inst, Decoder))
2651288943Sdim    Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
2652226633Sdim    return S;
2653226633Sdim  }
2654226633Sdim
2655234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2656234353Sdim                                true, 4, Inst, Decoder))
2657288943Sdim    Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
2658226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2659226633Sdim    return MCDisassembler::Fail;
2660226633Sdim
2661226633Sdim  return S;
2662226633Sdim}
2663226633Sdim
2664234353Sdimstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
2665226633Sdim                                   uint64_t Address, const void *Decoder) {
2666226633Sdim  DecodeStatus S = MCDisassembler::Success;
2667226633Sdim
2668239462Sdim  unsigned Rm = fieldFromInstruction(Val, 0, 4);
2669239462Sdim  unsigned align = fieldFromInstruction(Val, 4, 2);
2670226633Sdim
2671226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2672226633Sdim    return MCDisassembler::Fail;
2673226633Sdim  if (!align)
2674288943Sdim    Inst.addOperand(MCOperand::createImm(0));
2675226633Sdim  else
2676288943Sdim    Inst.addOperand(MCOperand::createImm(4 << align));
2677226633Sdim
2678226633Sdim  return S;
2679226633Sdim}
2680226633Sdim
2681234353Sdimstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
2682226633Sdim                                   uint64_t Address, const void *Decoder) {
2683226633Sdim  DecodeStatus S = MCDisassembler::Success;
2684226633Sdim
2685239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2686239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2687239462Sdim  unsigned wb = fieldFromInstruction(Insn, 16, 4);
2688239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2689239462Sdim  Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2690239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2691226633Sdim
2692226633Sdim  // First output register
2693234353Sdim  switch (Inst.getOpcode()) {
2694234353Sdim  case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
2695234353Sdim  case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
2696234353Sdim  case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
2697234353Sdim  case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
2698234353Sdim  case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
2699234353Sdim  case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
2700234353Sdim  case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
2701234353Sdim  case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
2702234353Sdim  case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
2703234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2704234353Sdim      return MCDisassembler::Fail;
2705234353Sdim    break;
2706234353Sdim  case ARM::VLD2b16:
2707234353Sdim  case ARM::VLD2b32:
2708234353Sdim  case ARM::VLD2b8:
2709234353Sdim  case ARM::VLD2b16wb_fixed:
2710234353Sdim  case ARM::VLD2b16wb_register:
2711234353Sdim  case ARM::VLD2b32wb_fixed:
2712234353Sdim  case ARM::VLD2b32wb_register:
2713234353Sdim  case ARM::VLD2b8wb_fixed:
2714234353Sdim  case ARM::VLD2b8wb_register:
2715234353Sdim    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2716234353Sdim      return MCDisassembler::Fail;
2717234353Sdim    break;
2718234353Sdim  default:
2719234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2720234353Sdim      return MCDisassembler::Fail;
2721234353Sdim  }
2722226633Sdim
2723226633Sdim  // Second output register
2724226633Sdim  switch (Inst.getOpcode()) {
2725226633Sdim    case ARM::VLD3d8:
2726226633Sdim    case ARM::VLD3d16:
2727226633Sdim    case ARM::VLD3d32:
2728226633Sdim    case ARM::VLD3d8_UPD:
2729226633Sdim    case ARM::VLD3d16_UPD:
2730226633Sdim    case ARM::VLD3d32_UPD:
2731226633Sdim    case ARM::VLD4d8:
2732226633Sdim    case ARM::VLD4d16:
2733226633Sdim    case ARM::VLD4d32:
2734226633Sdim    case ARM::VLD4d8_UPD:
2735226633Sdim    case ARM::VLD4d16_UPD:
2736226633Sdim    case ARM::VLD4d32_UPD:
2737226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2738226633Sdim        return MCDisassembler::Fail;
2739206124Srdivacky      break;
2740226633Sdim    case ARM::VLD3q8:
2741226633Sdim    case ARM::VLD3q16:
2742226633Sdim    case ARM::VLD3q32:
2743226633Sdim    case ARM::VLD3q8_UPD:
2744226633Sdim    case ARM::VLD3q16_UPD:
2745226633Sdim    case ARM::VLD3q32_UPD:
2746226633Sdim    case ARM::VLD4q8:
2747226633Sdim    case ARM::VLD4q16:
2748226633Sdim    case ARM::VLD4q32:
2749226633Sdim    case ARM::VLD4q8_UPD:
2750226633Sdim    case ARM::VLD4q16_UPD:
2751226633Sdim    case ARM::VLD4q32_UPD:
2752226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2753226633Sdim        return MCDisassembler::Fail;
2754327952Sdim      break;
2755206124Srdivacky    default:
2756226633Sdim      break;
2757226633Sdim  }
2758226633Sdim
2759226633Sdim  // Third output register
2760226633Sdim  switch(Inst.getOpcode()) {
2761226633Sdim    case ARM::VLD3d8:
2762226633Sdim    case ARM::VLD3d16:
2763226633Sdim    case ARM::VLD3d32:
2764226633Sdim    case ARM::VLD3d8_UPD:
2765226633Sdim    case ARM::VLD3d16_UPD:
2766226633Sdim    case ARM::VLD3d32_UPD:
2767226633Sdim    case ARM::VLD4d8:
2768226633Sdim    case ARM::VLD4d16:
2769226633Sdim    case ARM::VLD4d32:
2770226633Sdim    case ARM::VLD4d8_UPD:
2771226633Sdim    case ARM::VLD4d16_UPD:
2772226633Sdim    case ARM::VLD4d32_UPD:
2773226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2774226633Sdim        return MCDisassembler::Fail;
2775226633Sdim      break;
2776226633Sdim    case ARM::VLD3q8:
2777226633Sdim    case ARM::VLD3q16:
2778226633Sdim    case ARM::VLD3q32:
2779226633Sdim    case ARM::VLD3q8_UPD:
2780226633Sdim    case ARM::VLD3q16_UPD:
2781226633Sdim    case ARM::VLD3q32_UPD:
2782226633Sdim    case ARM::VLD4q8:
2783226633Sdim    case ARM::VLD4q16:
2784226633Sdim    case ARM::VLD4q32:
2785226633Sdim    case ARM::VLD4q8_UPD:
2786226633Sdim    case ARM::VLD4q16_UPD:
2787226633Sdim    case ARM::VLD4q32_UPD:
2788226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2789226633Sdim        return MCDisassembler::Fail;
2790226633Sdim      break;
2791226633Sdim    default:
2792226633Sdim      break;
2793226633Sdim  }
2794226633Sdim
2795226633Sdim  // Fourth output register
2796226633Sdim  switch (Inst.getOpcode()) {
2797226633Sdim    case ARM::VLD4d8:
2798226633Sdim    case ARM::VLD4d16:
2799226633Sdim    case ARM::VLD4d32:
2800226633Sdim    case ARM::VLD4d8_UPD:
2801226633Sdim    case ARM::VLD4d16_UPD:
2802226633Sdim    case ARM::VLD4d32_UPD:
2803226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2804226633Sdim        return MCDisassembler::Fail;
2805226633Sdim      break;
2806226633Sdim    case ARM::VLD4q8:
2807226633Sdim    case ARM::VLD4q16:
2808226633Sdim    case ARM::VLD4q32:
2809226633Sdim    case ARM::VLD4q8_UPD:
2810226633Sdim    case ARM::VLD4q16_UPD:
2811226633Sdim    case ARM::VLD4q32_UPD:
2812226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2813226633Sdim        return MCDisassembler::Fail;
2814226633Sdim      break;
2815226633Sdim    default:
2816226633Sdim      break;
2817226633Sdim  }
2818226633Sdim
2819226633Sdim  // Writeback operand
2820226633Sdim  switch (Inst.getOpcode()) {
2821234353Sdim    case ARM::VLD1d8wb_fixed:
2822234353Sdim    case ARM::VLD1d16wb_fixed:
2823234353Sdim    case ARM::VLD1d32wb_fixed:
2824234353Sdim    case ARM::VLD1d64wb_fixed:
2825234353Sdim    case ARM::VLD1d8wb_register:
2826234353Sdim    case ARM::VLD1d16wb_register:
2827234353Sdim    case ARM::VLD1d32wb_register:
2828234353Sdim    case ARM::VLD1d64wb_register:
2829234353Sdim    case ARM::VLD1q8wb_fixed:
2830234353Sdim    case ARM::VLD1q16wb_fixed:
2831234353Sdim    case ARM::VLD1q32wb_fixed:
2832234353Sdim    case ARM::VLD1q64wb_fixed:
2833234353Sdim    case ARM::VLD1q8wb_register:
2834234353Sdim    case ARM::VLD1q16wb_register:
2835234353Sdim    case ARM::VLD1q32wb_register:
2836234353Sdim    case ARM::VLD1q64wb_register:
2837234353Sdim    case ARM::VLD1d8Twb_fixed:
2838234353Sdim    case ARM::VLD1d8Twb_register:
2839234353Sdim    case ARM::VLD1d16Twb_fixed:
2840234353Sdim    case ARM::VLD1d16Twb_register:
2841234353Sdim    case ARM::VLD1d32Twb_fixed:
2842234353Sdim    case ARM::VLD1d32Twb_register:
2843234353Sdim    case ARM::VLD1d64Twb_fixed:
2844234353Sdim    case ARM::VLD1d64Twb_register:
2845234353Sdim    case ARM::VLD1d8Qwb_fixed:
2846234353Sdim    case ARM::VLD1d8Qwb_register:
2847234353Sdim    case ARM::VLD1d16Qwb_fixed:
2848234353Sdim    case ARM::VLD1d16Qwb_register:
2849234353Sdim    case ARM::VLD1d32Qwb_fixed:
2850234353Sdim    case ARM::VLD1d32Qwb_register:
2851234353Sdim    case ARM::VLD1d64Qwb_fixed:
2852234353Sdim    case ARM::VLD1d64Qwb_register:
2853234353Sdim    case ARM::VLD2d8wb_fixed:
2854234353Sdim    case ARM::VLD2d16wb_fixed:
2855234353Sdim    case ARM::VLD2d32wb_fixed:
2856234353Sdim    case ARM::VLD2q8wb_fixed:
2857234353Sdim    case ARM::VLD2q16wb_fixed:
2858234353Sdim    case ARM::VLD2q32wb_fixed:
2859234353Sdim    case ARM::VLD2d8wb_register:
2860234353Sdim    case ARM::VLD2d16wb_register:
2861234353Sdim    case ARM::VLD2d32wb_register:
2862234353Sdim    case ARM::VLD2q8wb_register:
2863234353Sdim    case ARM::VLD2q16wb_register:
2864234353Sdim    case ARM::VLD2q32wb_register:
2865234353Sdim    case ARM::VLD2b8wb_fixed:
2866234353Sdim    case ARM::VLD2b16wb_fixed:
2867234353Sdim    case ARM::VLD2b32wb_fixed:
2868234353Sdim    case ARM::VLD2b8wb_register:
2869234353Sdim    case ARM::VLD2b16wb_register:
2870234353Sdim    case ARM::VLD2b32wb_register:
2871288943Sdim      Inst.addOperand(MCOperand::createImm(0));
2872234353Sdim      break;
2873226633Sdim    case ARM::VLD3d8_UPD:
2874226633Sdim    case ARM::VLD3d16_UPD:
2875226633Sdim    case ARM::VLD3d32_UPD:
2876226633Sdim    case ARM::VLD3q8_UPD:
2877226633Sdim    case ARM::VLD3q16_UPD:
2878226633Sdim    case ARM::VLD3q32_UPD:
2879226633Sdim    case ARM::VLD4d8_UPD:
2880226633Sdim    case ARM::VLD4d16_UPD:
2881226633Sdim    case ARM::VLD4d32_UPD:
2882226633Sdim    case ARM::VLD4q8_UPD:
2883226633Sdim    case ARM::VLD4q16_UPD:
2884226633Sdim    case ARM::VLD4q32_UPD:
2885226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2886226633Sdim        return MCDisassembler::Fail;
2887226633Sdim      break;
2888226633Sdim    default:
2889226633Sdim      break;
2890226633Sdim  }
2891226633Sdim
2892226633Sdim  // AddrMode6 Base (register+alignment)
2893226633Sdim  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2894226633Sdim    return MCDisassembler::Fail;
2895226633Sdim
2896226633Sdim  // AddrMode6 Offset (register)
2897234353Sdim  switch (Inst.getOpcode()) {
2898234353Sdim  default:
2899234353Sdim    // The below have been updated to have explicit am6offset split
2900234353Sdim    // between fixed and register offset. For those instructions not
2901234353Sdim    // yet updated, we need to add an additional reg0 operand for the
2902234353Sdim    // fixed variant.
2903234353Sdim    //
2904234353Sdim    // The fixed offset encodes as Rm == 0xd, so we check for that.
2905234353Sdim    if (Rm == 0xd) {
2906288943Sdim      Inst.addOperand(MCOperand::createReg(0));
2907234353Sdim      break;
2908234353Sdim    }
2909234353Sdim    // Fall through to handle the register offset variant.
2910314564Sdim    LLVM_FALLTHROUGH;
2911234353Sdim  case ARM::VLD1d8wb_fixed:
2912234353Sdim  case ARM::VLD1d16wb_fixed:
2913234353Sdim  case ARM::VLD1d32wb_fixed:
2914234353Sdim  case ARM::VLD1d64wb_fixed:
2915234353Sdim  case ARM::VLD1d8Twb_fixed:
2916234353Sdim  case ARM::VLD1d16Twb_fixed:
2917234353Sdim  case ARM::VLD1d32Twb_fixed:
2918234353Sdim  case ARM::VLD1d64Twb_fixed:
2919234353Sdim  case ARM::VLD1d8Qwb_fixed:
2920234353Sdim  case ARM::VLD1d16Qwb_fixed:
2921234353Sdim  case ARM::VLD1d32Qwb_fixed:
2922234353Sdim  case ARM::VLD1d64Qwb_fixed:
2923234353Sdim  case ARM::VLD1d8wb_register:
2924234353Sdim  case ARM::VLD1d16wb_register:
2925234353Sdim  case ARM::VLD1d32wb_register:
2926234353Sdim  case ARM::VLD1d64wb_register:
2927234353Sdim  case ARM::VLD1q8wb_fixed:
2928234353Sdim  case ARM::VLD1q16wb_fixed:
2929234353Sdim  case ARM::VLD1q32wb_fixed:
2930234353Sdim  case ARM::VLD1q64wb_fixed:
2931234353Sdim  case ARM::VLD1q8wb_register:
2932234353Sdim  case ARM::VLD1q16wb_register:
2933234353Sdim  case ARM::VLD1q32wb_register:
2934234353Sdim  case ARM::VLD1q64wb_register:
2935234353Sdim    // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2936234353Sdim    // variant encodes Rm == 0xf. Anything else is a register offset post-
2937234353Sdim    // increment and we need to add the register operand to the instruction.
2938234353Sdim    if (Rm != 0xD && Rm != 0xF &&
2939234353Sdim        !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2940226633Sdim      return MCDisassembler::Fail;
2941234353Sdim    break;
2942234353Sdim  case ARM::VLD2d8wb_fixed:
2943234353Sdim  case ARM::VLD2d16wb_fixed:
2944234353Sdim  case ARM::VLD2d32wb_fixed:
2945234353Sdim  case ARM::VLD2b8wb_fixed:
2946234353Sdim  case ARM::VLD2b16wb_fixed:
2947234353Sdim  case ARM::VLD2b32wb_fixed:
2948234353Sdim  case ARM::VLD2q8wb_fixed:
2949234353Sdim  case ARM::VLD2q16wb_fixed:
2950234353Sdim  case ARM::VLD2q32wb_fixed:
2951234353Sdim    break;
2952226633Sdim  }
2953226633Sdim
2954226633Sdim  return S;
2955226633Sdim}
2956226633Sdim
2957261991Sdimstatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
2958261991Sdim                                   uint64_t Address, const void *Decoder) {
2959261991Sdim  unsigned type = fieldFromInstruction(Insn, 8, 4);
2960261991Sdim  unsigned align = fieldFromInstruction(Insn, 4, 2);
2961261991Sdim  if (type == 6 && (align & 2)) return MCDisassembler::Fail;
2962261991Sdim  if (type == 7 && (align & 2)) return MCDisassembler::Fail;
2963261991Sdim  if (type == 10 && align == 3) return MCDisassembler::Fail;
2964261991Sdim
2965261991Sdim  unsigned load = fieldFromInstruction(Insn, 21, 1);
2966261991Sdim  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2967261991Sdim              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2968261991Sdim}
2969261991Sdim
2970261991Sdimstatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
2971261991Sdim                                   uint64_t Address, const void *Decoder) {
2972261991Sdim  unsigned size = fieldFromInstruction(Insn, 6, 2);
2973261991Sdim  if (size == 3) return MCDisassembler::Fail;
2974261991Sdim
2975261991Sdim  unsigned type = fieldFromInstruction(Insn, 8, 4);
2976261991Sdim  unsigned align = fieldFromInstruction(Insn, 4, 2);
2977261991Sdim  if (type == 8 && align == 3) return MCDisassembler::Fail;
2978261991Sdim  if (type == 9 && align == 3) return MCDisassembler::Fail;
2979261991Sdim
2980261991Sdim  unsigned load = fieldFromInstruction(Insn, 21, 1);
2981261991Sdim  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2982261991Sdim              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2983261991Sdim}
2984261991Sdim
2985261991Sdimstatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
2986261991Sdim                                   uint64_t Address, const void *Decoder) {
2987261991Sdim  unsigned size = fieldFromInstruction(Insn, 6, 2);
2988261991Sdim  if (size == 3) return MCDisassembler::Fail;
2989261991Sdim
2990261991Sdim  unsigned align = fieldFromInstruction(Insn, 4, 2);
2991261991Sdim  if (align & 2) return MCDisassembler::Fail;
2992261991Sdim
2993261991Sdim  unsigned load = fieldFromInstruction(Insn, 21, 1);
2994261991Sdim  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2995261991Sdim              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2996261991Sdim}
2997261991Sdim
2998261991Sdimstatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
2999261991Sdim                                   uint64_t Address, const void *Decoder) {
3000261991Sdim  unsigned size = fieldFromInstruction(Insn, 6, 2);
3001261991Sdim  if (size == 3) return MCDisassembler::Fail;
3002261991Sdim
3003261991Sdim  unsigned load = fieldFromInstruction(Insn, 21, 1);
3004261991Sdim  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
3005261991Sdim              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
3006261991Sdim}
3007261991Sdim
3008234353Sdimstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
3009226633Sdim                                 uint64_t Address, const void *Decoder) {
3010226633Sdim  DecodeStatus S = MCDisassembler::Success;
3011226633Sdim
3012239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3013239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3014239462Sdim  unsigned wb = fieldFromInstruction(Insn, 16, 4);
3015239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3016239462Sdim  Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
3017239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3018226633Sdim
3019226633Sdim  // Writeback Operand
3020226633Sdim  switch (Inst.getOpcode()) {
3021234353Sdim    case ARM::VST1d8wb_fixed:
3022234353Sdim    case ARM::VST1d16wb_fixed:
3023234353Sdim    case ARM::VST1d32wb_fixed:
3024234353Sdim    case ARM::VST1d64wb_fixed:
3025234353Sdim    case ARM::VST1d8wb_register:
3026234353Sdim    case ARM::VST1d16wb_register:
3027234353Sdim    case ARM::VST1d32wb_register:
3028234353Sdim    case ARM::VST1d64wb_register:
3029234353Sdim    case ARM::VST1q8wb_fixed:
3030234353Sdim    case ARM::VST1q16wb_fixed:
3031234353Sdim    case ARM::VST1q32wb_fixed:
3032234353Sdim    case ARM::VST1q64wb_fixed:
3033234353Sdim    case ARM::VST1q8wb_register:
3034234353Sdim    case ARM::VST1q16wb_register:
3035234353Sdim    case ARM::VST1q32wb_register:
3036234353Sdim    case ARM::VST1q64wb_register:
3037234353Sdim    case ARM::VST1d8Twb_fixed:
3038234353Sdim    case ARM::VST1d16Twb_fixed:
3039234353Sdim    case ARM::VST1d32Twb_fixed:
3040234353Sdim    case ARM::VST1d64Twb_fixed:
3041234353Sdim    case ARM::VST1d8Twb_register:
3042234353Sdim    case ARM::VST1d16Twb_register:
3043234353Sdim    case ARM::VST1d32Twb_register:
3044234353Sdim    case ARM::VST1d64Twb_register:
3045234353Sdim    case ARM::VST1d8Qwb_fixed:
3046234353Sdim    case ARM::VST1d16Qwb_fixed:
3047234353Sdim    case ARM::VST1d32Qwb_fixed:
3048234353Sdim    case ARM::VST1d64Qwb_fixed:
3049234353Sdim    case ARM::VST1d8Qwb_register:
3050234353Sdim    case ARM::VST1d16Qwb_register:
3051234353Sdim    case ARM::VST1d32Qwb_register:
3052234353Sdim    case ARM::VST1d64Qwb_register:
3053234353Sdim    case ARM::VST2d8wb_fixed:
3054234353Sdim    case ARM::VST2d16wb_fixed:
3055234353Sdim    case ARM::VST2d32wb_fixed:
3056234353Sdim    case ARM::VST2d8wb_register:
3057234353Sdim    case ARM::VST2d16wb_register:
3058234353Sdim    case ARM::VST2d32wb_register:
3059234353Sdim    case ARM::VST2q8wb_fixed:
3060234353Sdim    case ARM::VST2q16wb_fixed:
3061234353Sdim    case ARM::VST2q32wb_fixed:
3062234353Sdim    case ARM::VST2q8wb_register:
3063234353Sdim    case ARM::VST2q16wb_register:
3064234353Sdim    case ARM::VST2q32wb_register:
3065234353Sdim    case ARM::VST2b8wb_fixed:
3066234353Sdim    case ARM::VST2b16wb_fixed:
3067234353Sdim    case ARM::VST2b32wb_fixed:
3068234353Sdim    case ARM::VST2b8wb_register:
3069234353Sdim    case ARM::VST2b16wb_register:
3070234353Sdim    case ARM::VST2b32wb_register:
3071234353Sdim      if (Rm == 0xF)
3072234353Sdim        return MCDisassembler::Fail;
3073288943Sdim      Inst.addOperand(MCOperand::createImm(0));
3074234353Sdim      break;
3075226633Sdim    case ARM::VST3d8_UPD:
3076226633Sdim    case ARM::VST3d16_UPD:
3077226633Sdim    case ARM::VST3d32_UPD:
3078226633Sdim    case ARM::VST3q8_UPD:
3079226633Sdim    case ARM::VST3q16_UPD:
3080226633Sdim    case ARM::VST3q32_UPD:
3081226633Sdim    case ARM::VST4d8_UPD:
3082226633Sdim    case ARM::VST4d16_UPD:
3083226633Sdim    case ARM::VST4d32_UPD:
3084226633Sdim    case ARM::VST4q8_UPD:
3085226633Sdim    case ARM::VST4q16_UPD:
3086226633Sdim    case ARM::VST4q32_UPD:
3087226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
3088226633Sdim        return MCDisassembler::Fail;
3089226633Sdim      break;
3090226633Sdim    default:
3091226633Sdim      break;
3092226633Sdim  }
3093226633Sdim
3094226633Sdim  // AddrMode6 Base (register+alignment)
3095226633Sdim  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
3096226633Sdim    return MCDisassembler::Fail;
3097226633Sdim
3098226633Sdim  // AddrMode6 Offset (register)
3099234353Sdim  switch (Inst.getOpcode()) {
3100234353Sdim    default:
3101234353Sdim      if (Rm == 0xD)
3102288943Sdim        Inst.addOperand(MCOperand::createReg(0));
3103234353Sdim      else if (Rm != 0xF) {
3104234353Sdim        if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3105234353Sdim          return MCDisassembler::Fail;
3106234353Sdim      }
3107234353Sdim      break;
3108234353Sdim    case ARM::VST1d8wb_fixed:
3109234353Sdim    case ARM::VST1d16wb_fixed:
3110234353Sdim    case ARM::VST1d32wb_fixed:
3111234353Sdim    case ARM::VST1d64wb_fixed:
3112234353Sdim    case ARM::VST1q8wb_fixed:
3113234353Sdim    case ARM::VST1q16wb_fixed:
3114234353Sdim    case ARM::VST1q32wb_fixed:
3115234353Sdim    case ARM::VST1q64wb_fixed:
3116234353Sdim    case ARM::VST1d8Twb_fixed:
3117234353Sdim    case ARM::VST1d16Twb_fixed:
3118234353Sdim    case ARM::VST1d32Twb_fixed:
3119234353Sdim    case ARM::VST1d64Twb_fixed:
3120234353Sdim    case ARM::VST1d8Qwb_fixed:
3121234353Sdim    case ARM::VST1d16Qwb_fixed:
3122234353Sdim    case ARM::VST1d32Qwb_fixed:
3123234353Sdim    case ARM::VST1d64Qwb_fixed:
3124234353Sdim    case ARM::VST2d8wb_fixed:
3125234353Sdim    case ARM::VST2d16wb_fixed:
3126234353Sdim    case ARM::VST2d32wb_fixed:
3127234353Sdim    case ARM::VST2q8wb_fixed:
3128234353Sdim    case ARM::VST2q16wb_fixed:
3129234353Sdim    case ARM::VST2q32wb_fixed:
3130234353Sdim    case ARM::VST2b8wb_fixed:
3131234353Sdim    case ARM::VST2b16wb_fixed:
3132234353Sdim    case ARM::VST2b32wb_fixed:
3133234353Sdim      break;
3134226633Sdim  }
3135226633Sdim
3136226633Sdim  // First input register
3137234353Sdim  switch (Inst.getOpcode()) {
3138234353Sdim  case ARM::VST1q16:
3139234353Sdim  case ARM::VST1q32:
3140234353Sdim  case ARM::VST1q64:
3141234353Sdim  case ARM::VST1q8:
3142234353Sdim  case ARM::VST1q16wb_fixed:
3143234353Sdim  case ARM::VST1q16wb_register:
3144234353Sdim  case ARM::VST1q32wb_fixed:
3145234353Sdim  case ARM::VST1q32wb_register:
3146234353Sdim  case ARM::VST1q64wb_fixed:
3147234353Sdim  case ARM::VST1q64wb_register:
3148234353Sdim  case ARM::VST1q8wb_fixed:
3149234353Sdim  case ARM::VST1q8wb_register:
3150234353Sdim  case ARM::VST2d16:
3151234353Sdim  case ARM::VST2d32:
3152234353Sdim  case ARM::VST2d8:
3153234353Sdim  case ARM::VST2d16wb_fixed:
3154234353Sdim  case ARM::VST2d16wb_register:
3155234353Sdim  case ARM::VST2d32wb_fixed:
3156234353Sdim  case ARM::VST2d32wb_register:
3157234353Sdim  case ARM::VST2d8wb_fixed:
3158234353Sdim  case ARM::VST2d8wb_register:
3159234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
3160234353Sdim      return MCDisassembler::Fail;
3161234353Sdim    break;
3162234353Sdim  case ARM::VST2b16:
3163234353Sdim  case ARM::VST2b32:
3164234353Sdim  case ARM::VST2b8:
3165234353Sdim  case ARM::VST2b16wb_fixed:
3166234353Sdim  case ARM::VST2b16wb_register:
3167234353Sdim  case ARM::VST2b32wb_fixed:
3168234353Sdim  case ARM::VST2b32wb_register:
3169234353Sdim  case ARM::VST2b8wb_fixed:
3170234353Sdim  case ARM::VST2b8wb_register:
3171234353Sdim    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
3172234353Sdim      return MCDisassembler::Fail;
3173234353Sdim    break;
3174234353Sdim  default:
3175234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3176234353Sdim      return MCDisassembler::Fail;
3177234353Sdim  }
3178226633Sdim
3179226633Sdim  // Second input register
3180226633Sdim  switch (Inst.getOpcode()) {
3181226633Sdim    case ARM::VST3d8:
3182226633Sdim    case ARM::VST3d16:
3183226633Sdim    case ARM::VST3d32:
3184226633Sdim    case ARM::VST3d8_UPD:
3185226633Sdim    case ARM::VST3d16_UPD:
3186226633Sdim    case ARM::VST3d32_UPD:
3187226633Sdim    case ARM::VST4d8:
3188226633Sdim    case ARM::VST4d16:
3189226633Sdim    case ARM::VST4d32:
3190226633Sdim    case ARM::VST4d8_UPD:
3191226633Sdim    case ARM::VST4d16_UPD:
3192226633Sdim    case ARM::VST4d32_UPD:
3193226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
3194226633Sdim        return MCDisassembler::Fail;
3195226633Sdim      break;
3196226633Sdim    case ARM::VST3q8:
3197226633Sdim    case ARM::VST3q16:
3198226633Sdim    case ARM::VST3q32:
3199226633Sdim    case ARM::VST3q8_UPD:
3200226633Sdim    case ARM::VST3q16_UPD:
3201226633Sdim    case ARM::VST3q32_UPD:
3202226633Sdim    case ARM::VST4q8:
3203226633Sdim    case ARM::VST4q16:
3204226633Sdim    case ARM::VST4q32:
3205226633Sdim    case ARM::VST4q8_UPD:
3206226633Sdim    case ARM::VST4q16_UPD:
3207226633Sdim    case ARM::VST4q32_UPD:
3208226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
3209226633Sdim        return MCDisassembler::Fail;
3210226633Sdim      break;
3211226633Sdim    default:
3212226633Sdim      break;
3213226633Sdim  }
3214226633Sdim
3215226633Sdim  // Third input register
3216226633Sdim  switch (Inst.getOpcode()) {
3217226633Sdim    case ARM::VST3d8:
3218226633Sdim    case ARM::VST3d16:
3219226633Sdim    case ARM::VST3d32:
3220226633Sdim    case ARM::VST3d8_UPD:
3221226633Sdim    case ARM::VST3d16_UPD:
3222226633Sdim    case ARM::VST3d32_UPD:
3223226633Sdim    case ARM::VST4d8:
3224226633Sdim    case ARM::VST4d16:
3225226633Sdim    case ARM::VST4d32:
3226226633Sdim    case ARM::VST4d8_UPD:
3227226633Sdim    case ARM::VST4d16_UPD:
3228226633Sdim    case ARM::VST4d32_UPD:
3229226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
3230226633Sdim        return MCDisassembler::Fail;
3231226633Sdim      break;
3232226633Sdim    case ARM::VST3q8:
3233226633Sdim    case ARM::VST3q16:
3234226633Sdim    case ARM::VST3q32:
3235226633Sdim    case ARM::VST3q8_UPD:
3236226633Sdim    case ARM::VST3q16_UPD:
3237226633Sdim    case ARM::VST3q32_UPD:
3238226633Sdim    case ARM::VST4q8:
3239226633Sdim    case ARM::VST4q16:
3240226633Sdim    case ARM::VST4q32:
3241226633Sdim    case ARM::VST4q8_UPD:
3242226633Sdim    case ARM::VST4q16_UPD:
3243226633Sdim    case ARM::VST4q32_UPD:
3244226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
3245226633Sdim        return MCDisassembler::Fail;
3246226633Sdim      break;
3247226633Sdim    default:
3248226633Sdim      break;
3249226633Sdim  }
3250226633Sdim
3251226633Sdim  // Fourth input register
3252226633Sdim  switch (Inst.getOpcode()) {
3253226633Sdim    case ARM::VST4d8:
3254226633Sdim    case ARM::VST4d16:
3255226633Sdim    case ARM::VST4d32:
3256226633Sdim    case ARM::VST4d8_UPD:
3257226633Sdim    case ARM::VST4d16_UPD:
3258226633Sdim    case ARM::VST4d32_UPD:
3259226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
3260226633Sdim        return MCDisassembler::Fail;
3261226633Sdim      break;
3262226633Sdim    case ARM::VST4q8:
3263226633Sdim    case ARM::VST4q16:
3264226633Sdim    case ARM::VST4q32:
3265226633Sdim    case ARM::VST4q8_UPD:
3266226633Sdim    case ARM::VST4q16_UPD:
3267226633Sdim    case ARM::VST4q32_UPD:
3268226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
3269226633Sdim        return MCDisassembler::Fail;
3270226633Sdim      break;
3271226633Sdim    default:
3272226633Sdim      break;
3273226633Sdim  }
3274226633Sdim
3275226633Sdim  return S;
3276226633Sdim}
3277226633Sdim
3278234353Sdimstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
3279226633Sdim                                    uint64_t Address, const void *Decoder) {
3280226633Sdim  DecodeStatus S = MCDisassembler::Success;
3281226633Sdim
3282239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3283239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3284239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3285239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3286239462Sdim  unsigned align = fieldFromInstruction(Insn, 4, 1);
3287239462Sdim  unsigned size = fieldFromInstruction(Insn, 6, 2);
3288226633Sdim
3289243830Sdim  if (size == 0 && align == 1)
3290243830Sdim    return MCDisassembler::Fail;
3291226633Sdim  align *= (1 << size);
3292226633Sdim
3293234353Sdim  switch (Inst.getOpcode()) {
3294234353Sdim  case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
3295234353Sdim  case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
3296234353Sdim  case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
3297234353Sdim  case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
3298234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
3299226633Sdim      return MCDisassembler::Fail;
3300234353Sdim    break;
3301234353Sdim  default:
3302234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3303234353Sdim      return MCDisassembler::Fail;
3304234353Sdim    break;
3305226633Sdim  }
3306226633Sdim  if (Rm != 0xF) {
3307226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3308226633Sdim      return MCDisassembler::Fail;
3309226633Sdim  }
3310226633Sdim
3311226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3312226633Sdim    return MCDisassembler::Fail;
3313288943Sdim  Inst.addOperand(MCOperand::createImm(align));
3314226633Sdim
3315234353Sdim  // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
3316234353Sdim  // variant encodes Rm == 0xf. Anything else is a register offset post-
3317234353Sdim  // increment and we need to add the register operand to the instruction.
3318234353Sdim  if (Rm != 0xD && Rm != 0xF &&
3319234353Sdim      !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3320234353Sdim    return MCDisassembler::Fail;
3321226633Sdim
3322226633Sdim  return S;
3323226633Sdim}
3324226633Sdim
3325234353Sdimstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
3326226633Sdim                                    uint64_t Address, const void *Decoder) {
3327226633Sdim  DecodeStatus S = MCDisassembler::Success;
3328226633Sdim
3329239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3330239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3331239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3332239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3333239462Sdim  unsigned align = fieldFromInstruction(Insn, 4, 1);
3334239462Sdim  unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
3335226633Sdim  align *= 2*size;
3336226633Sdim
3337234353Sdim  switch (Inst.getOpcode()) {
3338234353Sdim  case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
3339234353Sdim  case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
3340234353Sdim  case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
3341234353Sdim  case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
3342234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
3343226633Sdim      return MCDisassembler::Fail;
3344234353Sdim    break;
3345234353Sdim  case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
3346234353Sdim  case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
3347234353Sdim  case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
3348234353Sdim  case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
3349234353Sdim    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
3350234353Sdim      return MCDisassembler::Fail;
3351234353Sdim    break;
3352234353Sdim  default:
3353234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3354234353Sdim      return MCDisassembler::Fail;
3355234353Sdim    break;
3356226633Sdim  }
3357226633Sdim
3358234353Sdim  if (Rm != 0xF)
3359288943Sdim    Inst.addOperand(MCOperand::createImm(0));
3360234353Sdim
3361226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3362226633Sdim    return MCDisassembler::Fail;
3363288943Sdim  Inst.addOperand(MCOperand::createImm(align));
3364226633Sdim
3365234982Sdim  if (Rm != 0xD && Rm != 0xF) {
3366226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3367226633Sdim      return MCDisassembler::Fail;
3368226633Sdim  }
3369226633Sdim
3370226633Sdim  return S;
3371226633Sdim}
3372226633Sdim
3373234353Sdimstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
3374226633Sdim                                    uint64_t Address, const void *Decoder) {
3375226633Sdim  DecodeStatus S = MCDisassembler::Success;
3376226633Sdim
3377239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3378239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3379239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3380239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3381239462Sdim  unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
3382226633Sdim
3383226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3384226633Sdim    return MCDisassembler::Fail;
3385226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
3386226633Sdim    return MCDisassembler::Fail;
3387226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
3388226633Sdim    return MCDisassembler::Fail;
3389226633Sdim  if (Rm != 0xF) {
3390226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3391226633Sdim      return MCDisassembler::Fail;
3392226633Sdim  }
3393226633Sdim
3394226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3395226633Sdim    return MCDisassembler::Fail;
3396288943Sdim  Inst.addOperand(MCOperand::createImm(0));
3397226633Sdim
3398226633Sdim  if (Rm == 0xD)
3399288943Sdim    Inst.addOperand(MCOperand::createReg(0));
3400226633Sdim  else if (Rm != 0xF) {
3401226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3402226633Sdim      return MCDisassembler::Fail;
3403226633Sdim  }
3404226633Sdim
3405226633Sdim  return S;
3406226633Sdim}
3407226633Sdim
3408234353Sdimstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
3409226633Sdim                                    uint64_t Address, const void *Decoder) {
3410226633Sdim  DecodeStatus S = MCDisassembler::Success;
3411226633Sdim
3412239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3413239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3414239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3415239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3416239462Sdim  unsigned size = fieldFromInstruction(Insn, 6, 2);
3417239462Sdim  unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
3418239462Sdim  unsigned align = fieldFromInstruction(Insn, 4, 1);
3419226633Sdim
3420226633Sdim  if (size == 0x3) {
3421243830Sdim    if (align == 0)
3422243830Sdim      return MCDisassembler::Fail;
3423226633Sdim    align = 16;
3424226633Sdim  } else {
3425226633Sdim    if (size == 2) {
3426226633Sdim      align *= 8;
3427226633Sdim    } else {
3428226633Sdim      size = 1 << size;
3429226633Sdim      align *= 4*size;
3430206124Srdivacky    }
3431206124Srdivacky  }
3432206124Srdivacky
3433226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3434226633Sdim    return MCDisassembler::Fail;
3435226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
3436226633Sdim    return MCDisassembler::Fail;
3437226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
3438226633Sdim    return MCDisassembler::Fail;
3439226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
3440226633Sdim    return MCDisassembler::Fail;
3441226633Sdim  if (Rm != 0xF) {
3442226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3443226633Sdim      return MCDisassembler::Fail;
3444226633Sdim  }
3445226633Sdim
3446226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3447226633Sdim    return MCDisassembler::Fail;
3448288943Sdim  Inst.addOperand(MCOperand::createImm(align));
3449226633Sdim
3450226633Sdim  if (Rm == 0xD)
3451288943Sdim    Inst.addOperand(MCOperand::createReg(0));
3452226633Sdim  else if (Rm != 0xF) {
3453226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3454226633Sdim      return MCDisassembler::Fail;
3455226633Sdim  }
3456226633Sdim
3457226633Sdim  return S;
3458206124Srdivacky}
3459206124Srdivacky
3460226633Sdimstatic DecodeStatus
3461360784SdimDecodeVMOVModImmInstruction(MCInst &Inst, unsigned Insn,
3462226633Sdim                            uint64_t Address, const void *Decoder) {
3463226633Sdim  DecodeStatus S = MCDisassembler::Success;
3464206124Srdivacky
3465239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3466239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3467239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 4);
3468239462Sdim  imm |= fieldFromInstruction(Insn, 16, 3) << 4;
3469239462Sdim  imm |= fieldFromInstruction(Insn, 24, 1) << 7;
3470239462Sdim  imm |= fieldFromInstruction(Insn, 8, 4) << 8;
3471239462Sdim  imm |= fieldFromInstruction(Insn, 5, 1) << 12;
3472239462Sdim  unsigned Q = fieldFromInstruction(Insn, 6, 1);
3473206124Srdivacky
3474226633Sdim  if (Q) {
3475226633Sdim    if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3476226633Sdim    return MCDisassembler::Fail;
3477226633Sdim  } else {
3478226633Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3479226633Sdim    return MCDisassembler::Fail;
3480226633Sdim  }
3481206124Srdivacky
3482288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
3483206124Srdivacky
3484226633Sdim  switch (Inst.getOpcode()) {
3485226633Sdim    case ARM::VORRiv4i16:
3486226633Sdim    case ARM::VORRiv2i32:
3487226633Sdim    case ARM::VBICiv4i16:
3488226633Sdim    case ARM::VBICiv2i32:
3489226633Sdim      if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3490226633Sdim        return MCDisassembler::Fail;
3491226633Sdim      break;
3492226633Sdim    case ARM::VORRiv8i16:
3493226633Sdim    case ARM::VORRiv4i32:
3494226633Sdim    case ARM::VBICiv8i16:
3495226633Sdim    case ARM::VBICiv4i32:
3496226633Sdim      if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3497226633Sdim        return MCDisassembler::Fail;
3498226633Sdim      break;
3499226633Sdim    default:
3500226633Sdim      break;
3501226633Sdim  }
3502206124Srdivacky
3503226633Sdim  return S;
3504226633Sdim}
3505226633Sdim
3506353358Sdimstatic DecodeStatus
3507353358SdimDecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
3508353358Sdim                           uint64_t Address, const void *Decoder) {
3509353358Sdim  DecodeStatus S = MCDisassembler::Success;
3510353358Sdim
3511353358Sdim  unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
3512353358Sdim                 fieldFromInstruction(Insn, 13, 3));
3513353358Sdim  unsigned cmode = fieldFromInstruction(Insn, 8, 4);
3514353358Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 4);
3515353358Sdim  imm |= fieldFromInstruction(Insn, 16, 3) << 4;
3516353358Sdim  imm |= fieldFromInstruction(Insn, 28, 1) << 7;
3517353358Sdim  imm |= cmode                             << 8;
3518353358Sdim  imm |= fieldFromInstruction(Insn, 5, 1)  << 12;
3519353358Sdim
3520353358Sdim  if (cmode == 0xF && Inst.getOpcode() == ARM::MVE_VMVNimmi32)
3521353358Sdim    return MCDisassembler::Fail;
3522353358Sdim
3523353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
3524353358Sdim    return MCDisassembler::Fail;
3525353358Sdim
3526353358Sdim  Inst.addOperand(MCOperand::createImm(imm));
3527353358Sdim
3528353358Sdim  Inst.addOperand(MCOperand::createImm(ARMVCC::None));
3529353358Sdim  Inst.addOperand(MCOperand::createReg(0));
3530353358Sdim  Inst.addOperand(MCOperand::createImm(0));
3531353358Sdim
3532353358Sdim  return S;
3533353358Sdim}
3534353358Sdim
3535353358Sdimstatic DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
3536353358Sdim                               uint64_t Address, const void *Decoder) {
3537353358Sdim  DecodeStatus S = MCDisassembler::Success;
3538353358Sdim
3539353358Sdim  unsigned Qd = fieldFromInstruction(Insn, 13, 3);
3540353358Sdim  Qd |= fieldFromInstruction(Insn, 22, 1) << 3;
3541353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
3542353358Sdim    return MCDisassembler::Fail;
3543353358Sdim  Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
3544353358Sdim
3545353358Sdim  unsigned Qn = fieldFromInstruction(Insn, 17, 3);
3546353358Sdim  Qn |= fieldFromInstruction(Insn, 7, 1) << 3;
3547353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
3548353358Sdim    return MCDisassembler::Fail;
3549353358Sdim  unsigned Qm = fieldFromInstruction(Insn, 1, 3);
3550353358Sdim  Qm |= fieldFromInstruction(Insn, 5, 1) << 3;
3551353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
3552353358Sdim    return MCDisassembler::Fail;
3553353358Sdim  if (!fieldFromInstruction(Insn, 12, 1)) // I bit clear => need input FPSCR
3554353358Sdim    Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
3555353358Sdim  Inst.addOperand(MCOperand::createImm(Qd));
3556353358Sdim
3557353358Sdim  return S;
3558353358Sdim}
3559353358Sdim
3560234353Sdimstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
3561226633Sdim                                        uint64_t Address, const void *Decoder) {
3562226633Sdim  DecodeStatus S = MCDisassembler::Success;
3563226633Sdim
3564239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3565239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3566239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3567239462Sdim  Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3568239462Sdim  unsigned size = fieldFromInstruction(Insn, 18, 2);
3569226633Sdim
3570226633Sdim  if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3571226633Sdim    return MCDisassembler::Fail;
3572226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3573226633Sdim    return MCDisassembler::Fail;
3574288943Sdim  Inst.addOperand(MCOperand::createImm(8 << size));
3575226633Sdim
3576226633Sdim  return S;
3577226633Sdim}
3578226633Sdim
3579234353Sdimstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
3580226633Sdim                               uint64_t Address, const void *Decoder) {
3581288943Sdim  Inst.addOperand(MCOperand::createImm(8 - Val));
3582226633Sdim  return MCDisassembler::Success;
3583226633Sdim}
3584226633Sdim
3585234353Sdimstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
3586226633Sdim                               uint64_t Address, const void *Decoder) {
3587288943Sdim  Inst.addOperand(MCOperand::createImm(16 - Val));
3588226633Sdim  return MCDisassembler::Success;
3589226633Sdim}
3590226633Sdim
3591234353Sdimstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
3592226633Sdim                               uint64_t Address, const void *Decoder) {
3593288943Sdim  Inst.addOperand(MCOperand::createImm(32 - Val));
3594226633Sdim  return MCDisassembler::Success;
3595226633Sdim}
3596226633Sdim
3597234353Sdimstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
3598226633Sdim                               uint64_t Address, const void *Decoder) {
3599288943Sdim  Inst.addOperand(MCOperand::createImm(64 - Val));
3600226633Sdim  return MCDisassembler::Success;
3601226633Sdim}
3602226633Sdim
3603234353Sdimstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
3604226633Sdim                               uint64_t Address, const void *Decoder) {
3605226633Sdim  DecodeStatus S = MCDisassembler::Success;
3606226633Sdim
3607239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3608239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3609239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3610239462Sdim  Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
3611239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3612239462Sdim  Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3613239462Sdim  unsigned op = fieldFromInstruction(Insn, 6, 1);
3614226633Sdim
3615226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3616226633Sdim    return MCDisassembler::Fail;
3617226633Sdim  if (op) {
3618226633Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3619226633Sdim    return MCDisassembler::Fail; // Writeback
3620206124Srdivacky  }
3621226633Sdim
3622234353Sdim  switch (Inst.getOpcode()) {
3623234353Sdim  case ARM::VTBL2:
3624234353Sdim  case ARM::VTBX2:
3625234353Sdim    if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
3626234353Sdim      return MCDisassembler::Fail;
3627234353Sdim    break;
3628234353Sdim  default:
3629234353Sdim    if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
3630234353Sdim      return MCDisassembler::Fail;
3631226633Sdim  }
3632226633Sdim
3633226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3634226633Sdim    return MCDisassembler::Fail;
3635226633Sdim
3636226633Sdim  return S;
3637206124Srdivacky}
3638206124Srdivacky
3639234353Sdimstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
3640226633Sdim                                     uint64_t Address, const void *Decoder) {
3641226633Sdim  DecodeStatus S = MCDisassembler::Success;
3642221345Sdim
3643239462Sdim  unsigned dst = fieldFromInstruction(Insn, 8, 3);
3644239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 8);
3645221345Sdim
3646226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
3647226633Sdim    return MCDisassembler::Fail;
3648226633Sdim
3649226633Sdim  switch(Inst.getOpcode()) {
3650226633Sdim    default:
3651226633Sdim      return MCDisassembler::Fail;
3652226633Sdim    case ARM::tADR:
3653226633Sdim      break; // tADR does not explicitly represent the PC as an operand.
3654226633Sdim    case ARM::tADDrSPi:
3655288943Sdim      Inst.addOperand(MCOperand::createReg(ARM::SP));
3656226633Sdim      break;
3657221345Sdim  }
3658226633Sdim
3659288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
3660226633Sdim  return S;
3661221345Sdim}
3662221345Sdim
3663234353Sdimstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
3664226633Sdim                                 uint64_t Address, const void *Decoder) {
3665234353Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
3666234353Sdim                                true, 2, Inst, Decoder))
3667288943Sdim    Inst.addOperand(MCOperand::createImm(SignExtend32<12>(Val << 1)));
3668226633Sdim  return MCDisassembler::Success;
3669226633Sdim}
3670206124Srdivacky
3671234353Sdimstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
3672226633Sdim                                 uint64_t Address, const void *Decoder) {
3673239462Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
3674234353Sdim                                true, 4, Inst, Decoder))
3675288943Sdim    Inst.addOperand(MCOperand::createImm(SignExtend32<21>(Val)));
3676226633Sdim  return MCDisassembler::Success;
3677226633Sdim}
3678206124Srdivacky
3679234353Sdimstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
3680226633Sdim                                 uint64_t Address, const void *Decoder) {
3681249423Sdim  if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
3682234353Sdim                                true, 2, Inst, Decoder))
3683288943Sdim    Inst.addOperand(MCOperand::createImm(Val << 1));
3684226633Sdim  return MCDisassembler::Success;
3685226633Sdim}
3686206124Srdivacky
3687234353Sdimstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
3688226633Sdim                                 uint64_t Address, const void *Decoder) {
3689226633Sdim  DecodeStatus S = MCDisassembler::Success;
3690206124Srdivacky
3691239462Sdim  unsigned Rn = fieldFromInstruction(Val, 0, 3);
3692239462Sdim  unsigned Rm = fieldFromInstruction(Val, 3, 3);
3693226633Sdim
3694226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3695226633Sdim    return MCDisassembler::Fail;
3696226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
3697226633Sdim    return MCDisassembler::Fail;
3698226633Sdim
3699226633Sdim  return S;
3700226633Sdim}
3701226633Sdim
3702234353Sdimstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
3703226633Sdim                                  uint64_t Address, const void *Decoder) {
3704226633Sdim  DecodeStatus S = MCDisassembler::Success;
3705226633Sdim
3706239462Sdim  unsigned Rn = fieldFromInstruction(Val, 0, 3);
3707239462Sdim  unsigned imm = fieldFromInstruction(Val, 3, 5);
3708226633Sdim
3709226633Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3710226633Sdim    return MCDisassembler::Fail;
3711288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
3712226633Sdim
3713226633Sdim  return S;
3714226633Sdim}
3715226633Sdim
3716234353Sdimstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
3717226633Sdim                                  uint64_t Address, const void *Decoder) {
3718226633Sdim  unsigned imm = Val << 2;
3719226633Sdim
3720288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
3721226633Sdim  tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
3722226633Sdim
3723226633Sdim  return MCDisassembler::Success;
3724226633Sdim}
3725226633Sdim
3726234353Sdimstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
3727226633Sdim                                  uint64_t Address, const void *Decoder) {
3728288943Sdim  Inst.addOperand(MCOperand::createReg(ARM::SP));
3729288943Sdim  Inst.addOperand(MCOperand::createImm(Val));
3730226633Sdim
3731226633Sdim  return MCDisassembler::Success;
3732226633Sdim}
3733226633Sdim
3734234353Sdimstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
3735226633Sdim                                  uint64_t Address, const void *Decoder) {
3736226633Sdim  DecodeStatus S = MCDisassembler::Success;
3737226633Sdim
3738239462Sdim  unsigned Rn = fieldFromInstruction(Val, 6, 4);
3739239462Sdim  unsigned Rm = fieldFromInstruction(Val, 2, 4);
3740239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 2);
3741226633Sdim
3742261991Sdim  // Thumb stores cannot use PC as dest register.
3743261991Sdim  switch (Inst.getOpcode()) {
3744261991Sdim  case ARM::t2STRHs:
3745261991Sdim  case ARM::t2STRBs:
3746261991Sdim  case ARM::t2STRs:
3747261991Sdim    if (Rn == 15)
3748261991Sdim      return MCDisassembler::Fail;
3749327952Sdim    break;
3750261991Sdim  default:
3751261991Sdim    break;
3752261991Sdim  }
3753261991Sdim
3754226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3755226633Sdim    return MCDisassembler::Fail;
3756226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3757226633Sdim    return MCDisassembler::Fail;
3758288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
3759226633Sdim
3760226633Sdim  return S;
3761226633Sdim}
3762226633Sdim
3763234353Sdimstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
3764226633Sdim                              uint64_t Address, const void *Decoder) {
3765226633Sdim  DecodeStatus S = MCDisassembler::Success;
3766226633Sdim
3767261991Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3768261991Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3769261991Sdim
3770288943Sdim  const FeatureBitset &featureBits =
3771288943Sdim    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3772280031Sdim
3773288943Sdim  bool hasMP = featureBits[ARM::FeatureMP];
3774288943Sdim  bool hasV7Ops = featureBits[ARM::HasV7Ops];
3775288943Sdim
3776261991Sdim  if (Rn == 15) {
3777261991Sdim    switch (Inst.getOpcode()) {
3778261991Sdim    case ARM::t2LDRBs:
3779261991Sdim      Inst.setOpcode(ARM::t2LDRBpci);
3780261991Sdim      break;
3781261991Sdim    case ARM::t2LDRHs:
3782261991Sdim      Inst.setOpcode(ARM::t2LDRHpci);
3783261991Sdim      break;
3784261991Sdim    case ARM::t2LDRSHs:
3785261991Sdim      Inst.setOpcode(ARM::t2LDRSHpci);
3786261991Sdim      break;
3787261991Sdim    case ARM::t2LDRSBs:
3788261991Sdim      Inst.setOpcode(ARM::t2LDRSBpci);
3789261991Sdim      break;
3790261991Sdim    case ARM::t2LDRs:
3791261991Sdim      Inst.setOpcode(ARM::t2LDRpci);
3792261991Sdim      break;
3793261991Sdim    case ARM::t2PLDs:
3794261991Sdim      Inst.setOpcode(ARM::t2PLDpci);
3795261991Sdim      break;
3796261991Sdim    case ARM::t2PLIs:
3797261991Sdim      Inst.setOpcode(ARM::t2PLIpci);
3798261991Sdim      break;
3799261991Sdim    default:
3800261991Sdim      return MCDisassembler::Fail;
3801261991Sdim    }
3802261991Sdim
3803261991Sdim    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3804261991Sdim  }
3805261991Sdim
3806261991Sdim  if (Rt == 15) {
3807261991Sdim    switch (Inst.getOpcode()) {
3808261991Sdim    case ARM::t2LDRSHs:
3809261991Sdim      return MCDisassembler::Fail;
3810261991Sdim    case ARM::t2LDRHs:
3811261991Sdim      Inst.setOpcode(ARM::t2PLDWs);
3812261991Sdim      break;
3813280031Sdim    case ARM::t2LDRSBs:
3814280031Sdim      Inst.setOpcode(ARM::t2PLIs);
3815327952Sdim      break;
3816261991Sdim    default:
3817261991Sdim      break;
3818261991Sdim    }
3819261991Sdim  }
3820261991Sdim
3821226633Sdim  switch (Inst.getOpcode()) {
3822226633Sdim    case ARM::t2PLDs:
3823280031Sdim      break;
3824226633Sdim    case ARM::t2PLIs:
3825280031Sdim      if (!hasV7Ops)
3826280031Sdim        return MCDisassembler::Fail;
3827226633Sdim      break;
3828280031Sdim    case ARM::t2PLDWs:
3829280031Sdim      if (!hasV7Ops || !hasMP)
3830280031Sdim        return MCDisassembler::Fail;
3831280031Sdim      break;
3832261991Sdim    default:
3833261991Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3834261991Sdim        return MCDisassembler::Fail;
3835261991Sdim  }
3836261991Sdim
3837261991Sdim  unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
3838261991Sdim  addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
3839261991Sdim  addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
3840261991Sdim  if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
3841226633Sdim    return MCDisassembler::Fail;
3842261991Sdim
3843261991Sdim  return S;
3844261991Sdim}
3845261991Sdim
3846261991Sdimstatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
3847261991Sdim                                uint64_t Address, const void* Decoder) {
3848261991Sdim  DecodeStatus S = MCDisassembler::Success;
3849261991Sdim
3850261991Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3851261991Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3852261991Sdim  unsigned U = fieldFromInstruction(Insn, 9, 1);
3853261991Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 8);
3854261991Sdim  imm |= (U << 8);
3855261991Sdim  imm |= (Rn << 9);
3856280031Sdim  unsigned add = fieldFromInstruction(Insn, 9, 1);
3857261991Sdim
3858288943Sdim  const FeatureBitset &featureBits =
3859288943Sdim    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3860280031Sdim
3861288943Sdim  bool hasMP = featureBits[ARM::FeatureMP];
3862288943Sdim  bool hasV7Ops = featureBits[ARM::HasV7Ops];
3863288943Sdim
3864261991Sdim  if (Rn == 15) {
3865261991Sdim    switch (Inst.getOpcode()) {
3866261991Sdim    case ARM::t2LDRi8:
3867261991Sdim      Inst.setOpcode(ARM::t2LDRpci);
3868261991Sdim      break;
3869261991Sdim    case ARM::t2LDRBi8:
3870261991Sdim      Inst.setOpcode(ARM::t2LDRBpci);
3871261991Sdim      break;
3872261991Sdim    case ARM::t2LDRSBi8:
3873261991Sdim      Inst.setOpcode(ARM::t2LDRSBpci);
3874261991Sdim      break;
3875261991Sdim    case ARM::t2LDRHi8:
3876261991Sdim      Inst.setOpcode(ARM::t2LDRHpci);
3877261991Sdim      break;
3878261991Sdim    case ARM::t2LDRSHi8:
3879261991Sdim      Inst.setOpcode(ARM::t2LDRSHpci);
3880261991Sdim      break;
3881261991Sdim    case ARM::t2PLDi8:
3882261991Sdim      Inst.setOpcode(ARM::t2PLDpci);
3883261991Sdim      break;
3884261991Sdim    case ARM::t2PLIi8:
3885261991Sdim      Inst.setOpcode(ARM::t2PLIpci);
3886261991Sdim      break;
3887261991Sdim    default:
3888261991Sdim      return MCDisassembler::Fail;
3889206124Srdivacky    }
3890261991Sdim    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3891226633Sdim  }
3892206124Srdivacky
3893261991Sdim  if (Rt == 15) {
3894261991Sdim    switch (Inst.getOpcode()) {
3895261991Sdim    case ARM::t2LDRSHi8:
3896261991Sdim      return MCDisassembler::Fail;
3897280031Sdim    case ARM::t2LDRHi8:
3898280031Sdim      if (!add)
3899280031Sdim        Inst.setOpcode(ARM::t2PLDWi8);
3900280031Sdim      break;
3901280031Sdim    case ARM::t2LDRSBi8:
3902280031Sdim      Inst.setOpcode(ARM::t2PLIi8);
3903280031Sdim      break;
3904261991Sdim    default:
3905261991Sdim      break;
3906261991Sdim    }
3907261991Sdim  }
3908261991Sdim
3909261991Sdim  switch (Inst.getOpcode()) {
3910261991Sdim  case ARM::t2PLDi8:
3911280031Sdim    break;
3912261991Sdim  case ARM::t2PLIi8:
3913280031Sdim    if (!hasV7Ops)
3914280031Sdim      return MCDisassembler::Fail;
3915280031Sdim    break;
3916261991Sdim  case ARM::t2PLDWi8:
3917280031Sdim      if (!hasV7Ops || !hasMP)
3918280031Sdim        return MCDisassembler::Fail;
3919280031Sdim      break;
3920261991Sdim  default:
3921261991Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3922261991Sdim      return MCDisassembler::Fail;
3923261991Sdim  }
3924261991Sdim
3925261991Sdim  if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3926261991Sdim    return MCDisassembler::Fail;
3927261991Sdim  return S;
3928261991Sdim}
3929261991Sdim
3930261991Sdimstatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
3931261991Sdim                                uint64_t Address, const void* Decoder) {
3932261991Sdim  DecodeStatus S = MCDisassembler::Success;
3933261991Sdim
3934239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3935261991Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3936261991Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
3937261991Sdim  imm |= (Rn << 13);
3938261991Sdim
3939288943Sdim  const FeatureBitset &featureBits =
3940288943Sdim    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
3941280031Sdim
3942288943Sdim  bool hasMP = featureBits[ARM::FeatureMP];
3943288943Sdim  bool hasV7Ops = featureBits[ARM::HasV7Ops];
3944288943Sdim
3945261991Sdim  if (Rn == 15) {
3946226633Sdim    switch (Inst.getOpcode()) {
3947261991Sdim    case ARM::t2LDRi12:
3948261991Sdim      Inst.setOpcode(ARM::t2LDRpci);
3949261991Sdim      break;
3950261991Sdim    case ARM::t2LDRHi12:
3951261991Sdim      Inst.setOpcode(ARM::t2LDRHpci);
3952261991Sdim      break;
3953261991Sdim    case ARM::t2LDRSHi12:
3954261991Sdim      Inst.setOpcode(ARM::t2LDRSHpci);
3955261991Sdim      break;
3956261991Sdim    case ARM::t2LDRBi12:
3957261991Sdim      Inst.setOpcode(ARM::t2LDRBpci);
3958261991Sdim      break;
3959261991Sdim    case ARM::t2LDRSBi12:
3960261991Sdim      Inst.setOpcode(ARM::t2LDRSBpci);
3961261991Sdim      break;
3962261991Sdim    case ARM::t2PLDi12:
3963261991Sdim      Inst.setOpcode(ARM::t2PLDpci);
3964261991Sdim      break;
3965261991Sdim    case ARM::t2PLIi12:
3966261991Sdim      Inst.setOpcode(ARM::t2PLIpci);
3967261991Sdim      break;
3968261991Sdim    default:
3969261991Sdim      return MCDisassembler::Fail;
3970261991Sdim    }
3971261991Sdim    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3972261991Sdim  }
3973261991Sdim
3974261991Sdim  if (Rt == 15) {
3975261991Sdim    switch (Inst.getOpcode()) {
3976261991Sdim    case ARM::t2LDRSHi12:
3977261991Sdim      return MCDisassembler::Fail;
3978261991Sdim    case ARM::t2LDRHi12:
3979280031Sdim      Inst.setOpcode(ARM::t2PLDWi12);
3980261991Sdim      break;
3981280031Sdim    case ARM::t2LDRSBi12:
3982280031Sdim      Inst.setOpcode(ARM::t2PLIi12);
3983280031Sdim      break;
3984261991Sdim    default:
3985261991Sdim      break;
3986261991Sdim    }
3987261991Sdim  }
3988261991Sdim
3989261991Sdim  switch (Inst.getOpcode()) {
3990261991Sdim  case ARM::t2PLDi12:
3991280031Sdim    break;
3992261991Sdim  case ARM::t2PLIi12:
3993280031Sdim    if (!hasV7Ops)
3994280031Sdim      return MCDisassembler::Fail;
3995261991Sdim    break;
3996280031Sdim  case ARM::t2PLDWi12:
3997280031Sdim      if (!hasV7Ops || !hasMP)
3998280031Sdim        return MCDisassembler::Fail;
3999280031Sdim      break;
4000261991Sdim  default:
4001261991Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4002261991Sdim      return MCDisassembler::Fail;
4003261991Sdim  }
4004261991Sdim
4005261991Sdim  if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
4006261991Sdim    return MCDisassembler::Fail;
4007261991Sdim  return S;
4008261991Sdim}
4009261991Sdim
4010261991Sdimstatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
4011261991Sdim                                uint64_t Address, const void* Decoder) {
4012261991Sdim  DecodeStatus S = MCDisassembler::Success;
4013261991Sdim
4014261991Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4015261991Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4016261991Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 8);
4017261991Sdim  imm |= (Rn << 9);
4018261991Sdim
4019261991Sdim  if (Rn == 15) {
4020261991Sdim    switch (Inst.getOpcode()) {
4021261991Sdim    case ARM::t2LDRT:
4022261991Sdim      Inst.setOpcode(ARM::t2LDRpci);
4023261991Sdim      break;
4024261991Sdim    case ARM::t2LDRBT:
4025261991Sdim      Inst.setOpcode(ARM::t2LDRBpci);
4026261991Sdim      break;
4027261991Sdim    case ARM::t2LDRHT:
4028261991Sdim      Inst.setOpcode(ARM::t2LDRHpci);
4029261991Sdim      break;
4030261991Sdim    case ARM::t2LDRSBT:
4031261991Sdim      Inst.setOpcode(ARM::t2LDRSBpci);
4032261991Sdim      break;
4033261991Sdim    case ARM::t2LDRSHT:
4034261991Sdim      Inst.setOpcode(ARM::t2LDRSHpci);
4035261991Sdim      break;
4036261991Sdim    default:
4037261991Sdim      return MCDisassembler::Fail;
4038261991Sdim    }
4039261991Sdim    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
4040261991Sdim  }
4041261991Sdim
4042261991Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4043261991Sdim    return MCDisassembler::Fail;
4044261991Sdim  if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
4045261991Sdim    return MCDisassembler::Fail;
4046261991Sdim  return S;
4047261991Sdim}
4048261991Sdim
4049261991Sdimstatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
4050261991Sdim                                uint64_t Address, const void* Decoder) {
4051261991Sdim  DecodeStatus S = MCDisassembler::Success;
4052261991Sdim
4053261991Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4054261991Sdim  unsigned U = fieldFromInstruction(Insn, 23, 1);
4055261991Sdim  int imm = fieldFromInstruction(Insn, 0, 12);
4056261991Sdim
4057288943Sdim  const FeatureBitset &featureBits =
4058288943Sdim    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
4059280031Sdim
4060288943Sdim  bool hasV7Ops = featureBits[ARM::HasV7Ops];
4061288943Sdim
4062261991Sdim  if (Rt == 15) {
4063261991Sdim    switch (Inst.getOpcode()) {
4064261991Sdim      case ARM::t2LDRBpci:
4065261991Sdim      case ARM::t2LDRHpci:
4066261991Sdim        Inst.setOpcode(ARM::t2PLDpci);
4067226633Sdim        break;
4068261991Sdim      case ARM::t2LDRSBpci:
4069261991Sdim        Inst.setOpcode(ARM::t2PLIpci);
4070226633Sdim        break;
4071261991Sdim      case ARM::t2LDRSHpci:
4072261991Sdim        return MCDisassembler::Fail;
4073261991Sdim      default:
4074226633Sdim        break;
4075206124Srdivacky    }
4076261991Sdim  }
4077206124Srdivacky
4078261991Sdim  switch(Inst.getOpcode()) {
4079261991Sdim  case ARM::t2PLDpci:
4080280031Sdim    break;
4081261991Sdim  case ARM::t2PLIpci:
4082280031Sdim    if (!hasV7Ops)
4083280031Sdim      return MCDisassembler::Fail;
4084261991Sdim    break;
4085261991Sdim  default:
4086261991Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4087261991Sdim      return MCDisassembler::Fail;
4088261991Sdim  }
4089221345Sdim
4090261991Sdim  if (!U) {
4091261991Sdim    // Special case for #-0.
4092261991Sdim    if (imm == 0)
4093261991Sdim      imm = INT32_MIN;
4094261991Sdim    else
4095261991Sdim      imm = -imm;
4096226633Sdim  }
4097288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
4098226633Sdim
4099226633Sdim  return S;
4100226633Sdim}
4101226633Sdim
4102234353Sdimstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
4103226633Sdim                           uint64_t Address, const void *Decoder) {
4104239462Sdim  if (Val == 0)
4105288943Sdim    Inst.addOperand(MCOperand::createImm(INT32_MIN));
4106239462Sdim  else {
4107239462Sdim    int imm = Val & 0xFF;
4108226633Sdim
4109239462Sdim    if (!(Val & 0x100)) imm *= -1;
4110288943Sdim    Inst.addOperand(MCOperand::createImm(imm * 4));
4111239462Sdim  }
4112239462Sdim
4113226633Sdim  return MCDisassembler::Success;
4114226633Sdim}
4115226633Sdim
4116353358Sdimstatic DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val, uint64_t Address,
4117353358Sdim                                   const void *Decoder) {
4118353358Sdim  if (Val == 0)
4119353358Sdim    Inst.addOperand(MCOperand::createImm(INT32_MIN));
4120353358Sdim  else {
4121353358Sdim    int imm = Val & 0x7F;
4122353358Sdim
4123353358Sdim    if (!(Val & 0x80))
4124353358Sdim      imm *= -1;
4125353358Sdim    Inst.addOperand(MCOperand::createImm(imm * 4));
4126353358Sdim  }
4127353358Sdim
4128353358Sdim  return MCDisassembler::Success;
4129353358Sdim}
4130353358Sdim
4131234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
4132226633Sdim                                   uint64_t Address, const void *Decoder) {
4133226633Sdim  DecodeStatus S = MCDisassembler::Success;
4134226633Sdim
4135239462Sdim  unsigned Rn = fieldFromInstruction(Val, 9, 4);
4136239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 9);
4137226633Sdim
4138226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4139226633Sdim    return MCDisassembler::Fail;
4140226633Sdim  if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
4141226633Sdim    return MCDisassembler::Fail;
4142226633Sdim
4143226633Sdim  return S;
4144226633Sdim}
4145226633Sdim
4146353358Sdimstatic DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val,
4147353358Sdim                                           uint64_t Address,
4148353358Sdim                                           const void *Decoder) {
4149353358Sdim  DecodeStatus S = MCDisassembler::Success;
4150353358Sdim
4151353358Sdim  unsigned Rn = fieldFromInstruction(Val, 8, 4);
4152353358Sdim  unsigned imm = fieldFromInstruction(Val, 0, 8);
4153353358Sdim
4154353358Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4155353358Sdim    return MCDisassembler::Fail;
4156353358Sdim  if (!Check(S, DecodeT2Imm7S4(Inst, imm, Address, Decoder)))
4157353358Sdim    return MCDisassembler::Fail;
4158353358Sdim
4159353358Sdim  return S;
4160353358Sdim}
4161353358Sdim
4162234353Sdimstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
4163226633Sdim                                   uint64_t Address, const void *Decoder) {
4164226633Sdim  DecodeStatus S = MCDisassembler::Success;
4165226633Sdim
4166239462Sdim  unsigned Rn = fieldFromInstruction(Val, 8, 4);
4167239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 8);
4168226633Sdim
4169226633Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4170226633Sdim    return MCDisassembler::Fail;
4171226633Sdim
4172288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
4173226633Sdim
4174226633Sdim  return S;
4175226633Sdim}
4176226633Sdim
4177234353Sdimstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
4178226633Sdim                         uint64_t Address, const void *Decoder) {
4179226633Sdim  int imm = Val & 0xFF;
4180226633Sdim  if (Val == 0)
4181226633Sdim    imm = INT32_MIN;
4182226633Sdim  else if (!(Val & 0x100))
4183226633Sdim    imm *= -1;
4184288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
4185226633Sdim
4186226633Sdim  return MCDisassembler::Success;
4187226633Sdim}
4188226633Sdim
4189353358Sdimtemplate<int shift>
4190353358Sdimstatic DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val,
4191353358Sdim                         uint64_t Address, const void *Decoder) {
4192353358Sdim  int imm = Val & 0x7F;
4193353358Sdim  if (Val == 0)
4194353358Sdim    imm = INT32_MIN;
4195353358Sdim  else if (!(Val & 0x80))
4196353358Sdim    imm *= -1;
4197353358Sdim  if (imm != INT32_MIN)
4198353358Sdim    imm *= (1U << shift);
4199353358Sdim  Inst.addOperand(MCOperand::createImm(imm));
4200353358Sdim
4201353358Sdim  return MCDisassembler::Success;
4202353358Sdim}
4203353358Sdim
4204234353Sdimstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
4205226633Sdim                                 uint64_t Address, const void *Decoder) {
4206226633Sdim  DecodeStatus S = MCDisassembler::Success;
4207226633Sdim
4208239462Sdim  unsigned Rn = fieldFromInstruction(Val, 9, 4);
4209239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 9);
4210226633Sdim
4211261991Sdim  // Thumb stores cannot use PC as dest register.
4212261991Sdim  switch (Inst.getOpcode()) {
4213261991Sdim  case ARM::t2STRT:
4214261991Sdim  case ARM::t2STRBT:
4215261991Sdim  case ARM::t2STRHT:
4216261991Sdim  case ARM::t2STRi8:
4217261991Sdim  case ARM::t2STRHi8:
4218261991Sdim  case ARM::t2STRBi8:
4219261991Sdim    if (Rn == 15)
4220261991Sdim      return MCDisassembler::Fail;
4221261991Sdim    break;
4222261991Sdim  default:
4223261991Sdim    break;
4224261991Sdim  }
4225261991Sdim
4226226633Sdim  // Some instructions always use an additive offset.
4227226633Sdim  switch (Inst.getOpcode()) {
4228226633Sdim    case ARM::t2LDRT:
4229226633Sdim    case ARM::t2LDRBT:
4230226633Sdim    case ARM::t2LDRHT:
4231226633Sdim    case ARM::t2LDRSBT:
4232226633Sdim    case ARM::t2LDRSHT:
4233226633Sdim    case ARM::t2STRT:
4234226633Sdim    case ARM::t2STRBT:
4235226633Sdim    case ARM::t2STRHT:
4236226633Sdim      imm |= 0x100;
4237226633Sdim      break;
4238226633Sdim    default:
4239226633Sdim      break;
4240226633Sdim  }
4241226633Sdim
4242226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4243226633Sdim    return MCDisassembler::Fail;
4244226633Sdim  if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
4245226633Sdim    return MCDisassembler::Fail;
4246226633Sdim
4247226633Sdim  return S;
4248226633Sdim}
4249226633Sdim
4250353358Sdimtemplate<int shift>
4251353358Sdimstatic DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val,
4252353358Sdim                                         uint64_t Address,
4253353358Sdim                                         const void *Decoder) {
4254353358Sdim  DecodeStatus S = MCDisassembler::Success;
4255353358Sdim
4256353358Sdim  unsigned Rn = fieldFromInstruction(Val, 8, 3);
4257353358Sdim  unsigned imm = fieldFromInstruction(Val, 0, 8);
4258353358Sdim
4259353358Sdim  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
4260353358Sdim    return MCDisassembler::Fail;
4261353358Sdim  if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
4262353358Sdim    return MCDisassembler::Fail;
4263353358Sdim
4264353358Sdim  return S;
4265353358Sdim}
4266353358Sdim
4267353358Sdimtemplate<int shift, int WriteBack>
4268353358Sdimstatic DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val,
4269353358Sdim                                         uint64_t Address,
4270353358Sdim                                         const void *Decoder) {
4271353358Sdim  DecodeStatus S = MCDisassembler::Success;
4272353358Sdim
4273353358Sdim  unsigned Rn = fieldFromInstruction(Val, 8, 4);
4274353358Sdim  unsigned imm = fieldFromInstruction(Val, 0, 8);
4275353358Sdim  if (WriteBack) {
4276353358Sdim    if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4277353358Sdim      return MCDisassembler::Fail;
4278353358Sdim  } else if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4279353358Sdim    return MCDisassembler::Fail;
4280353358Sdim  if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
4281353358Sdim    return MCDisassembler::Fail;
4282353358Sdim
4283353358Sdim  return S;
4284353358Sdim}
4285353358Sdim
4286234353Sdimstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
4287226633Sdim                                    uint64_t Address, const void *Decoder) {
4288226633Sdim  DecodeStatus S = MCDisassembler::Success;
4289226633Sdim
4290239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4291239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4292239462Sdim  unsigned addr = fieldFromInstruction(Insn, 0, 8);
4293239462Sdim  addr |= fieldFromInstruction(Insn, 9, 1) << 8;
4294226633Sdim  addr |= Rn << 9;
4295239462Sdim  unsigned load = fieldFromInstruction(Insn, 20, 1);
4296226633Sdim
4297261991Sdim  if (Rn == 15) {
4298261991Sdim    switch (Inst.getOpcode()) {
4299261991Sdim    case ARM::t2LDR_PRE:
4300261991Sdim    case ARM::t2LDR_POST:
4301261991Sdim      Inst.setOpcode(ARM::t2LDRpci);
4302261991Sdim      break;
4303261991Sdim    case ARM::t2LDRB_PRE:
4304261991Sdim    case ARM::t2LDRB_POST:
4305261991Sdim      Inst.setOpcode(ARM::t2LDRBpci);
4306261991Sdim      break;
4307261991Sdim    case ARM::t2LDRH_PRE:
4308261991Sdim    case ARM::t2LDRH_POST:
4309261991Sdim      Inst.setOpcode(ARM::t2LDRHpci);
4310261991Sdim      break;
4311261991Sdim    case ARM::t2LDRSB_PRE:
4312261991Sdim    case ARM::t2LDRSB_POST:
4313261991Sdim      if (Rt == 15)
4314261991Sdim        Inst.setOpcode(ARM::t2PLIpci);
4315261991Sdim      else
4316261991Sdim        Inst.setOpcode(ARM::t2LDRSBpci);
4317261991Sdim      break;
4318261991Sdim    case ARM::t2LDRSH_PRE:
4319261991Sdim    case ARM::t2LDRSH_POST:
4320261991Sdim      Inst.setOpcode(ARM::t2LDRSHpci);
4321261991Sdim      break;
4322261991Sdim    default:
4323261991Sdim      return MCDisassembler::Fail;
4324261991Sdim    }
4325261991Sdim    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
4326261991Sdim  }
4327261991Sdim
4328226633Sdim  if (!load) {
4329226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4330226633Sdim      return MCDisassembler::Fail;
4331226633Sdim  }
4332226633Sdim
4333249423Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4334226633Sdim    return MCDisassembler::Fail;
4335226633Sdim
4336226633Sdim  if (load) {
4337226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4338226633Sdim      return MCDisassembler::Fail;
4339226633Sdim  }
4340226633Sdim
4341226633Sdim  if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
4342226633Sdim    return MCDisassembler::Fail;
4343226633Sdim
4344226633Sdim  return S;
4345226633Sdim}
4346226633Sdim
4347234353Sdimstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
4348226633Sdim                                  uint64_t Address, const void *Decoder) {
4349226633Sdim  DecodeStatus S = MCDisassembler::Success;
4350226633Sdim
4351239462Sdim  unsigned Rn = fieldFromInstruction(Val, 13, 4);
4352239462Sdim  unsigned imm = fieldFromInstruction(Val, 0, 12);
4353226633Sdim
4354261991Sdim  // Thumb stores cannot use PC as dest register.
4355261991Sdim  switch (Inst.getOpcode()) {
4356261991Sdim  case ARM::t2STRi12:
4357261991Sdim  case ARM::t2STRBi12:
4358261991Sdim  case ARM::t2STRHi12:
4359261991Sdim    if (Rn == 15)
4360261991Sdim      return MCDisassembler::Fail;
4361327952Sdim    break;
4362261991Sdim  default:
4363261991Sdim    break;
4364261991Sdim  }
4365261991Sdim
4366226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4367226633Sdim    return MCDisassembler::Fail;
4368288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
4369226633Sdim
4370226633Sdim  return S;
4371226633Sdim}
4372226633Sdim
4373234353Sdimstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
4374226633Sdim                                uint64_t Address, const void *Decoder) {
4375239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 7);
4376226633Sdim
4377288943Sdim  Inst.addOperand(MCOperand::createReg(ARM::SP));
4378288943Sdim  Inst.addOperand(MCOperand::createReg(ARM::SP));
4379288943Sdim  Inst.addOperand(MCOperand::createImm(imm));
4380226633Sdim
4381226633Sdim  return MCDisassembler::Success;
4382226633Sdim}
4383226633Sdim
4384234353Sdimstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
4385226633Sdim                                uint64_t Address, const void *Decoder) {
4386226633Sdim  DecodeStatus S = MCDisassembler::Success;
4387226633Sdim
4388226633Sdim  if (Inst.getOpcode() == ARM::tADDrSP) {
4389239462Sdim    unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
4390239462Sdim    Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
4391226633Sdim
4392226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
4393226633Sdim    return MCDisassembler::Fail;
4394288943Sdim    Inst.addOperand(MCOperand::createReg(ARM::SP));
4395226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
4396226633Sdim    return MCDisassembler::Fail;
4397226633Sdim  } else if (Inst.getOpcode() == ARM::tADDspr) {
4398239462Sdim    unsigned Rm = fieldFromInstruction(Insn, 3, 4);
4399226633Sdim
4400288943Sdim    Inst.addOperand(MCOperand::createReg(ARM::SP));
4401288943Sdim    Inst.addOperand(MCOperand::createReg(ARM::SP));
4402226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4403226633Sdim    return MCDisassembler::Fail;
4404226633Sdim  }
4405226633Sdim
4406226633Sdim  return S;
4407226633Sdim}
4408226633Sdim
4409234353Sdimstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
4410226633Sdim                           uint64_t Address, const void *Decoder) {
4411239462Sdim  unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
4412239462Sdim  unsigned flags = fieldFromInstruction(Insn, 0, 3);
4413226633Sdim
4414288943Sdim  Inst.addOperand(MCOperand::createImm(imod));
4415288943Sdim  Inst.addOperand(MCOperand::createImm(flags));
4416226633Sdim
4417226633Sdim  return MCDisassembler::Success;
4418226633Sdim}
4419226633Sdim
4420234353Sdimstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
4421226633Sdim                             uint64_t Address, const void *Decoder) {
4422226633Sdim  DecodeStatus S = MCDisassembler::Success;
4423239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4424239462Sdim  unsigned add = fieldFromInstruction(Insn, 4, 1);
4425226633Sdim
4426234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
4427226633Sdim    return MCDisassembler::Fail;
4428288943Sdim  Inst.addOperand(MCOperand::createImm(add));
4429226633Sdim
4430226633Sdim  return S;
4431226633Sdim}
4432226633Sdim
4433353358Sdimstatic DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn,
4434353358Sdim                             uint64_t Address, const void *Decoder) {
4435353358Sdim  DecodeStatus S = MCDisassembler::Success;
4436353358Sdim  unsigned Rn = fieldFromInstruction(Insn, 3, 4);
4437353358Sdim  unsigned Qm = fieldFromInstruction(Insn, 0, 3);
4438353358Sdim
4439353358Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4440353358Sdim    return MCDisassembler::Fail;
4441353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
4442353358Sdim    return MCDisassembler::Fail;
4443353358Sdim
4444353358Sdim  return S;
4445353358Sdim}
4446353358Sdim
4447353358Sdimtemplate<int shift>
4448353358Sdimstatic DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn,
4449353358Sdim                             uint64_t Address, const void *Decoder) {
4450353358Sdim  DecodeStatus S = MCDisassembler::Success;
4451353358Sdim  unsigned Qm = fieldFromInstruction(Insn, 8, 3);
4452353358Sdim  int imm = fieldFromInstruction(Insn, 0, 7);
4453353358Sdim
4454353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
4455353358Sdim    return MCDisassembler::Fail;
4456353358Sdim
4457353358Sdim  if(!fieldFromInstruction(Insn, 7, 1)) {
4458353358Sdim    if (imm == 0)
4459353358Sdim      imm = INT32_MIN;                 // indicate -0
4460353358Sdim    else
4461353358Sdim      imm *= -1;
4462353358Sdim  }
4463353358Sdim  if (imm != INT32_MIN)
4464353358Sdim    imm *= (1U << shift);
4465353358Sdim  Inst.addOperand(MCOperand::createImm(imm));
4466353358Sdim
4467353358Sdim  return S;
4468353358Sdim}
4469353358Sdim
4470234353Sdimstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
4471226633Sdim                                 uint64_t Address, const void *Decoder) {
4472239462Sdim  // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
4473239462Sdim  // Note only one trailing zero not two.  Also the J1 and J2 values are from
4474239462Sdim  // the encoded instruction.  So here change to I1 and I2 values via:
4475239462Sdim  // I1 = NOT(J1 EOR S);
4476239462Sdim  // I2 = NOT(J2 EOR S);
4477239462Sdim  // and build the imm32 with two trailing zeros as documented:
4478239462Sdim  // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
4479239462Sdim  unsigned S = (Val >> 23) & 1;
4480239462Sdim  unsigned J1 = (Val >> 22) & 1;
4481239462Sdim  unsigned J2 = (Val >> 21) & 1;
4482239462Sdim  unsigned I1 = !(J1 ^ S);
4483239462Sdim  unsigned I2 = !(J2 ^ S);
4484239462Sdim  unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
4485239462Sdim  int imm32 = SignExtend32<25>(tmp << 1);
4486239462Sdim
4487234353Sdim  if (!tryAddingSymbolicOperand(Address,
4488239462Sdim                                (Address & ~2u) + imm32 + 4,
4489226633Sdim                                true, 4, Inst, Decoder))
4490288943Sdim    Inst.addOperand(MCOperand::createImm(imm32));
4491226633Sdim  return MCDisassembler::Success;
4492226633Sdim}
4493226633Sdim
4494234353Sdimstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
4495226633Sdim                              uint64_t Address, const void *Decoder) {
4496226633Sdim  if (Val == 0xA || Val == 0xB)
4497226633Sdim    return MCDisassembler::Fail;
4498226633Sdim
4499288943Sdim  const FeatureBitset &featureBits =
4500288943Sdim    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
4501288943Sdim
4502353358Sdim  if (!isValidCoprocessorNumber(Val, featureBits))
4503261991Sdim    return MCDisassembler::Fail;
4504261991Sdim
4505288943Sdim  Inst.addOperand(MCOperand::createImm(Val));
4506226633Sdim  return MCDisassembler::Success;
4507226633Sdim}
4508226633Sdim
4509226633Sdimstatic DecodeStatus
4510234353SdimDecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
4511226633Sdim                       uint64_t Address, const void *Decoder) {
4512226633Sdim  DecodeStatus S = MCDisassembler::Success;
4513226633Sdim
4514239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4515239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4516226633Sdim
4517226633Sdim  if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
4518226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4519226633Sdim    return MCDisassembler::Fail;
4520226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
4521226633Sdim    return MCDisassembler::Fail;
4522226633Sdim  return S;
4523226633Sdim}
4524226633Sdim
4525226633Sdimstatic DecodeStatus
4526234353SdimDecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
4527226633Sdim                           uint64_t Address, const void *Decoder) {
4528226633Sdim  DecodeStatus S = MCDisassembler::Success;
4529226633Sdim
4530239462Sdim  unsigned pred = fieldFromInstruction(Insn, 22, 4);
4531226633Sdim  if (pred == 0xE || pred == 0xF) {
4532239462Sdim    unsigned opc = fieldFromInstruction(Insn, 4, 28);
4533226633Sdim    switch (opc) {
4534226633Sdim      default:
4535226633Sdim        return MCDisassembler::Fail;
4536226633Sdim      case 0xf3bf8f4:
4537226633Sdim        Inst.setOpcode(ARM::t2DSB);
4538226633Sdim        break;
4539226633Sdim      case 0xf3bf8f5:
4540226633Sdim        Inst.setOpcode(ARM::t2DMB);
4541226633Sdim        break;
4542226633Sdim      case 0xf3bf8f6:
4543226633Sdim        Inst.setOpcode(ARM::t2ISB);
4544226633Sdim        break;
4545221345Sdim    }
4546206124Srdivacky
4547239462Sdim    unsigned imm = fieldFromInstruction(Insn, 0, 4);
4548226633Sdim    return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
4549226633Sdim  }
4550226633Sdim
4551239462Sdim  unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
4552239462Sdim  brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
4553239462Sdim  brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
4554239462Sdim  brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
4555239462Sdim  brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
4556226633Sdim
4557226633Sdim  if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
4558226633Sdim    return MCDisassembler::Fail;
4559226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4560226633Sdim    return MCDisassembler::Fail;
4561226633Sdim
4562226633Sdim  return S;
4563226633Sdim}
4564226633Sdim
4565226633Sdim// Decode a shifted immediate operand.  These basically consist
4566226633Sdim// of an 8-bit value, and a 4-bit directive that specifies either
4567226633Sdim// a splat operation or a rotation.
4568234353Sdimstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
4569226633Sdim                          uint64_t Address, const void *Decoder) {
4570239462Sdim  unsigned ctrl = fieldFromInstruction(Val, 10, 2);
4571226633Sdim  if (ctrl == 0) {
4572239462Sdim    unsigned byte = fieldFromInstruction(Val, 8, 2);
4573239462Sdim    unsigned imm = fieldFromInstruction(Val, 0, 8);
4574226633Sdim    switch (byte) {
4575226633Sdim      case 0:
4576288943Sdim        Inst.addOperand(MCOperand::createImm(imm));
4577226633Sdim        break;
4578226633Sdim      case 1:
4579288943Sdim        Inst.addOperand(MCOperand::createImm((imm << 16) | imm));
4580226633Sdim        break;
4581226633Sdim      case 2:
4582288943Sdim        Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 8)));
4583226633Sdim        break;
4584226633Sdim      case 3:
4585288943Sdim        Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 16) |
4586226633Sdim                                             (imm << 8)  |  imm));
4587226633Sdim        break;
4588221345Sdim    }
4589226633Sdim  } else {
4590239462Sdim    unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
4591239462Sdim    unsigned rot = fieldFromInstruction(Val, 7, 5);
4592226633Sdim    unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
4593288943Sdim    Inst.addOperand(MCOperand::createImm(imm));
4594226633Sdim  }
4595221345Sdim
4596226633Sdim  return MCDisassembler::Success;
4597226633Sdim}
4598206124Srdivacky
4599226633Sdimstatic DecodeStatus
4600234353SdimDecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
4601321369Sdim                            uint64_t Address, const void *Decoder) {
4602239462Sdim  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
4603234353Sdim                                true, 2, Inst, Decoder))
4604288943Sdim    Inst.addOperand(MCOperand::createImm(SignExtend32<9>(Val << 1)));
4605226633Sdim  return MCDisassembler::Success;
4606226633Sdim}
4607226633Sdim
4608234353Sdimstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
4609321369Sdim                                               uint64_t Address,
4610321369Sdim                                               const void *Decoder) {
4611239462Sdim  // Val is passed in as S:J1:J2:imm10:imm11
4612239462Sdim  // Note no trailing zero after imm11.  Also the J1 and J2 values are from
4613239462Sdim  // the encoded instruction.  So here change to I1 and I2 values via:
4614239462Sdim  // I1 = NOT(J1 EOR S);
4615239462Sdim  // I2 = NOT(J2 EOR S);
4616239462Sdim  // and build the imm32 with one trailing zero as documented:
4617239462Sdim  // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
4618239462Sdim  unsigned S = (Val >> 23) & 1;
4619239462Sdim  unsigned J1 = (Val >> 22) & 1;
4620239462Sdim  unsigned J2 = (Val >> 21) & 1;
4621239462Sdim  unsigned I1 = !(J1 ^ S);
4622239462Sdim  unsigned I2 = !(J2 ^ S);
4623239462Sdim  unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
4624239462Sdim  int imm32 = SignExtend32<25>(tmp << 1);
4625239462Sdim
4626239462Sdim  if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
4627234353Sdim                                true, 4, Inst, Decoder))
4628288943Sdim    Inst.addOperand(MCOperand::createImm(imm32));
4629226633Sdim  return MCDisassembler::Success;
4630226633Sdim}
4631226633Sdim
4632234353Sdimstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
4633226633Sdim                                   uint64_t Address, const void *Decoder) {
4634239462Sdim  if (Val & ~0xf)
4635226633Sdim    return MCDisassembler::Fail;
4636206124Srdivacky
4637288943Sdim  Inst.addOperand(MCOperand::createImm(Val));
4638226633Sdim  return MCDisassembler::Success;
4639206124Srdivacky}
4640206124Srdivacky
4641261991Sdimstatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
4642261991Sdim                                        uint64_t Address, const void *Decoder) {
4643261991Sdim  if (Val & ~0xf)
4644261991Sdim    return MCDisassembler::Fail;
4645261991Sdim
4646288943Sdim  Inst.addOperand(MCOperand::createImm(Val));
4647261991Sdim  return MCDisassembler::Success;
4648261991Sdim}
4649261991Sdim
4650234353Sdimstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
4651226633Sdim                          uint64_t Address, const void *Decoder) {
4652280031Sdim  DecodeStatus S = MCDisassembler::Success;
4653288943Sdim  const FeatureBitset &FeatureBits =
4654288943Sdim    ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
4655288943Sdim
4656288943Sdim  if (FeatureBits[ARM::FeatureMClass]) {
4657280031Sdim    unsigned ValLow = Val & 0xff;
4658280031Sdim
4659280031Sdim    // Validate the SYSm value first.
4660280031Sdim    switch (ValLow) {
4661280031Sdim    case  0: // apsr
4662280031Sdim    case  1: // iapsr
4663280031Sdim    case  2: // eapsr
4664280031Sdim    case  3: // xpsr
4665280031Sdim    case  5: // ipsr
4666280031Sdim    case  6: // epsr
4667280031Sdim    case  7: // iepsr
4668280031Sdim    case  8: // msp
4669280031Sdim    case  9: // psp
4670280031Sdim    case 16: // primask
4671280031Sdim    case 20: // control
4672280031Sdim      break;
4673280031Sdim    case 17: // basepri
4674280031Sdim    case 18: // basepri_max
4675280031Sdim    case 19: // faultmask
4676288943Sdim      if (!(FeatureBits[ARM::HasV7Ops]))
4677280031Sdim        // Values basepri, basepri_max and faultmask are only valid for v7m.
4678280031Sdim        return MCDisassembler::Fail;
4679280031Sdim      break;
4680309124Sdim    case 0x8a: // msplim_ns
4681309124Sdim    case 0x8b: // psplim_ns
4682309124Sdim    case 0x91: // basepri_ns
4683309124Sdim    case 0x93: // faultmask_ns
4684309124Sdim      if (!(FeatureBits[ARM::HasV8MMainlineOps]))
4685309124Sdim        return MCDisassembler::Fail;
4686314564Sdim      LLVM_FALLTHROUGH;
4687309124Sdim    case 10:   // msplim
4688309124Sdim    case 11:   // psplim
4689309124Sdim    case 0x88: // msp_ns
4690309124Sdim    case 0x89: // psp_ns
4691309124Sdim    case 0x90: // primask_ns
4692309124Sdim    case 0x94: // control_ns
4693309124Sdim    case 0x98: // sp_ns
4694309124Sdim      if (!(FeatureBits[ARM::Feature8MSecExt]))
4695309124Sdim        return MCDisassembler::Fail;
4696309124Sdim      break;
4697280031Sdim    default:
4698341825Sdim      // Architecturally defined as unpredictable
4699341825Sdim      S = MCDisassembler::SoftFail;
4700341825Sdim      break;
4701280031Sdim    }
4702280031Sdim
4703280031Sdim    if (Inst.getOpcode() == ARM::t2MSR_M) {
4704280031Sdim      unsigned Mask = fieldFromInstruction(Val, 10, 2);
4705288943Sdim      if (!(FeatureBits[ARM::HasV7Ops])) {
4706280031Sdim        // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
4707280031Sdim        // unpredictable.
4708280031Sdim        if (Mask != 2)
4709280031Sdim          S = MCDisassembler::SoftFail;
4710280031Sdim      }
4711280031Sdim      else {
4712280031Sdim        // The ARMv7-M architecture stores an additional 2-bit mask value in
4713280031Sdim        // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
4714280031Sdim        // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
4715280031Sdim        // the NZCVQ bits should be moved by the instruction. Bit mask{0}
4716280031Sdim        // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
4717280031Sdim        // only if the processor includes the DSP extension.
4718280031Sdim        if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
4719296417Sdim            (!(FeatureBits[ARM::FeatureDSP]) && (Mask & 1)))
4720280031Sdim          S = MCDisassembler::SoftFail;
4721280031Sdim      }
4722280031Sdim    }
4723280031Sdim  } else {
4724280031Sdim    // A/R class
4725280031Sdim    if (Val == 0)
4726280031Sdim      return MCDisassembler::Fail;
4727280031Sdim  }
4728288943Sdim  Inst.addOperand(MCOperand::createImm(Val));
4729280031Sdim  return S;
4730280031Sdim}
4731280031Sdim
4732280031Sdimstatic DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
4733280031Sdim                                    uint64_t Address, const void *Decoder) {
4734280031Sdim  unsigned R = fieldFromInstruction(Val, 5, 1);
4735280031Sdim  unsigned SysM = fieldFromInstruction(Val, 0, 5);
4736280031Sdim
4737280031Sdim  // The table of encodings for these banked registers comes from B9.2.3 of the
4738280031Sdim  // ARM ARM. There are patterns, but nothing regular enough to make this logic
4739280031Sdim  // neater. So by fiat, these values are UNPREDICTABLE:
4740341825Sdim  if (!ARMBankedReg::lookupBankedRegByEncoding((R << 5) | SysM))
4741341825Sdim    return MCDisassembler::Fail;
4742280031Sdim
4743288943Sdim  Inst.addOperand(MCOperand::createImm(Val));
4744226633Sdim  return MCDisassembler::Success;
4745226633Sdim}
4746206124Srdivacky
4747234353Sdimstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
4748226633Sdim                                        uint64_t Address, const void *Decoder) {
4749226633Sdim  DecodeStatus S = MCDisassembler::Success;
4750206124Srdivacky
4751239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4752239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4753239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4754206124Srdivacky
4755261991Sdim  if (Rn == 0xF)
4756261991Sdim    S = MCDisassembler::SoftFail;
4757206274Srdivacky
4758261991Sdim  if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
4759226633Sdim    return MCDisassembler::Fail;
4760226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4761226633Sdim    return MCDisassembler::Fail;
4762226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4763226633Sdim    return MCDisassembler::Fail;
4764206124Srdivacky
4765226633Sdim  return S;
4766226633Sdim}
4767206124Srdivacky
4768234353Sdimstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
4769321369Sdim                                         uint64_t Address,
4770321369Sdim                                         const void *Decoder) {
4771226633Sdim  DecodeStatus S = MCDisassembler::Success;
4772221345Sdim
4773239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4774239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 0, 4);
4775239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4776239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4777206124Srdivacky
4778251662Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
4779226633Sdim    return MCDisassembler::Fail;
4780226633Sdim
4781261991Sdim  if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
4782261991Sdim    S = MCDisassembler::SoftFail;
4783226633Sdim
4784261991Sdim  if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
4785226633Sdim    return MCDisassembler::Fail;
4786226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4787226633Sdim    return MCDisassembler::Fail;
4788226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4789226633Sdim    return MCDisassembler::Fail;
4790226633Sdim
4791226633Sdim  return S;
4792206124Srdivacky}
4793206124Srdivacky
4794234353Sdimstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
4795226633Sdim                            uint64_t Address, const void *Decoder) {
4796226633Sdim  DecodeStatus S = MCDisassembler::Success;
4797206274Srdivacky
4798239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4799239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4800239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4801239462Sdim  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4802239462Sdim  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4803239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4804206124Srdivacky
4805226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4806206124Srdivacky
4807226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4808226633Sdim    return MCDisassembler::Fail;
4809226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4810226633Sdim    return MCDisassembler::Fail;
4811226633Sdim  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4812226633Sdim    return MCDisassembler::Fail;
4813226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4814226633Sdim    return MCDisassembler::Fail;
4815206124Srdivacky
4816226633Sdim  return S;
4817226633Sdim}
4818206124Srdivacky
4819234353Sdimstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
4820226633Sdim                            uint64_t Address, const void *Decoder) {
4821226633Sdim  DecodeStatus S = MCDisassembler::Success;
4822226633Sdim
4823239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4824239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4825239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4826239462Sdim  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4827239462Sdim  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4828239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4829239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4830226633Sdim
4831226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4832226633Sdim  if (Rm == 0xF) S = MCDisassembler::SoftFail;
4833226633Sdim
4834226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4835226633Sdim    return MCDisassembler::Fail;
4836226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4837226633Sdim    return MCDisassembler::Fail;
4838226633Sdim  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4839226633Sdim    return MCDisassembler::Fail;
4840226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4841226633Sdim    return MCDisassembler::Fail;
4842226633Sdim
4843226633Sdim  return S;
4844226633Sdim}
4845226633Sdim
4846234353Sdimstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
4847226633Sdim                            uint64_t Address, const void *Decoder) {
4848226633Sdim  DecodeStatus S = MCDisassembler::Success;
4849226633Sdim
4850239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4851239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4852239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4853239462Sdim  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4854239462Sdim  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4855239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4856226633Sdim
4857226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4858226633Sdim
4859226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4860226633Sdim    return MCDisassembler::Fail;
4861226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4862226633Sdim    return MCDisassembler::Fail;
4863226633Sdim  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4864226633Sdim    return MCDisassembler::Fail;
4865226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4866226633Sdim    return MCDisassembler::Fail;
4867226633Sdim
4868226633Sdim  return S;
4869226633Sdim}
4870226633Sdim
4871234353Sdimstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
4872226633Sdim                            uint64_t Address, const void *Decoder) {
4873226633Sdim  DecodeStatus S = MCDisassembler::Success;
4874226633Sdim
4875239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4876239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4877239462Sdim  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4878239462Sdim  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4879239462Sdim  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4880239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4881226633Sdim
4882226633Sdim  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4883226633Sdim
4884226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4885226633Sdim    return MCDisassembler::Fail;
4886226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4887226633Sdim    return MCDisassembler::Fail;
4888226633Sdim  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4889226633Sdim    return MCDisassembler::Fail;
4890226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4891226633Sdim    return MCDisassembler::Fail;
4892226633Sdim
4893226633Sdim  return S;
4894226633Sdim}
4895226633Sdim
4896234353Sdimstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
4897226633Sdim                         uint64_t Address, const void *Decoder) {
4898226633Sdim  DecodeStatus S = MCDisassembler::Success;
4899226633Sdim
4900239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4901239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4902239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4903239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4904239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
4905226633Sdim
4906226633Sdim  unsigned align = 0;
4907226633Sdim  unsigned index = 0;
4908226633Sdim  switch (size) {
4909226633Sdim    default:
4910226633Sdim      return MCDisassembler::Fail;
4911226633Sdim    case 0:
4912239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4913226633Sdim        return MCDisassembler::Fail; // UNDEFINED
4914239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
4915226633Sdim      break;
4916226633Sdim    case 1:
4917239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
4918226633Sdim        return MCDisassembler::Fail; // UNDEFINED
4919239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
4920239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4921226633Sdim        align = 2;
4922226633Sdim      break;
4923226633Sdim    case 2:
4924239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
4925226633Sdim        return MCDisassembler::Fail; // UNDEFINED
4926239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
4927243830Sdim
4928243830Sdim      switch (fieldFromInstruction(Insn, 4, 2)) {
4929243830Sdim        case 0 :
4930243830Sdim          align = 0; break;
4931243830Sdim        case 3:
4932243830Sdim          align = 4; break;
4933243830Sdim        default:
4934243830Sdim          return MCDisassembler::Fail;
4935243830Sdim      }
4936243830Sdim      break;
4937206124Srdivacky  }
4938206124Srdivacky
4939226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4940226633Sdim    return MCDisassembler::Fail;
4941226633Sdim  if (Rm != 0xF) { // Writeback
4942226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4943226633Sdim      return MCDisassembler::Fail;
4944226633Sdim  }
4945226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4946226633Sdim    return MCDisassembler::Fail;
4947288943Sdim  Inst.addOperand(MCOperand::createImm(align));
4948226633Sdim  if (Rm != 0xF) {
4949226633Sdim    if (Rm != 0xD) {
4950226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4951226633Sdim        return MCDisassembler::Fail;
4952226633Sdim    } else
4953288943Sdim      Inst.addOperand(MCOperand::createReg(0));
4954226633Sdim  }
4955206124Srdivacky
4956226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4957226633Sdim    return MCDisassembler::Fail;
4958288943Sdim  Inst.addOperand(MCOperand::createImm(index));
4959206124Srdivacky
4960226633Sdim  return S;
4961226633Sdim}
4962206124Srdivacky
4963234353Sdimstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
4964226633Sdim                         uint64_t Address, const void *Decoder) {
4965226633Sdim  DecodeStatus S = MCDisassembler::Success;
4966206124Srdivacky
4967239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4968239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4969239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4970239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4971239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
4972207618Srdivacky
4973226633Sdim  unsigned align = 0;
4974226633Sdim  unsigned index = 0;
4975226633Sdim  switch (size) {
4976226633Sdim    default:
4977226633Sdim      return MCDisassembler::Fail;
4978226633Sdim    case 0:
4979239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4980226633Sdim        return MCDisassembler::Fail; // UNDEFINED
4981239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
4982226633Sdim      break;
4983226633Sdim    case 1:
4984239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
4985226633Sdim        return MCDisassembler::Fail; // UNDEFINED
4986239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
4987239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
4988226633Sdim        align = 2;
4989226633Sdim      break;
4990226633Sdim    case 2:
4991239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
4992226633Sdim        return MCDisassembler::Fail; // UNDEFINED
4993239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
4994243830Sdim
4995243830Sdim      switch (fieldFromInstruction(Insn, 4, 2)) {
4996341825Sdim        case 0:
4997243830Sdim          align = 0; break;
4998243830Sdim        case 3:
4999243830Sdim          align = 4; break;
5000243830Sdim        default:
5001243830Sdim          return MCDisassembler::Fail;
5002243830Sdim      }
5003243830Sdim      break;
5004226633Sdim  }
5005221345Sdim
5006226633Sdim  if (Rm != 0xF) { // Writeback
5007226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5008226633Sdim    return MCDisassembler::Fail;
5009226633Sdim  }
5010226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5011226633Sdim    return MCDisassembler::Fail;
5012288943Sdim  Inst.addOperand(MCOperand::createImm(align));
5013226633Sdim  if (Rm != 0xF) {
5014226633Sdim    if (Rm != 0xD) {
5015226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5016226633Sdim    return MCDisassembler::Fail;
5017226633Sdim    } else
5018288943Sdim      Inst.addOperand(MCOperand::createReg(0));
5019226633Sdim  }
5020206124Srdivacky
5021226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5022226633Sdim    return MCDisassembler::Fail;
5023288943Sdim  Inst.addOperand(MCOperand::createImm(index));
5024226633Sdim
5025226633Sdim  return S;
5026206124Srdivacky}
5027206124Srdivacky
5028234353Sdimstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
5029226633Sdim                         uint64_t Address, const void *Decoder) {
5030226633Sdim  DecodeStatus S = MCDisassembler::Success;
5031226633Sdim
5032239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5033239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5034239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5035239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5036239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
5037226633Sdim
5038226633Sdim  unsigned align = 0;
5039226633Sdim  unsigned index = 0;
5040226633Sdim  unsigned inc = 1;
5041226633Sdim  switch (size) {
5042226633Sdim    default:
5043226633Sdim      return MCDisassembler::Fail;
5044226633Sdim    case 0:
5045239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
5046239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5047226633Sdim        align = 2;
5048226633Sdim      break;
5049226633Sdim    case 1:
5050239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
5051239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5052226633Sdim        align = 4;
5053239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
5054226633Sdim        inc = 2;
5055226633Sdim      break;
5056226633Sdim    case 2:
5057239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
5058226633Sdim        return MCDisassembler::Fail; // UNDEFINED
5059239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
5060239462Sdim      if (fieldFromInstruction(Insn, 4, 1) != 0)
5061226633Sdim        align = 8;
5062239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
5063226633Sdim        inc = 2;
5064226633Sdim      break;
5065207618Srdivacky  }
5066226633Sdim
5067226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5068226633Sdim    return MCDisassembler::Fail;
5069226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
5070226633Sdim    return MCDisassembler::Fail;
5071226633Sdim  if (Rm != 0xF) { // Writeback
5072226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5073226633Sdim      return MCDisassembler::Fail;
5074226633Sdim  }
5075226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5076226633Sdim    return MCDisassembler::Fail;
5077288943Sdim  Inst.addOperand(MCOperand::createImm(align));
5078226633Sdim  if (Rm != 0xF) {
5079226633Sdim    if (Rm != 0xD) {
5080226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5081226633Sdim        return MCDisassembler::Fail;
5082226633Sdim    } else
5083288943Sdim      Inst.addOperand(MCOperand::createReg(0));
5084226633Sdim  }
5085226633Sdim
5086226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5087226633Sdim    return MCDisassembler::Fail;
5088226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
5089226633Sdim    return MCDisassembler::Fail;
5090288943Sdim  Inst.addOperand(MCOperand::createImm(index));
5091226633Sdim
5092226633Sdim  return S;
5093206124Srdivacky}
5094206124Srdivacky
5095234353Sdimstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
5096226633Sdim                         uint64_t Address, const void *Decoder) {
5097226633Sdim  DecodeStatus S = MCDisassembler::Success;
5098207618Srdivacky
5099239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5100239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5101239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5102239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5103239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
5104226633Sdim
5105226633Sdim  unsigned align = 0;
5106226633Sdim  unsigned index = 0;
5107226633Sdim  unsigned inc = 1;
5108226633Sdim  switch (size) {
5109226633Sdim    default:
5110226633Sdim      return MCDisassembler::Fail;
5111226633Sdim    case 0:
5112239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
5113239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5114226633Sdim        align = 2;
5115226633Sdim      break;
5116226633Sdim    case 1:
5117239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
5118239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5119226633Sdim        align = 4;
5120239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
5121226633Sdim        inc = 2;
5122226633Sdim      break;
5123226633Sdim    case 2:
5124239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
5125226633Sdim        return MCDisassembler::Fail; // UNDEFINED
5126239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
5127239462Sdim      if (fieldFromInstruction(Insn, 4, 1) != 0)
5128226633Sdim        align = 8;
5129239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
5130226633Sdim        inc = 2;
5131226633Sdim      break;
5132207618Srdivacky  }
5133226633Sdim
5134226633Sdim  if (Rm != 0xF) { // Writeback
5135226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5136226633Sdim      return MCDisassembler::Fail;
5137207618Srdivacky  }
5138226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5139226633Sdim    return MCDisassembler::Fail;
5140288943Sdim  Inst.addOperand(MCOperand::createImm(align));
5141226633Sdim  if (Rm != 0xF) {
5142226633Sdim    if (Rm != 0xD) {
5143226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5144226633Sdim        return MCDisassembler::Fail;
5145226633Sdim    } else
5146288943Sdim      Inst.addOperand(MCOperand::createReg(0));
5147226633Sdim  }
5148207618Srdivacky
5149226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5150226633Sdim    return MCDisassembler::Fail;
5151226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
5152226633Sdim    return MCDisassembler::Fail;
5153288943Sdim  Inst.addOperand(MCOperand::createImm(index));
5154207618Srdivacky
5155226633Sdim  return S;
5156206124Srdivacky}
5157206124Srdivacky
5158234353Sdimstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
5159226633Sdim                         uint64_t Address, const void *Decoder) {
5160226633Sdim  DecodeStatus S = MCDisassembler::Success;
5161226633Sdim
5162239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5163239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5164239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5165239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5166239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
5167226633Sdim
5168226633Sdim  unsigned align = 0;
5169226633Sdim  unsigned index = 0;
5170226633Sdim  unsigned inc = 1;
5171226633Sdim  switch (size) {
5172226633Sdim    default:
5173226633Sdim      return MCDisassembler::Fail;
5174226633Sdim    case 0:
5175239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5176226633Sdim        return MCDisassembler::Fail; // UNDEFINED
5177239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
5178226633Sdim      break;
5179226633Sdim    case 1:
5180239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5181226633Sdim        return MCDisassembler::Fail; // UNDEFINED
5182239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
5183239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
5184226633Sdim        inc = 2;
5185226633Sdim      break;
5186226633Sdim    case 2:
5187239462Sdim      if (fieldFromInstruction(Insn, 4, 2))
5188226633Sdim        return MCDisassembler::Fail; // UNDEFINED
5189239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
5190239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
5191226633Sdim        inc = 2;
5192226633Sdim      break;
5193206124Srdivacky  }
5194226633Sdim
5195226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5196226633Sdim    return MCDisassembler::Fail;
5197226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
5198226633Sdim    return MCDisassembler::Fail;
5199226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
5200226633Sdim    return MCDisassembler::Fail;
5201226633Sdim
5202226633Sdim  if (Rm != 0xF) { // Writeback
5203226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5204226633Sdim    return MCDisassembler::Fail;
5205226633Sdim  }
5206226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5207226633Sdim    return MCDisassembler::Fail;
5208288943Sdim  Inst.addOperand(MCOperand::createImm(align));
5209226633Sdim  if (Rm != 0xF) {
5210226633Sdim    if (Rm != 0xD) {
5211226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5212226633Sdim    return MCDisassembler::Fail;
5213226633Sdim    } else
5214288943Sdim      Inst.addOperand(MCOperand::createReg(0));
5215226633Sdim  }
5216226633Sdim
5217226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5218226633Sdim    return MCDisassembler::Fail;
5219226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
5220226633Sdim    return MCDisassembler::Fail;
5221226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
5222226633Sdim    return MCDisassembler::Fail;
5223288943Sdim  Inst.addOperand(MCOperand::createImm(index));
5224226633Sdim
5225226633Sdim  return S;
5226206124Srdivacky}
5227206124Srdivacky
5228234353Sdimstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
5229226633Sdim                         uint64_t Address, const void *Decoder) {
5230226633Sdim  DecodeStatus S = MCDisassembler::Success;
5231226633Sdim
5232239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5233239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5234239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5235239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5236239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
5237226633Sdim
5238226633Sdim  unsigned align = 0;
5239226633Sdim  unsigned index = 0;
5240226633Sdim  unsigned inc = 1;
5241226633Sdim  switch (size) {
5242226633Sdim    default:
5243226633Sdim      return MCDisassembler::Fail;
5244226633Sdim    case 0:
5245239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5246226633Sdim        return MCDisassembler::Fail; // UNDEFINED
5247239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
5248226633Sdim      break;
5249226633Sdim    case 1:
5250239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5251226633Sdim        return MCDisassembler::Fail; // UNDEFINED
5252239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
5253239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
5254226633Sdim        inc = 2;
5255226633Sdim      break;
5256226633Sdim    case 2:
5257239462Sdim      if (fieldFromInstruction(Insn, 4, 2))
5258226633Sdim        return MCDisassembler::Fail; // UNDEFINED
5259239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
5260239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
5261226633Sdim        inc = 2;
5262226633Sdim      break;
5263226633Sdim  }
5264226633Sdim
5265226633Sdim  if (Rm != 0xF) { // Writeback
5266226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5267226633Sdim    return MCDisassembler::Fail;
5268226633Sdim  }
5269226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5270226633Sdim    return MCDisassembler::Fail;
5271288943Sdim  Inst.addOperand(MCOperand::createImm(align));
5272226633Sdim  if (Rm != 0xF) {
5273226633Sdim    if (Rm != 0xD) {
5274226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5275226633Sdim    return MCDisassembler::Fail;
5276226633Sdim    } else
5277288943Sdim      Inst.addOperand(MCOperand::createReg(0));
5278226633Sdim  }
5279226633Sdim
5280226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5281226633Sdim    return MCDisassembler::Fail;
5282226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
5283226633Sdim    return MCDisassembler::Fail;
5284226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
5285226633Sdim    return MCDisassembler::Fail;
5286288943Sdim  Inst.addOperand(MCOperand::createImm(index));
5287226633Sdim
5288226633Sdim  return S;
5289206124Srdivacky}
5290206124Srdivacky
5291234353Sdimstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
5292226633Sdim                         uint64_t Address, const void *Decoder) {
5293226633Sdim  DecodeStatus S = MCDisassembler::Success;
5294226633Sdim
5295239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5296239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5297239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5298239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5299239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
5300226633Sdim
5301226633Sdim  unsigned align = 0;
5302226633Sdim  unsigned index = 0;
5303226633Sdim  unsigned inc = 1;
5304226633Sdim  switch (size) {
5305226633Sdim    default:
5306226633Sdim      return MCDisassembler::Fail;
5307226633Sdim    case 0:
5308239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5309226633Sdim        align = 4;
5310239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
5311226633Sdim      break;
5312226633Sdim    case 1:
5313239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5314226633Sdim        align = 8;
5315239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
5316239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
5317226633Sdim        inc = 2;
5318226633Sdim      break;
5319226633Sdim    case 2:
5320243830Sdim      switch (fieldFromInstruction(Insn, 4, 2)) {
5321243830Sdim        case 0:
5322243830Sdim          align = 0; break;
5323243830Sdim        case 3:
5324243830Sdim          return MCDisassembler::Fail;
5325243830Sdim        default:
5326243830Sdim          align = 4 << fieldFromInstruction(Insn, 4, 2); break;
5327243830Sdim      }
5328243830Sdim
5329239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
5330239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
5331226633Sdim        inc = 2;
5332226633Sdim      break;
5333226633Sdim  }
5334226633Sdim
5335226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5336226633Sdim    return MCDisassembler::Fail;
5337226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
5338226633Sdim    return MCDisassembler::Fail;
5339226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
5340226633Sdim    return MCDisassembler::Fail;
5341226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
5342226633Sdim    return MCDisassembler::Fail;
5343226633Sdim
5344226633Sdim  if (Rm != 0xF) { // Writeback
5345226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5346226633Sdim      return MCDisassembler::Fail;
5347226633Sdim  }
5348226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5349226633Sdim    return MCDisassembler::Fail;
5350288943Sdim  Inst.addOperand(MCOperand::createImm(align));
5351226633Sdim  if (Rm != 0xF) {
5352226633Sdim    if (Rm != 0xD) {
5353226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5354226633Sdim        return MCDisassembler::Fail;
5355226633Sdim    } else
5356288943Sdim      Inst.addOperand(MCOperand::createReg(0));
5357226633Sdim  }
5358226633Sdim
5359226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5360226633Sdim    return MCDisassembler::Fail;
5361226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
5362226633Sdim    return MCDisassembler::Fail;
5363226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
5364226633Sdim    return MCDisassembler::Fail;
5365226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
5366226633Sdim    return MCDisassembler::Fail;
5367288943Sdim  Inst.addOperand(MCOperand::createImm(index));
5368226633Sdim
5369226633Sdim  return S;
5370206124Srdivacky}
5371206124Srdivacky
5372234353Sdimstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
5373226633Sdim                         uint64_t Address, const void *Decoder) {
5374226633Sdim  DecodeStatus S = MCDisassembler::Success;
5375226633Sdim
5376239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5377239462Sdim  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5378239462Sdim  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5379239462Sdim  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5380239462Sdim  unsigned size = fieldFromInstruction(Insn, 10, 2);
5381226633Sdim
5382226633Sdim  unsigned align = 0;
5383226633Sdim  unsigned index = 0;
5384226633Sdim  unsigned inc = 1;
5385226633Sdim  switch (size) {
5386226633Sdim    default:
5387226633Sdim      return MCDisassembler::Fail;
5388226633Sdim    case 0:
5389239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5390226633Sdim        align = 4;
5391239462Sdim      index = fieldFromInstruction(Insn, 5, 3);
5392226633Sdim      break;
5393226633Sdim    case 1:
5394239462Sdim      if (fieldFromInstruction(Insn, 4, 1))
5395226633Sdim        align = 8;
5396239462Sdim      index = fieldFromInstruction(Insn, 6, 2);
5397239462Sdim      if (fieldFromInstruction(Insn, 5, 1))
5398226633Sdim        inc = 2;
5399226633Sdim      break;
5400226633Sdim    case 2:
5401243830Sdim      switch (fieldFromInstruction(Insn, 4, 2)) {
5402243830Sdim        case 0:
5403243830Sdim          align = 0; break;
5404243830Sdim        case 3:
5405243830Sdim          return MCDisassembler::Fail;
5406243830Sdim        default:
5407243830Sdim          align = 4 << fieldFromInstruction(Insn, 4, 2); break;
5408243830Sdim      }
5409243830Sdim
5410239462Sdim      index = fieldFromInstruction(Insn, 7, 1);
5411239462Sdim      if (fieldFromInstruction(Insn, 6, 1))
5412226633Sdim        inc = 2;
5413226633Sdim      break;
5414226633Sdim  }
5415226633Sdim
5416226633Sdim  if (Rm != 0xF) { // Writeback
5417226633Sdim    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5418226633Sdim    return MCDisassembler::Fail;
5419226633Sdim  }
5420226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5421226633Sdim    return MCDisassembler::Fail;
5422288943Sdim  Inst.addOperand(MCOperand::createImm(align));
5423226633Sdim  if (Rm != 0xF) {
5424226633Sdim    if (Rm != 0xD) {
5425226633Sdim      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5426226633Sdim    return MCDisassembler::Fail;
5427226633Sdim    } else
5428288943Sdim      Inst.addOperand(MCOperand::createReg(0));
5429226633Sdim  }
5430226633Sdim
5431226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5432226633Sdim    return MCDisassembler::Fail;
5433226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
5434226633Sdim    return MCDisassembler::Fail;
5435226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
5436226633Sdim    return MCDisassembler::Fail;
5437226633Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
5438226633Sdim    return MCDisassembler::Fail;
5439288943Sdim  Inst.addOperand(MCOperand::createImm(index));
5440226633Sdim
5441226633Sdim  return S;
5442206124Srdivacky}
5443206124Srdivacky
5444234353Sdimstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
5445226633Sdim                                  uint64_t Address, const void *Decoder) {
5446226633Sdim  DecodeStatus S = MCDisassembler::Success;
5447239462Sdim  unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
5448239462Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
5449239462Sdim  unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
5450239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
5451239462Sdim  Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
5452226633Sdim
5453226633Sdim  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
5454226633Sdim    S = MCDisassembler::SoftFail;
5455226633Sdim
5456226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
5457226633Sdim    return MCDisassembler::Fail;
5458226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
5459226633Sdim    return MCDisassembler::Fail;
5460226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
5461226633Sdim    return MCDisassembler::Fail;
5462226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
5463226633Sdim    return MCDisassembler::Fail;
5464226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5465226633Sdim    return MCDisassembler::Fail;
5466226633Sdim
5467226633Sdim  return S;
5468207618Srdivacky}
5469207618Srdivacky
5470234353Sdimstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
5471226633Sdim                                  uint64_t Address, const void *Decoder) {
5472226633Sdim  DecodeStatus S = MCDisassembler::Success;
5473239462Sdim  unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
5474239462Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
5475239462Sdim  unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
5476239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
5477239462Sdim  Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
5478226633Sdim
5479226633Sdim  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
5480226633Sdim    S = MCDisassembler::SoftFail;
5481226633Sdim
5482226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
5483226633Sdim    return MCDisassembler::Fail;
5484226633Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
5485226633Sdim    return MCDisassembler::Fail;
5486226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
5487226633Sdim    return MCDisassembler::Fail;
5488226633Sdim  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
5489226633Sdim    return MCDisassembler::Fail;
5490226633Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5491226633Sdim    return MCDisassembler::Fail;
5492226633Sdim
5493226633Sdim  return S;
5494207618Srdivacky}
5495226633Sdim
5496234353Sdimstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn,
5497226633Sdim                             uint64_t Address, const void *Decoder) {
5498226633Sdim  DecodeStatus S = MCDisassembler::Success;
5499239462Sdim  unsigned pred = fieldFromInstruction(Insn, 4, 4);
5500239462Sdim  unsigned mask = fieldFromInstruction(Insn, 0, 4);
5501226633Sdim
5502226633Sdim  if (pred == 0xF) {
5503226633Sdim    pred = 0xE;
5504226633Sdim    S = MCDisassembler::SoftFail;
5505226633Sdim  }
5506226633Sdim
5507261991Sdim  if (mask == 0x0)
5508261991Sdim    return MCDisassembler::Fail;
5509226633Sdim
5510353358Sdim  // IT masks are encoded as a sequence of replacement low-order bits
5511353358Sdim  // for the condition code. So if the low bit of the starting
5512353358Sdim  // condition code is 1, then we have to flip all the bits above the
5513353358Sdim  // terminating bit (which is the lowest 1 bit).
5514353358Sdim  if (pred & 1) {
5515353358Sdim    unsigned LowBit = mask & -mask;
5516353358Sdim    unsigned BitsAboveLowBit = 0xF & (-LowBit << 1);
5517353358Sdim    mask ^= BitsAboveLowBit;
5518353358Sdim  }
5519353358Sdim
5520288943Sdim  Inst.addOperand(MCOperand::createImm(pred));
5521288943Sdim  Inst.addOperand(MCOperand::createImm(mask));
5522226633Sdim  return S;
5523226633Sdim}
5524226633Sdim
5525226633Sdimstatic DecodeStatus
5526234353SdimDecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
5527226633Sdim                           uint64_t Address, const void *Decoder) {
5528226633Sdim  DecodeStatus S = MCDisassembler::Success;
5529226633Sdim
5530239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5531239462Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
5532239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5533239462Sdim  unsigned addr = fieldFromInstruction(Insn, 0, 8);
5534239462Sdim  unsigned W = fieldFromInstruction(Insn, 21, 1);
5535239462Sdim  unsigned U = fieldFromInstruction(Insn, 23, 1);
5536239462Sdim  unsigned P = fieldFromInstruction(Insn, 24, 1);
5537226633Sdim  bool writeback = (W == 1) | (P == 0);
5538226633Sdim
5539226633Sdim  addr |= (U << 8) | (Rn << 9);
5540226633Sdim
5541226633Sdim  if (writeback && (Rn == Rt || Rn == Rt2))
5542226633Sdim    Check(S, MCDisassembler::SoftFail);
5543226633Sdim  if (Rt == Rt2)
5544226633Sdim    Check(S, MCDisassembler::SoftFail);
5545226633Sdim
5546226633Sdim  // Rt
5547226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
5548226633Sdim    return MCDisassembler::Fail;
5549226633Sdim  // Rt2
5550226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
5551226633Sdim    return MCDisassembler::Fail;
5552226633Sdim  // Writeback operand
5553226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
5554226633Sdim    return MCDisassembler::Fail;
5555226633Sdim  // addr
5556226633Sdim  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
5557226633Sdim    return MCDisassembler::Fail;
5558226633Sdim
5559226633Sdim  return S;
5560226633Sdim}
5561226633Sdim
5562226633Sdimstatic DecodeStatus
5563234353SdimDecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
5564226633Sdim                           uint64_t Address, const void *Decoder) {
5565226633Sdim  DecodeStatus S = MCDisassembler::Success;
5566226633Sdim
5567239462Sdim  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5568239462Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
5569239462Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5570239462Sdim  unsigned addr = fieldFromInstruction(Insn, 0, 8);
5571239462Sdim  unsigned W = fieldFromInstruction(Insn, 21, 1);
5572239462Sdim  unsigned U = fieldFromInstruction(Insn, 23, 1);
5573239462Sdim  unsigned P = fieldFromInstruction(Insn, 24, 1);
5574226633Sdim  bool writeback = (W == 1) | (P == 0);
5575226633Sdim
5576226633Sdim  addr |= (U << 8) | (Rn << 9);
5577226633Sdim
5578226633Sdim  if (writeback && (Rn == Rt || Rn == Rt2))
5579226633Sdim    Check(S, MCDisassembler::SoftFail);
5580226633Sdim
5581226633Sdim  // Writeback operand
5582226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
5583226633Sdim    return MCDisassembler::Fail;
5584226633Sdim  // Rt
5585226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
5586226633Sdim    return MCDisassembler::Fail;
5587226633Sdim  // Rt2
5588226633Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
5589226633Sdim    return MCDisassembler::Fail;
5590226633Sdim  // addr
5591226633Sdim  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
5592226633Sdim    return MCDisassembler::Fail;
5593226633Sdim
5594226633Sdim  return S;
5595226633Sdim}
5596226633Sdim
5597234353Sdimstatic DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn,
5598226633Sdim                                uint64_t Address, const void *Decoder) {
5599239462Sdim  unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
5600239462Sdim  unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
5601226633Sdim  if (sign1 != sign2) return MCDisassembler::Fail;
5602360784Sdim  const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
5603360784Sdim  assert(Inst.getNumOperands() == 0 && "We should receive an empty Inst");
5604360784Sdim  DecodeStatus S = DecoderGPRRegisterClass(Inst, Rd, Address, Decoder);
5605226633Sdim
5606239462Sdim  unsigned Val = fieldFromInstruction(Insn, 0, 8);
5607239462Sdim  Val |= fieldFromInstruction(Insn, 12, 3) << 8;
5608239462Sdim  Val |= fieldFromInstruction(Insn, 26, 1) << 11;
5609360784Sdim  // If sign, then it is decreasing the address.
5610360784Sdim  if (sign1) {
5611360784Sdim    // Following ARMv7 Architecture Manual, when the offset
5612360784Sdim    // is zero, it is decoded as a subw, not as a adr.w
5613360784Sdim    if (!Val) {
5614360784Sdim      Inst.setOpcode(ARM::t2SUBri12);
5615360784Sdim      Inst.addOperand(MCOperand::createReg(ARM::PC));
5616360784Sdim    } else
5617360784Sdim      Val = -Val;
5618360784Sdim  }
5619360784Sdim  Inst.addOperand(MCOperand::createImm(Val));
5620360784Sdim  return S;
5621226633Sdim}
5622226633Sdim
5623234353Sdimstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
5624226633Sdim                                              uint64_t Address,
5625226633Sdim                                              const void *Decoder) {
5626226633Sdim  DecodeStatus S = MCDisassembler::Success;
5627226633Sdim
5628226633Sdim  // Shift of "asr #32" is not allowed in Thumb2 mode.
5629288943Sdim  if (Val == 0x20) S = MCDisassembler::Fail;
5630288943Sdim  Inst.addOperand(MCOperand::createImm(Val));
5631226633Sdim  return S;
5632226633Sdim}
5633226633Sdim
5634234353Sdimstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
5635234353Sdim                               uint64_t Address, const void *Decoder) {
5636239462Sdim  unsigned Rt   = fieldFromInstruction(Insn, 12, 4);
5637239462Sdim  unsigned Rt2  = fieldFromInstruction(Insn, 0,  4);
5638239462Sdim  unsigned Rn   = fieldFromInstruction(Insn, 16, 4);
5639239462Sdim  unsigned pred = fieldFromInstruction(Insn, 28, 4);
5640234353Sdim
5641234353Sdim  if (pred == 0xF)
5642234353Sdim    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
5643234353Sdim
5644234353Sdim  DecodeStatus S = MCDisassembler::Success;
5645234982Sdim
5646234982Sdim  if (Rt == Rn || Rn == Rt2)
5647234982Sdim    S = MCDisassembler::SoftFail;
5648234982Sdim
5649234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5650234353Sdim    return MCDisassembler::Fail;
5651234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5652234353Sdim    return MCDisassembler::Fail;
5653234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
5654234353Sdim    return MCDisassembler::Fail;
5655234353Sdim  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5656234353Sdim    return MCDisassembler::Fail;
5657234353Sdim
5658234353Sdim  return S;
5659234353Sdim}
5660234353Sdim
5661234353Sdimstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
5662234353Sdim                                uint64_t Address, const void *Decoder) {
5663296417Sdim  const FeatureBitset &featureBits =
5664296417Sdim      ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
5665296417Sdim  bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
5666296417Sdim
5667239462Sdim  unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
5668239462Sdim  Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
5669239462Sdim  unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
5670239462Sdim  Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
5671239462Sdim  unsigned imm = fieldFromInstruction(Insn, 16, 6);
5672239462Sdim  unsigned cmode = fieldFromInstruction(Insn, 8, 4);
5673261991Sdim  unsigned op = fieldFromInstruction(Insn, 5, 1);
5674234353Sdim
5675234353Sdim  DecodeStatus S = MCDisassembler::Success;
5676234353Sdim
5677296417Sdim  // If the top 3 bits of imm are clear, this is a VMOV (immediate)
5678296417Sdim  if (!(imm & 0x38)) {
5679296417Sdim    if (cmode == 0xF) {
5680296417Sdim      if (op == 1) return MCDisassembler::Fail;
5681296417Sdim      Inst.setOpcode(ARM::VMOVv2f32);
5682296417Sdim    }
5683296417Sdim    if (hasFullFP16) {
5684296417Sdim      if (cmode == 0xE) {
5685296417Sdim        if (op == 1) {
5686296417Sdim          Inst.setOpcode(ARM::VMOVv1i64);
5687296417Sdim        } else {
5688296417Sdim          Inst.setOpcode(ARM::VMOVv8i8);
5689296417Sdim        }
5690296417Sdim      }
5691296417Sdim      if (cmode == 0xD) {
5692296417Sdim        if (op == 1) {
5693296417Sdim          Inst.setOpcode(ARM::VMVNv2i32);
5694296417Sdim        } else {
5695296417Sdim          Inst.setOpcode(ARM::VMOVv2i32);
5696296417Sdim        }
5697296417Sdim      }
5698296417Sdim      if (cmode == 0xC) {
5699296417Sdim        if (op == 1) {
5700296417Sdim          Inst.setOpcode(ARM::VMVNv2i32);
5701296417Sdim        } else {
5702296417Sdim          Inst.setOpcode(ARM::VMOVv2i32);
5703296417Sdim        }
5704296417Sdim      }
5705296417Sdim    }
5706360784Sdim    return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
5707234353Sdim  }
5708234353Sdim
5709261991Sdim  if (!(imm & 0x20)) return MCDisassembler::Fail;
5710234353Sdim
5711234353Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
5712234353Sdim    return MCDisassembler::Fail;
5713234353Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
5714234353Sdim    return MCDisassembler::Fail;
5715288943Sdim  Inst.addOperand(MCOperand::createImm(64 - imm));
5716234353Sdim
5717234353Sdim  return S;
5718234353Sdim}
5719234353Sdim
5720234353Sdimstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
5721234353Sdim                                uint64_t Address, const void *Decoder) {
5722296417Sdim  const FeatureBitset &featureBits =
5723296417Sdim      ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
5724296417Sdim  bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
5725296417Sdim
5726239462Sdim  unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
5727239462Sdim  Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
5728239462Sdim  unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
5729239462Sdim  Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
5730239462Sdim  unsigned imm = fieldFromInstruction(Insn, 16, 6);
5731239462Sdim  unsigned cmode = fieldFromInstruction(Insn, 8, 4);
5732261991Sdim  unsigned op = fieldFromInstruction(Insn, 5, 1);
5733234353Sdim
5734234353Sdim  DecodeStatus S = MCDisassembler::Success;
5735234353Sdim
5736296417Sdim  // If the top 3 bits of imm are clear, this is a VMOV (immediate)
5737296417Sdim  if (!(imm & 0x38)) {
5738296417Sdim    if (cmode == 0xF) {
5739296417Sdim      if (op == 1) return MCDisassembler::Fail;
5740296417Sdim      Inst.setOpcode(ARM::VMOVv4f32);
5741296417Sdim    }
5742296417Sdim    if (hasFullFP16) {
5743296417Sdim      if (cmode == 0xE) {
5744296417Sdim        if (op == 1) {
5745296417Sdim          Inst.setOpcode(ARM::VMOVv2i64);
5746296417Sdim        } else {
5747296417Sdim          Inst.setOpcode(ARM::VMOVv16i8);
5748296417Sdim        }
5749296417Sdim      }
5750296417Sdim      if (cmode == 0xD) {
5751296417Sdim        if (op == 1) {
5752296417Sdim          Inst.setOpcode(ARM::VMVNv4i32);
5753296417Sdim        } else {
5754296417Sdim          Inst.setOpcode(ARM::VMOVv4i32);
5755296417Sdim        }
5756296417Sdim      }
5757296417Sdim      if (cmode == 0xC) {
5758296417Sdim        if (op == 1) {
5759296417Sdim          Inst.setOpcode(ARM::VMVNv4i32);
5760296417Sdim        } else {
5761296417Sdim          Inst.setOpcode(ARM::VMOVv4i32);
5762296417Sdim        }
5763296417Sdim      }
5764296417Sdim    }
5765360784Sdim    return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
5766234353Sdim  }
5767234353Sdim
5768261991Sdim  if (!(imm & 0x20)) return MCDisassembler::Fail;
5769234353Sdim
5770234353Sdim  if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
5771234353Sdim    return MCDisassembler::Fail;
5772234353Sdim  if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
5773234353Sdim    return MCDisassembler::Fail;
5774288943Sdim  Inst.addOperand(MCOperand::createImm(64 - imm));
5775234353Sdim
5776234353Sdim  return S;
5777234353Sdim}
5778234353Sdim
5779327952Sdimstatic DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst,
5780327952Sdim                                                       unsigned Insn,
5781327952Sdim                                                       uint64_t Address,
5782327952Sdim                                                       const void *Decoder) {
5783327952Sdim  unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
5784327952Sdim  Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
5785327952Sdim  unsigned Vn = (fieldFromInstruction(Insn, 16, 4) << 0);
5786327952Sdim  Vn |= (fieldFromInstruction(Insn, 7, 1) << 4);
5787327952Sdim  unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
5788327952Sdim  Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
5789327952Sdim  unsigned q = (fieldFromInstruction(Insn, 6, 1) << 0);
5790327952Sdim  unsigned rotate = (fieldFromInstruction(Insn, 20, 2) << 0);
5791327952Sdim
5792327952Sdim  DecodeStatus S = MCDisassembler::Success;
5793327952Sdim
5794327952Sdim  auto DestRegDecoder = q ? DecodeQPRRegisterClass : DecodeDPRRegisterClass;
5795327952Sdim
5796327952Sdim  if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
5797327952Sdim    return MCDisassembler::Fail;
5798327952Sdim  if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
5799327952Sdim    return MCDisassembler::Fail;
5800327952Sdim  if (!Check(S, DestRegDecoder(Inst, Vn, Address, Decoder)))
5801327952Sdim    return MCDisassembler::Fail;
5802327952Sdim  if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
5803327952Sdim    return MCDisassembler::Fail;
5804327952Sdim  // The lane index does not have any bits in the encoding, because it can only
5805327952Sdim  // be 0.
5806327952Sdim  Inst.addOperand(MCOperand::createImm(0));
5807327952Sdim  Inst.addOperand(MCOperand::createImm(rotate));
5808327952Sdim
5809327952Sdim  return S;
5810327952Sdim}
5811327952Sdim
5812234353Sdimstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
5813234353Sdim                                uint64_t Address, const void *Decoder) {
5814234353Sdim  DecodeStatus S = MCDisassembler::Success;
5815234353Sdim
5816239462Sdim  unsigned Rn = fieldFromInstruction(Val, 16, 4);
5817239462Sdim  unsigned Rt = fieldFromInstruction(Val, 12, 4);
5818239462Sdim  unsigned Rm = fieldFromInstruction(Val, 0, 4);
5819239462Sdim  Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
5820239462Sdim  unsigned Cond = fieldFromInstruction(Val, 28, 4);
5821296417Sdim
5822239462Sdim  if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
5823234353Sdim    S = MCDisassembler::SoftFail;
5824234353Sdim
5825234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5826234353Sdim    return MCDisassembler::Fail;
5827234353Sdim  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
5828234353Sdim    return MCDisassembler::Fail;
5829341825Sdim  if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
5830234353Sdim    return MCDisassembler::Fail;
5831234353Sdim  if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
5832234353Sdim    return MCDisassembler::Fail;
5833234353Sdim  if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
5834234353Sdim    return MCDisassembler::Fail;
5835234353Sdim
5836234353Sdim  return S;
5837234353Sdim}
5838234353Sdim
5839321369Sdimstatic DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
5840309124Sdim                                            uint64_t Address, const void *Decoder) {
5841234982Sdim  DecodeStatus S = MCDisassembler::Success;
5842234982Sdim
5843239462Sdim  unsigned CRm = fieldFromInstruction(Val, 0, 4);
5844239462Sdim  unsigned opc1 = fieldFromInstruction(Val, 4, 4);
5845239462Sdim  unsigned cop = fieldFromInstruction(Val, 8, 4);
5846239462Sdim  unsigned Rt = fieldFromInstruction(Val, 12, 4);
5847239462Sdim  unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
5848234982Sdim
5849234982Sdim  if ((cop & ~0x1) == 0xa)
5850234982Sdim    return MCDisassembler::Fail;
5851234982Sdim
5852234982Sdim  if (Rt == Rt2)
5853234982Sdim    S = MCDisassembler::SoftFail;
5854234982Sdim
5855309124Sdim  // We have to check if the instruction is MRRC2
5856309124Sdim  // or MCRR2 when constructing the operands for
5857309124Sdim  // Inst. Reason is because MRRC2 stores to two
5858309124Sdim  // registers so it's tablegen desc has has two
5859309124Sdim  // outputs whereas MCRR doesn't store to any
5860309124Sdim  // registers so all of it's operands are listed
5861309124Sdim  // as inputs, therefore the operand order for
5862309124Sdim  // MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm]
5863309124Sdim  // and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm]
5864309124Sdim
5865309124Sdim  if (Inst.getOpcode() == ARM::MRRC2) {
5866309124Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5867309124Sdim      return MCDisassembler::Fail;
5868309124Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5869309124Sdim      return MCDisassembler::Fail;
5870309124Sdim  }
5871288943Sdim  Inst.addOperand(MCOperand::createImm(cop));
5872288943Sdim  Inst.addOperand(MCOperand::createImm(opc1));
5873309124Sdim  if (Inst.getOpcode() == ARM::MCRR2) {
5874309124Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5875309124Sdim      return MCDisassembler::Fail;
5876309124Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5877309124Sdim      return MCDisassembler::Fail;
5878309124Sdim  }
5879288943Sdim  Inst.addOperand(MCOperand::createImm(CRm));
5880234982Sdim
5881234982Sdim  return S;
5882234982Sdim}
5883327952Sdim
5884327952Sdimstatic DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
5885327952Sdim                                         uint64_t Address,
5886327952Sdim                                         const void *Decoder) {
5887327952Sdim  const FeatureBitset &featureBits =
5888327952Sdim      ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
5889327952Sdim  DecodeStatus S = MCDisassembler::Success;
5890327952Sdim
5891353358Sdim  // Add explicit operand for the destination sysreg, for cases where
5892353358Sdim  // we have to model it for code generation purposes.
5893353358Sdim  switch (Inst.getOpcode()) {
5894353358Sdim  case ARM::VMSR_FPSCR_NZCVQC:
5895353358Sdim    Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
5896353358Sdim    break;
5897353358Sdim  case ARM::VMSR_P0:
5898353358Sdim    Inst.addOperand(MCOperand::createReg(ARM::VPR));
5899353358Sdim    break;
5900353358Sdim  }
5901327952Sdim
5902353358Sdim  if (Inst.getOpcode() != ARM::FMSTAT) {
5903353358Sdim    unsigned Rt = fieldFromInstruction(Val, 12, 4);
5904327952Sdim
5905353358Sdim    if (featureBits[ARM::ModeThumb] && !featureBits[ARM::HasV8Ops]) {
5906353358Sdim      if (Rt == 13 || Rt == 15)
5907353358Sdim        S = MCDisassembler::SoftFail;
5908353358Sdim      Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder));
5909353358Sdim    } else
5910353358Sdim      Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder));
5911353358Sdim  }
5912353358Sdim
5913353358Sdim  // Add explicit operand for the source sysreg, similarly to above.
5914353358Sdim  switch (Inst.getOpcode()) {
5915353358Sdim  case ARM::VMRS_FPSCR_NZCVQC:
5916353358Sdim    Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
5917353358Sdim    break;
5918353358Sdim  case ARM::VMRS_P0:
5919353358Sdim    Inst.addOperand(MCOperand::createReg(ARM::VPR));
5920353358Sdim    break;
5921353358Sdim  }
5922353358Sdim
5923327952Sdim  if (featureBits[ARM::ModeThumb]) {
5924327952Sdim    Inst.addOperand(MCOperand::createImm(ARMCC::AL));
5925327952Sdim    Inst.addOperand(MCOperand::createReg(0));
5926327952Sdim  } else {
5927327952Sdim    unsigned pred = fieldFromInstruction(Val, 28, 4);
5928327952Sdim    if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5929327952Sdim      return MCDisassembler::Fail;
5930327952Sdim  }
5931327952Sdim
5932327952Sdim  return S;
5933327952Sdim}
5934353358Sdim
5935353358Sdimtemplate <bool isSigned, bool isNeg, bool zeroPermitted, int size>
5936353358Sdimstatic DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned Val,
5937353358Sdim                                         uint64_t Address,
5938353358Sdim                                         const void *Decoder) {
5939353358Sdim  DecodeStatus S = MCDisassembler::Success;
5940353358Sdim  if (Val == 0 && !zeroPermitted)
5941353358Sdim    S = MCDisassembler::Fail;
5942353358Sdim
5943353358Sdim  uint64_t DecVal;
5944353358Sdim  if (isSigned)
5945353358Sdim    DecVal = SignExtend32<size + 1>(Val << 1);
5946353358Sdim  else
5947353358Sdim    DecVal = (Val << 1);
5948353358Sdim
5949353358Sdim  if (!tryAddingSymbolicOperand(Address, Address + DecVal + 4, true, 4, Inst,
5950353358Sdim                                Decoder))
5951353358Sdim    Inst.addOperand(MCOperand::createImm(isNeg ? -DecVal : DecVal));
5952353358Sdim  return S;
5953353358Sdim}
5954353358Sdim
5955353358Sdimstatic DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned Val,
5956353358Sdim                                               uint64_t Address,
5957353358Sdim                                               const void *Decoder) {
5958353358Sdim
5959353358Sdim  uint64_t LocImm = Inst.getOperand(0).getImm();
5960353358Sdim  Val = LocImm + (2 << Val);
5961353358Sdim  if (!tryAddingSymbolicOperand(Address, Address + Val + 4, true, 4, Inst,
5962353358Sdim                                Decoder))
5963353358Sdim    Inst.addOperand(MCOperand::createImm(Val));
5964353358Sdim  return MCDisassembler::Success;
5965353358Sdim}
5966353358Sdim
5967353358Sdimstatic DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val,
5968353358Sdim                                          uint64_t Address,
5969353358Sdim                                          const void *Decoder) {
5970353358Sdim  if (Val >= ARMCC::AL)  // also exclude the non-condition NV
5971353358Sdim    return MCDisassembler::Fail;
5972353358Sdim  Inst.addOperand(MCOperand::createImm(Val));
5973353358Sdim  return MCDisassembler::Success;
5974353358Sdim}
5975353358Sdim
5976353358Sdimstatic DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address,
5977353358Sdim                                 const void *Decoder) {
5978353358Sdim  DecodeStatus S = MCDisassembler::Success;
5979353358Sdim
5980353358Sdim  if (Inst.getOpcode() == ARM::MVE_LCTP)
5981353358Sdim    return S;
5982353358Sdim
5983353358Sdim  unsigned Imm = fieldFromInstruction(Insn, 11, 1) |
5984353358Sdim                 fieldFromInstruction(Insn, 1, 10) << 1;
5985353358Sdim  switch (Inst.getOpcode()) {
5986353358Sdim  case ARM::t2LEUpdate:
5987353358Sdim  case ARM::MVE_LETP:
5988353358Sdim    Inst.addOperand(MCOperand::createReg(ARM::LR));
5989353358Sdim    Inst.addOperand(MCOperand::createReg(ARM::LR));
5990353358Sdim    LLVM_FALLTHROUGH;
5991353358Sdim  case ARM::t2LE:
5992353358Sdim    if (!Check(S, DecodeBFLabelOperand<false, true, true, 11>(
5993353358Sdim                   Inst, Imm, Address, Decoder)))
5994353358Sdim      return MCDisassembler::Fail;
5995353358Sdim    break;
5996353358Sdim  case ARM::t2WLS:
5997353358Sdim  case ARM::MVE_WLSTP_8:
5998353358Sdim  case ARM::MVE_WLSTP_16:
5999353358Sdim  case ARM::MVE_WLSTP_32:
6000353358Sdim  case ARM::MVE_WLSTP_64:
6001353358Sdim    Inst.addOperand(MCOperand::createReg(ARM::LR));
6002353358Sdim    if (!Check(S,
6003353358Sdim               DecoderGPRRegisterClass(Inst, fieldFromInstruction(Insn, 16, 4),
6004353358Sdim                                       Address, Decoder)) ||
6005353358Sdim        !Check(S, DecodeBFLabelOperand<false, false, true, 11>(
6006353358Sdim                   Inst, Imm, Address, Decoder)))
6007353358Sdim      return MCDisassembler::Fail;
6008353358Sdim    break;
6009353358Sdim  case ARM::t2DLS:
6010353358Sdim  case ARM::MVE_DLSTP_8:
6011353358Sdim  case ARM::MVE_DLSTP_16:
6012353358Sdim  case ARM::MVE_DLSTP_32:
6013353358Sdim  case ARM::MVE_DLSTP_64:
6014353358Sdim    unsigned Rn = fieldFromInstruction(Insn, 16, 4);
6015353358Sdim    if (Rn == 0xF) {
6016353358Sdim      // Enforce all the rest of the instruction bits in LCTP, which
6017353358Sdim      // won't have been reliably checked based on LCTP's own tablegen
6018353358Sdim      // record, because we came to this decode by a roundabout route.
6019353358Sdim      uint32_t CanonicalLCTP = 0xF00FE001, SBZMask = 0x00300FFE;
6020353358Sdim      if ((Insn & ~SBZMask) != CanonicalLCTP)
6021353358Sdim        return MCDisassembler::Fail;   // a mandatory bit is wrong: hard fail
6022353358Sdim      if (Insn != CanonicalLCTP)
6023353358Sdim        Check(S, MCDisassembler::SoftFail); // an SBZ bit is wrong: soft fail
6024353358Sdim
6025353358Sdim      Inst.setOpcode(ARM::MVE_LCTP);
6026353358Sdim    } else {
6027353358Sdim      Inst.addOperand(MCOperand::createReg(ARM::LR));
6028353358Sdim      if (!Check(S, DecoderGPRRegisterClass(Inst,
6029353358Sdim                                            fieldFromInstruction(Insn, 16, 4),
6030353358Sdim                                            Address, Decoder)))
6031353358Sdim        return MCDisassembler::Fail;
6032353358Sdim    }
6033353358Sdim    break;
6034353358Sdim  }
6035353358Sdim  return S;
6036353358Sdim}
6037353358Sdim
6038353358Sdimstatic DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val,
6039353358Sdim                                           uint64_t Address,
6040353358Sdim                                           const void *Decoder) {
6041353358Sdim  DecodeStatus S = MCDisassembler::Success;
6042353358Sdim
6043353358Sdim  if (Val == 0)
6044353358Sdim    Val = 32;
6045353358Sdim
6046353358Sdim  Inst.addOperand(MCOperand::createImm(Val));
6047353358Sdim
6048353358Sdim  return S;
6049353358Sdim}
6050353358Sdim
6051353358Sdimstatic DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo,
6052353358Sdim                                   uint64_t Address, const void *Decoder) {
6053353358Sdim  if ((RegNo) + 1 > 11)
6054353358Sdim    return MCDisassembler::Fail;
6055353358Sdim
6056353358Sdim  unsigned Register = GPRDecoderTable[(RegNo) + 1];
6057353358Sdim  Inst.addOperand(MCOperand::createReg(Register));
6058353358Sdim  return MCDisassembler::Success;
6059353358Sdim}
6060353358Sdim
6061353358Sdimstatic DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo,
6062353358Sdim                                   uint64_t Address, const void *Decoder) {
6063353358Sdim  if ((RegNo) > 14)
6064353358Sdim    return MCDisassembler::Fail;
6065353358Sdim
6066353358Sdim  unsigned Register = GPRDecoderTable[(RegNo)];
6067353358Sdim  Inst.addOperand(MCOperand::createReg(Register));
6068353358Sdim  return MCDisassembler::Success;
6069353358Sdim}
6070353358Sdim
6071353358Sdimstatic DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
6072353358Sdim                                  const void *Decoder) {
6073353358Sdim  DecodeStatus S = MCDisassembler::Success;
6074353358Sdim
6075353358Sdim  Inst.addOperand(MCOperand::createImm(ARMCC::AL));
6076353358Sdim  Inst.addOperand(MCOperand::createReg(0));
6077353358Sdim  if (Inst.getOpcode() == ARM::VSCCLRMD) {
6078353358Sdim    unsigned reglist = (fieldFromInstruction(Insn, 1, 7) << 1) |
6079353358Sdim                       (fieldFromInstruction(Insn, 12, 4) << 8) |
6080353358Sdim                       (fieldFromInstruction(Insn, 22, 1) << 12);
6081353358Sdim    if (!Check(S, DecodeDPRRegListOperand(Inst, reglist, Address, Decoder))) {
6082353358Sdim      return MCDisassembler::Fail;
6083353358Sdim    }
6084353358Sdim  } else {
6085353358Sdim    unsigned reglist = fieldFromInstruction(Insn, 0, 8) |
6086353358Sdim                       (fieldFromInstruction(Insn, 22, 1) << 8) |
6087353358Sdim                       (fieldFromInstruction(Insn, 12, 4) << 9);
6088353358Sdim    if (!Check(S, DecodeSPRRegListOperand(Inst, reglist, Address, Decoder))) {
6089353358Sdim      return MCDisassembler::Fail;
6090353358Sdim    }
6091353358Sdim  }
6092353358Sdim  Inst.addOperand(MCOperand::createReg(ARM::VPR));
6093353358Sdim
6094353358Sdim  return S;
6095353358Sdim}
6096353358Sdim
6097353358Sdimstatic DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
6098353358Sdim                              uint64_t Address,
6099353358Sdim                              const void *Decoder) {
6100353358Sdim  if (RegNo > 7)
6101353358Sdim    return MCDisassembler::Fail;
6102353358Sdim
6103353358Sdim  unsigned Register = QPRDecoderTable[RegNo];
6104353358Sdim  Inst.addOperand(MCOperand::createReg(Register));
6105353358Sdim  return MCDisassembler::Success;
6106353358Sdim}
6107353358Sdim
6108353358Sdimstatic const uint16_t QQPRDecoderTable[] = {
6109353358Sdim     ARM::Q0_Q1,  ARM::Q1_Q2,  ARM::Q2_Q3,  ARM::Q3_Q4,
6110353358Sdim     ARM::Q4_Q5,  ARM::Q5_Q6,  ARM::Q6_Q7
6111353358Sdim};
6112353358Sdim
6113353358Sdimstatic DecodeStatus DecodeQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
6114353358Sdim                              uint64_t Address,
6115353358Sdim                              const void *Decoder) {
6116353358Sdim  if (RegNo > 6)
6117353358Sdim    return MCDisassembler::Fail;
6118353358Sdim
6119353358Sdim  unsigned Register = QQPRDecoderTable[RegNo];
6120353358Sdim  Inst.addOperand(MCOperand::createReg(Register));
6121353358Sdim  return MCDisassembler::Success;
6122353358Sdim}
6123353358Sdim
6124353358Sdimstatic const uint16_t QQQQPRDecoderTable[] = {
6125353358Sdim     ARM::Q0_Q1_Q2_Q3,  ARM::Q1_Q2_Q3_Q4,  ARM::Q2_Q3_Q4_Q5,
6126353358Sdim     ARM::Q3_Q4_Q5_Q6,  ARM::Q4_Q5_Q6_Q7
6127353358Sdim};
6128353358Sdim
6129353358Sdimstatic DecodeStatus DecodeQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
6130353358Sdim                              uint64_t Address,
6131353358Sdim                              const void *Decoder) {
6132353358Sdim  if (RegNo > 4)
6133353358Sdim    return MCDisassembler::Fail;
6134353358Sdim
6135353358Sdim  unsigned Register = QQQQPRDecoderTable[RegNo];
6136353358Sdim  Inst.addOperand(MCOperand::createReg(Register));
6137353358Sdim  return MCDisassembler::Success;
6138353358Sdim}
6139353358Sdim
6140353358Sdimstatic DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
6141353358Sdim                                         uint64_t Address,
6142353358Sdim                                         const void *Decoder) {
6143353358Sdim  DecodeStatus S = MCDisassembler::Success;
6144353358Sdim
6145353358Sdim  // Parse VPT mask and encode it in the MCInst as an immediate with the same
6146353358Sdim  // format as the it_mask.  That is, from the second 'e|t' encode 'e' as 1 and
6147353358Sdim  // 't' as 0 and finish with a 1.
6148353358Sdim  unsigned Imm = 0;
6149353358Sdim  // We always start with a 't'.
6150353358Sdim  unsigned CurBit = 0;
6151353358Sdim  for (int i = 3; i >= 0; --i) {
6152353358Sdim    // If the bit we are looking at is not the same as last one, invert the
6153353358Sdim    // CurBit, if it is the same leave it as is.
6154353358Sdim    CurBit ^= (Val >> i) & 1U;
6155353358Sdim
6156353358Sdim    // Encode the CurBit at the right place in the immediate.
6157353358Sdim    Imm |= (CurBit << i);
6158353358Sdim
6159353358Sdim    // If we are done, finish the encoding with a 1.
6160353358Sdim    if ((Val & ~(~0U << i)) == 0) {
6161353358Sdim      Imm |= 1U << i;
6162353358Sdim      break;
6163353358Sdim    }
6164353358Sdim  }
6165353358Sdim
6166353358Sdim  Inst.addOperand(MCOperand::createImm(Imm));
6167353358Sdim
6168353358Sdim  return S;
6169353358Sdim}
6170353358Sdim
6171353358Sdimstatic DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned RegNo,
6172353358Sdim                                        uint64_t Address, const void *Decoder) {
6173353358Sdim  // The vpred_r operand type includes an MQPR register field derived
6174353358Sdim  // from the encoding. But we don't actually want to add an operand
6175353358Sdim  // to the MCInst at this stage, because AddThumbPredicate will do it
6176353358Sdim  // later, and will infer the register number from the TIED_TO
6177353358Sdim  // constraint. So this is a deliberately empty decoder method that
6178353358Sdim  // will inhibit the auto-generated disassembly code from adding an
6179353358Sdim  // operand at all.
6180353358Sdim  return MCDisassembler::Success;
6181353358Sdim}
6182353358Sdim
6183353358Sdimstatic DecodeStatus DecodeRestrictedIPredicateOperand(MCInst &Inst,
6184353358Sdim                                                      unsigned Val,
6185353358Sdim                                                      uint64_t Address,
6186353358Sdim                                                      const void *Decoder) {
6187353358Sdim  Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::EQ : ARMCC::NE));
6188353358Sdim  return MCDisassembler::Success;
6189353358Sdim}
6190353358Sdim
6191353358Sdimstatic DecodeStatus DecodeRestrictedSPredicateOperand(MCInst &Inst,
6192353358Sdim                                                      unsigned Val,
6193353358Sdim                                                      uint64_t Address,
6194353358Sdim                                                      const void *Decoder) {
6195353358Sdim  unsigned Code;
6196353358Sdim  switch (Val & 0x3) {
6197353358Sdim  case 0:
6198353358Sdim    Code = ARMCC::GE;
6199353358Sdim    break;
6200353358Sdim  case 1:
6201353358Sdim    Code = ARMCC::LT;
6202353358Sdim    break;
6203353358Sdim  case 2:
6204353358Sdim    Code = ARMCC::GT;
6205353358Sdim    break;
6206353358Sdim  case 3:
6207353358Sdim    Code = ARMCC::LE;
6208353358Sdim    break;
6209353358Sdim  }
6210353358Sdim  Inst.addOperand(MCOperand::createImm(Code));
6211353358Sdim  return MCDisassembler::Success;
6212353358Sdim}
6213353358Sdim
6214353358Sdimstatic DecodeStatus DecodeRestrictedUPredicateOperand(MCInst &Inst,
6215353358Sdim                                                      unsigned Val,
6216353358Sdim                                                      uint64_t Address,
6217353358Sdim                                                      const void *Decoder) {
6218353358Sdim  Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::HS : ARMCC::HI));
6219353358Sdim  return MCDisassembler::Success;
6220353358Sdim}
6221353358Sdim
6222353358Sdimstatic DecodeStatus DecodeRestrictedFPPredicateOperand(MCInst &Inst, unsigned Val,
6223353358Sdim                                                     uint64_t Address,
6224353358Sdim                                                     const void *Decoder) {
6225353358Sdim  unsigned Code;
6226353358Sdim  switch (Val) {
6227353358Sdim  default:
6228353358Sdim    return MCDisassembler::Fail;
6229353358Sdim  case 0:
6230353358Sdim    Code = ARMCC::EQ;
6231353358Sdim    break;
6232353358Sdim  case 1:
6233353358Sdim    Code = ARMCC::NE;
6234353358Sdim    break;
6235353358Sdim  case 4:
6236353358Sdim    Code = ARMCC::GE;
6237353358Sdim    break;
6238353358Sdim  case 5:
6239353358Sdim    Code = ARMCC::LT;
6240353358Sdim    break;
6241353358Sdim  case 6:
6242353358Sdim    Code = ARMCC::GT;
6243353358Sdim    break;
6244353358Sdim  case 7:
6245353358Sdim    Code = ARMCC::LE;
6246353358Sdim    break;
6247353358Sdim  }
6248353358Sdim
6249353358Sdim  Inst.addOperand(MCOperand::createImm(Code));
6250353358Sdim  return MCDisassembler::Success;
6251353358Sdim}
6252353358Sdim
6253353358Sdimstatic DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Val,
6254353358Sdim                                         uint64_t Address, const void *Decoder) {
6255353358Sdim  DecodeStatus S = MCDisassembler::Success;
6256353358Sdim
6257353358Sdim  unsigned DecodedVal = 64 - Val;
6258353358Sdim
6259353358Sdim  switch (Inst.getOpcode()) {
6260353358Sdim  case ARM::MVE_VCVTf16s16_fix:
6261353358Sdim  case ARM::MVE_VCVTs16f16_fix:
6262353358Sdim  case ARM::MVE_VCVTf16u16_fix:
6263353358Sdim  case ARM::MVE_VCVTu16f16_fix:
6264353358Sdim    if (DecodedVal > 16)
6265353358Sdim      return MCDisassembler::Fail;
6266353358Sdim    break;
6267353358Sdim  case ARM::MVE_VCVTf32s32_fix:
6268353358Sdim  case ARM::MVE_VCVTs32f32_fix:
6269353358Sdim  case ARM::MVE_VCVTf32u32_fix:
6270353358Sdim  case ARM::MVE_VCVTu32f32_fix:
6271353358Sdim    if (DecodedVal > 32)
6272353358Sdim      return MCDisassembler::Fail;
6273353358Sdim    break;
6274353358Sdim  }
6275353358Sdim
6276353358Sdim  Inst.addOperand(MCOperand::createImm(64 - Val));
6277353358Sdim
6278353358Sdim  return S;
6279353358Sdim}
6280353358Sdim
6281353358Sdimstatic unsigned FixedRegForVSTRVLDR_SYSREG(unsigned Opcode) {
6282353358Sdim  switch (Opcode) {
6283353358Sdim  case ARM::VSTR_P0_off:
6284353358Sdim  case ARM::VSTR_P0_pre:
6285353358Sdim  case ARM::VSTR_P0_post:
6286353358Sdim  case ARM::VLDR_P0_off:
6287353358Sdim  case ARM::VLDR_P0_pre:
6288353358Sdim  case ARM::VLDR_P0_post:
6289353358Sdim    return ARM::P0;
6290353358Sdim  default:
6291353358Sdim    return 0;
6292353358Sdim  }
6293353358Sdim}
6294353358Sdim
6295353358Sdimtemplate<bool Writeback>
6296353358Sdimstatic DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Val,
6297353358Sdim                                          uint64_t Address,
6298353358Sdim                                          const void *Decoder) {
6299353358Sdim  switch (Inst.getOpcode()) {
6300353358Sdim  case ARM::VSTR_FPSCR_pre:
6301353358Sdim  case ARM::VSTR_FPSCR_NZCVQC_pre:
6302353358Sdim  case ARM::VLDR_FPSCR_pre:
6303353358Sdim  case ARM::VLDR_FPSCR_NZCVQC_pre:
6304353358Sdim  case ARM::VSTR_FPSCR_off:
6305353358Sdim  case ARM::VSTR_FPSCR_NZCVQC_off:
6306353358Sdim  case ARM::VLDR_FPSCR_off:
6307353358Sdim  case ARM::VLDR_FPSCR_NZCVQC_off:
6308353358Sdim  case ARM::VSTR_FPSCR_post:
6309353358Sdim  case ARM::VSTR_FPSCR_NZCVQC_post:
6310353358Sdim  case ARM::VLDR_FPSCR_post:
6311353358Sdim  case ARM::VLDR_FPSCR_NZCVQC_post:
6312353358Sdim    const FeatureBitset &featureBits =
6313353358Sdim        ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
6314353358Sdim
6315353358Sdim    if (!featureBits[ARM::HasMVEIntegerOps] && !featureBits[ARM::FeatureVFP2])
6316353358Sdim      return MCDisassembler::Fail;
6317353358Sdim  }
6318353358Sdim
6319353358Sdim  DecodeStatus S = MCDisassembler::Success;
6320353358Sdim  if (unsigned Sysreg = FixedRegForVSTRVLDR_SYSREG(Inst.getOpcode()))
6321353358Sdim    Inst.addOperand(MCOperand::createReg(Sysreg));
6322353358Sdim  unsigned Rn = fieldFromInstruction(Val, 16, 4);
6323353358Sdim  unsigned addr = fieldFromInstruction(Val, 0, 7) |
6324353358Sdim                  (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
6325353358Sdim
6326353358Sdim  if (Writeback) {
6327353358Sdim    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
6328353358Sdim      return MCDisassembler::Fail;
6329353358Sdim  }
6330353358Sdim  if (!Check(S, DecodeT2AddrModeImm7s4(Inst, addr, Address, Decoder)))
6331353358Sdim    return MCDisassembler::Fail;
6332353358Sdim
6333353358Sdim  Inst.addOperand(MCOperand::createImm(ARMCC::AL));
6334353358Sdim  Inst.addOperand(MCOperand::createReg(0));
6335353358Sdim
6336353358Sdim  return S;
6337353358Sdim}
6338353358Sdim
6339353358Sdimstatic inline DecodeStatus DecodeMVE_MEM_pre(
6340353358Sdim  MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder,
6341353358Sdim  unsigned Rn, OperandDecoder RnDecoder, OperandDecoder AddrDecoder) {
6342353358Sdim  DecodeStatus S = MCDisassembler::Success;
6343353358Sdim
6344353358Sdim  unsigned Qd = fieldFromInstruction(Val, 13, 3);
6345353358Sdim  unsigned addr = fieldFromInstruction(Val, 0, 7) |
6346353358Sdim                  (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
6347353358Sdim
6348353358Sdim  if (!Check(S, RnDecoder(Inst, Rn, Address, Decoder)))
6349353358Sdim    return MCDisassembler::Fail;
6350353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6351353358Sdim    return MCDisassembler::Fail;
6352353358Sdim  if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder)))
6353353358Sdim    return MCDisassembler::Fail;
6354353358Sdim
6355353358Sdim  return S;
6356353358Sdim}
6357353358Sdim
6358353358Sdimtemplate <int shift>
6359353358Sdimstatic DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val,
6360353358Sdim                                        uint64_t Address, const void *Decoder) {
6361353358Sdim  return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
6362353358Sdim                           fieldFromInstruction(Val, 16, 3),
6363353358Sdim                           DecodetGPRRegisterClass,
6364353358Sdim                           DecodeTAddrModeImm7<shift>);
6365353358Sdim}
6366353358Sdim
6367353358Sdimtemplate <int shift>
6368353358Sdimstatic DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val,
6369353358Sdim                                        uint64_t Address, const void *Decoder) {
6370353358Sdim  return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
6371353358Sdim                           fieldFromInstruction(Val, 16, 4),
6372353358Sdim                           DecoderGPRRegisterClass,
6373353358Sdim                           DecodeT2AddrModeImm7<shift,1>);
6374353358Sdim}
6375353358Sdim
6376353358Sdimtemplate <int shift>
6377353358Sdimstatic DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val,
6378353358Sdim                                        uint64_t Address, const void *Decoder) {
6379353358Sdim  return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
6380353358Sdim                           fieldFromInstruction(Val, 17, 3),
6381353358Sdim                           DecodeMQPRRegisterClass,
6382353358Sdim                           DecodeMveAddrModeQ<shift>);
6383353358Sdim}
6384353358Sdim
6385353358Sdimtemplate<unsigned MinLog, unsigned MaxLog>
6386353358Sdimstatic DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
6387353358Sdim                                          uint64_t Address,
6388353358Sdim                                          const void *Decoder) {
6389353358Sdim  DecodeStatus S = MCDisassembler::Success;
6390353358Sdim
6391353358Sdim  if (Val < MinLog || Val > MaxLog)
6392353358Sdim    return MCDisassembler::Fail;
6393353358Sdim
6394353358Sdim  Inst.addOperand(MCOperand::createImm(1LL << Val));
6395353358Sdim  return S;
6396353358Sdim}
6397353358Sdim
6398353358Sdimtemplate <int shift>
6399353358Sdimstatic DecodeStatus DecodeExpandedImmOperand(MCInst &Inst, unsigned Val,
6400353358Sdim                                             uint64_t Address,
6401353358Sdim                                             const void *Decoder) {
6402353358Sdim    Val <<= shift;
6403353358Sdim
6404353358Sdim    Inst.addOperand(MCOperand::createImm(Val));
6405353358Sdim    return MCDisassembler::Success;
6406353358Sdim}
6407353358Sdim
6408353358Sdimtemplate<unsigned start>
6409353358Sdimstatic DecodeStatus DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val,
6410353358Sdim                                                    uint64_t Address,
6411353358Sdim                                                    const void *Decoder) {
6412353358Sdim  DecodeStatus S = MCDisassembler::Success;
6413353358Sdim
6414353358Sdim  Inst.addOperand(MCOperand::createImm(start + Val));
6415353358Sdim
6416353358Sdim  return S;
6417353358Sdim}
6418353358Sdim
6419353358Sdimstatic DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn,
6420353358Sdim                                         uint64_t Address, const void *Decoder) {
6421353358Sdim  DecodeStatus S = MCDisassembler::Success;
6422353358Sdim  unsigned Rt = fieldFromInstruction(Insn, 0, 4);
6423353358Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
6424353358Sdim  unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
6425353358Sdim                 fieldFromInstruction(Insn, 13, 3));
6426353358Sdim  unsigned index = fieldFromInstruction(Insn, 4, 1);
6427353358Sdim
6428353358Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
6429353358Sdim    return MCDisassembler::Fail;
6430353358Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
6431353358Sdim    return MCDisassembler::Fail;
6432353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6433353358Sdim    return MCDisassembler::Fail;
6434353358Sdim  if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
6435353358Sdim    return MCDisassembler::Fail;
6436353358Sdim  if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
6437353358Sdim    return MCDisassembler::Fail;
6438353358Sdim
6439353358Sdim  return S;
6440353358Sdim}
6441353358Sdim
6442353358Sdimstatic DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn,
6443353358Sdim                                         uint64_t Address, const void *Decoder) {
6444353358Sdim  DecodeStatus S = MCDisassembler::Success;
6445353358Sdim  unsigned Rt = fieldFromInstruction(Insn, 0, 4);
6446353358Sdim  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
6447353358Sdim  unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
6448353358Sdim                 fieldFromInstruction(Insn, 13, 3));
6449353358Sdim  unsigned index = fieldFromInstruction(Insn, 4, 1);
6450353358Sdim
6451353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6452353358Sdim    return MCDisassembler::Fail;
6453353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6454353358Sdim    return MCDisassembler::Fail;
6455353358Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
6456353358Sdim    return MCDisassembler::Fail;
6457353358Sdim  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
6458353358Sdim    return MCDisassembler::Fail;
6459353358Sdim  if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
6460353358Sdim    return MCDisassembler::Fail;
6461353358Sdim  if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
6462353358Sdim    return MCDisassembler::Fail;
6463353358Sdim
6464353358Sdim  return S;
6465353358Sdim}
6466353358Sdim
6467353358Sdimstatic DecodeStatus DecodeMVEOverlappingLongShift(
6468353358Sdim  MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) {
6469353358Sdim  DecodeStatus S = MCDisassembler::Success;
6470353358Sdim
6471353358Sdim  unsigned RdaLo = fieldFromInstruction(Insn, 17, 3) << 1;
6472353358Sdim  unsigned RdaHi = fieldFromInstruction(Insn, 9, 3) << 1;
6473353358Sdim  unsigned Rm = fieldFromInstruction(Insn, 12, 4);
6474353358Sdim
6475353358Sdim  if (RdaHi == 14) {
6476353358Sdim    // This value of RdaHi (really indicating pc, because RdaHi has to
6477353358Sdim    // be an odd-numbered register, so the low bit will be set by the
6478353358Sdim    // decode function below) indicates that we must decode as SQRSHR
6479353358Sdim    // or UQRSHL, which both have a single Rda register field with all
6480353358Sdim    // four bits.
6481353358Sdim    unsigned Rda = fieldFromInstruction(Insn, 16, 4);
6482353358Sdim
6483353358Sdim    switch (Inst.getOpcode()) {
6484353358Sdim      case ARM::MVE_ASRLr:
6485353358Sdim      case ARM::MVE_SQRSHRL:
6486353358Sdim        Inst.setOpcode(ARM::MVE_SQRSHR);
6487353358Sdim        break;
6488353358Sdim      case ARM::MVE_LSLLr:
6489353358Sdim      case ARM::MVE_UQRSHLL:
6490353358Sdim        Inst.setOpcode(ARM::MVE_UQRSHL);
6491353358Sdim        break;
6492353358Sdim      default:
6493353358Sdim        llvm_unreachable("Unexpected starting opcode!");
6494353358Sdim    }
6495353358Sdim
6496353358Sdim    // Rda as output parameter
6497353358Sdim    if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
6498353358Sdim      return MCDisassembler::Fail;
6499353358Sdim
6500353358Sdim    // Rda again as input parameter
6501353358Sdim    if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
6502353358Sdim      return MCDisassembler::Fail;
6503353358Sdim
6504353358Sdim    // Rm, the amount to shift by
6505353358Sdim    if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
6506353358Sdim      return MCDisassembler::Fail;
6507353358Sdim
6508360784Sdim    if (fieldFromInstruction (Insn, 6, 3) != 4)
6509360784Sdim      return MCDisassembler::SoftFail;
6510360784Sdim
6511360784Sdim    if (Rda == Rm)
6512360784Sdim      return MCDisassembler::SoftFail;
6513360784Sdim
6514353358Sdim    return S;
6515353358Sdim  }
6516353358Sdim
6517353358Sdim  // Otherwise, we decode as whichever opcode our caller has already
6518353358Sdim  // put into Inst. Those all look the same:
6519353358Sdim
6520353358Sdim  // RdaLo,RdaHi as output parameters
6521353358Sdim  if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
6522353358Sdim    return MCDisassembler::Fail;
6523353358Sdim  if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
6524353358Sdim    return MCDisassembler::Fail;
6525353358Sdim
6526353358Sdim  // RdaLo,RdaHi again as input parameters
6527353358Sdim  if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
6528353358Sdim    return MCDisassembler::Fail;
6529353358Sdim  if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
6530353358Sdim    return MCDisassembler::Fail;
6531353358Sdim
6532353358Sdim  // Rm, the amount to shift by
6533353358Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
6534353358Sdim    return MCDisassembler::Fail;
6535353358Sdim
6536360784Sdim  if (Inst.getOpcode() == ARM::MVE_SQRSHRL ||
6537360784Sdim      Inst.getOpcode() == ARM::MVE_UQRSHLL) {
6538360784Sdim    unsigned Saturate = fieldFromInstruction(Insn, 7, 1);
6539360784Sdim    // Saturate, the bit position for saturation
6540360784Sdim    Inst.addOperand(MCOperand::createImm(Saturate));
6541360784Sdim  }
6542360784Sdim
6543353358Sdim  return S;
6544353358Sdim}
6545353358Sdim
6546353358Sdimstatic DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn, uint64_t Address,
6547353358Sdim                                      const void *Decoder) {
6548353358Sdim  DecodeStatus S = MCDisassembler::Success;
6549353358Sdim  unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
6550353358Sdim                 fieldFromInstruction(Insn, 13, 3));
6551353358Sdim  unsigned Qm = ((fieldFromInstruction(Insn, 5, 1) << 3) |
6552353358Sdim                 fieldFromInstruction(Insn, 1, 3));
6553353358Sdim  unsigned imm6 = fieldFromInstruction(Insn, 16, 6);
6554353358Sdim
6555353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6556353358Sdim    return MCDisassembler::Fail;
6557353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
6558353358Sdim    return MCDisassembler::Fail;
6559353358Sdim  if (!Check(S, DecodeVCVTImmOperand(Inst, imm6, Address, Decoder)))
6560353358Sdim    return MCDisassembler::Fail;
6561353358Sdim
6562353358Sdim  return S;
6563353358Sdim}
6564353358Sdim
6565353358Sdimtemplate<bool scalar, OperandDecoder predicate_decoder>
6566353358Sdimstatic DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
6567353358Sdim                                  const void *Decoder) {
6568353358Sdim  DecodeStatus S = MCDisassembler::Success;
6569353358Sdim  Inst.addOperand(MCOperand::createReg(ARM::VPR));
6570353358Sdim  unsigned Qn = fieldFromInstruction(Insn, 17, 3);
6571353358Sdim  if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
6572353358Sdim    return MCDisassembler::Fail;
6573353358Sdim
6574353358Sdim  unsigned fc;
6575353358Sdim
6576353358Sdim  if (scalar) {
6577353358Sdim    fc = fieldFromInstruction(Insn, 12, 1) << 2 |
6578353358Sdim         fieldFromInstruction(Insn, 7, 1) |
6579353358Sdim         fieldFromInstruction(Insn, 5, 1) << 1;
6580353358Sdim    unsigned Rm = fieldFromInstruction(Insn, 0, 4);
6581353358Sdim    if (!Check(S, DecodeGPRwithZRRegisterClass(Inst, Rm, Address, Decoder)))
6582353358Sdim      return MCDisassembler::Fail;
6583353358Sdim  } else {
6584353358Sdim    fc = fieldFromInstruction(Insn, 12, 1) << 2 |
6585353358Sdim         fieldFromInstruction(Insn, 7, 1) |
6586353358Sdim         fieldFromInstruction(Insn, 0, 1) << 1;
6587353358Sdim    unsigned Qm = fieldFromInstruction(Insn, 5, 1) << 4 |
6588353358Sdim                  fieldFromInstruction(Insn, 1, 3);
6589353358Sdim    if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
6590353358Sdim      return MCDisassembler::Fail;
6591353358Sdim  }
6592353358Sdim
6593353358Sdim  if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder)))
6594353358Sdim    return MCDisassembler::Fail;
6595353358Sdim
6596353358Sdim  Inst.addOperand(MCOperand::createImm(ARMVCC::None));
6597353358Sdim  Inst.addOperand(MCOperand::createReg(0));
6598353358Sdim  Inst.addOperand(MCOperand::createImm(0));
6599353358Sdim
6600353358Sdim  return S;
6601353358Sdim}
6602353358Sdim
6603353358Sdimstatic DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
6604353358Sdim                                  const void *Decoder) {
6605353358Sdim  DecodeStatus S = MCDisassembler::Success;
6606353358Sdim  Inst.addOperand(MCOperand::createReg(ARM::VPR));
6607353358Sdim  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
6608353358Sdim  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
6609353358Sdim    return MCDisassembler::Fail;
6610353358Sdim  return S;
6611353358Sdim}
6612360784Sdim
6613360784Sdimstatic DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn, uint64_t Address,
6614360784Sdim                                   const void *Decoder) {
6615360784Sdim  DecodeStatus S = MCDisassembler::Success;
6616360784Sdim  Inst.addOperand(MCOperand::createReg(ARM::VPR));
6617360784Sdim  Inst.addOperand(MCOperand::createReg(ARM::VPR));
6618360784Sdim  return S;
6619360784Sdim}
6620360784Sdim
6621360784Sdimstatic DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
6622360784Sdim                                        uint64_t Address, const void *Decoder) {
6623360784Sdim  const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
6624360784Sdim  const unsigned Rn = fieldFromInstruction(Insn, 16, 4);
6625360784Sdim  const unsigned Imm12 = fieldFromInstruction(Insn, 26, 1) << 11 |
6626360784Sdim                         fieldFromInstruction(Insn, 12, 3) << 8 |
6627360784Sdim                         fieldFromInstruction(Insn, 0, 8);
6628360784Sdim  const unsigned TypeT3 = fieldFromInstruction(Insn, 25, 1);
6629360784Sdim  unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
6630360784Sdim  unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
6631360784Sdim  unsigned S = fieldFromInstruction(Insn, 20, 1);
6632360784Sdim  if (sign1 != sign2)
6633360784Sdim    return MCDisassembler::Fail;
6634360784Sdim
6635360784Sdim  // T3 does a zext of imm12, where T2 does a ThumbExpandImm (T2SOImm)
6636360784Sdim  DecodeStatus DS = MCDisassembler::Success;
6637360784Sdim  if ((!Check(DS,
6638360784Sdim              DecodeGPRspRegisterClass(Inst, Rd, Address, Decoder))) || // dst
6639360784Sdim      (!Check(DS, DecodeGPRspRegisterClass(Inst, Rn, Address, Decoder))))
6640360784Sdim    return MCDisassembler::Fail;
6641360784Sdim  if (TypeT3) {
6642360784Sdim    Inst.setOpcode(sign1 ? ARM::t2SUBspImm12 : ARM::t2ADDspImm12);
6643360784Sdim    S = 0;
6644360784Sdim    Inst.addOperand(MCOperand::createImm(Imm12)); // zext imm12
6645360784Sdim  } else {
6646360784Sdim    Inst.setOpcode(sign1 ? ARM::t2SUBspImm : ARM::t2ADDspImm);
6647360784Sdim    if (!Check(DS, DecodeT2SOImm(Inst, Imm12, Address, Decoder))) // imm12
6648360784Sdim      return MCDisassembler::Fail;
6649360784Sdim  }
6650360784Sdim  if (!Check(DS, DecodeCCOutOperand(Inst, S, Address, Decoder))) // cc_out
6651360784Sdim    return MCDisassembler::Fail;
6652360784Sdim
6653360784Sdim  Inst.addOperand(MCOperand::createReg(0)); // pred
6654360784Sdim
6655360784Sdim  return DS;
6656360784Sdim}
6657