1044eb2f6SDimitry Andric //===- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA ---------------===//
2b5efedafSRoman Divacky //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b5efedafSRoman Divacky //
7b5efedafSRoman Divacky //===----------------------------------------------------------------------===//
8b5efedafSRoman Divacky
9e6d15924SDimitry Andric #include "ARMBaseInstrInfo.h"
1030815c53SDimitry Andric #include "MCTargetDesc/ARMAddressingModes.h"
1130815c53SDimitry Andric #include "MCTargetDesc/ARMBaseInfo.h"
1271d5a254SDimitry Andric #include "MCTargetDesc/ARMMCTargetDesc.h"
13e6d15924SDimitry Andric #include "TargetInfo/ARMTargetInfo.h"
14044eb2f6SDimitry Andric #include "Utils/ARMBaseInfo.h"
154a16efa3SDimitry Andric #include "llvm/MC/MCContext.h"
16145449b1SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
1771d5a254SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
18b5efedafSRoman Divacky #include "llvm/MC/MCInst.h"
1963faed5bSDimitry Andric #include "llvm/MC/MCInstrDesc.h"
20e3b55780SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
2163faed5bSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
22c0981da4SDimitry Andric #include "llvm/MC/TargetRegistry.h"
2371d5a254SDimitry Andric #include "llvm/Support/Compiler.h"
24b5efedafSRoman Divacky #include "llvm/Support/ErrorHandling.h"
2571d5a254SDimitry Andric #include "llvm/Support/MathExtras.h"
267ab83427SDimitry Andric #include "llvm/Support/raw_ostream.h"
277fa27ce4SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
2871d5a254SDimitry Andric #include <algorithm>
2971d5a254SDimitry Andric #include <cassert>
3071d5a254SDimitry Andric #include <cstdint>
3158b69754SDimitry Andric #include <vector>
32b5efedafSRoman Divacky
33d7f7719eSRoman Divacky using namespace llvm;
34b5efedafSRoman Divacky
355ca98fd9SDimitry Andric #define DEBUG_TYPE "arm-disassembler"
365ca98fd9SDimitry Andric
37044eb2f6SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
3830815c53SDimitry Andric
3930815c53SDimitry Andric namespace {
4071d5a254SDimitry Andric
4158b69754SDimitry Andric // Handles the condition code status of instructions in IT blocks
4258b69754SDimitry Andric class ITStatus
4358b69754SDimitry Andric {
4458b69754SDimitry Andric public:
4558b69754SDimitry Andric // Returns the condition code for instruction in IT block
getITCC()4658b69754SDimitry Andric unsigned getITCC() {
4758b69754SDimitry Andric unsigned CC = ARMCC::AL;
4858b69754SDimitry Andric if (instrInITBlock())
4958b69754SDimitry Andric CC = ITStates.back();
5058b69754SDimitry Andric return CC;
5158b69754SDimitry Andric }
5258b69754SDimitry Andric
5358b69754SDimitry Andric // Advances the IT block state to the next T or E
advanceITState()5458b69754SDimitry Andric void advanceITState() {
5558b69754SDimitry Andric ITStates.pop_back();
5658b69754SDimitry Andric }
5758b69754SDimitry Andric
5858b69754SDimitry Andric // Returns true if the current instruction is in an IT block
instrInITBlock()5958b69754SDimitry Andric bool instrInITBlock() {
6058b69754SDimitry Andric return !ITStates.empty();
6158b69754SDimitry Andric }
6258b69754SDimitry Andric
6358b69754SDimitry Andric // Returns true if current instruction is the last instruction in an IT block
instrLastInITBlock()6458b69754SDimitry Andric bool instrLastInITBlock() {
6558b69754SDimitry Andric return ITStates.size() == 1;
6658b69754SDimitry Andric }
6758b69754SDimitry Andric
68e6d15924SDimitry Andric // Called when decoding an IT instruction. Sets the IT state for
69e6d15924SDimitry Andric // the following instructions that for the IT block. Firstcond
70e6d15924SDimitry Andric // corresponds to the field in the IT instruction encoding; Mask
71e6d15924SDimitry Andric // is in the MCOperand format in which 1 means 'else' and 0 'then'.
setITState(char Firstcond,char Mask)7258b69754SDimitry Andric void setITState(char Firstcond, char Mask) {
7358b69754SDimitry Andric // (3 - the number of trailing zeros) is the number of then / else.
747fa27ce4SDimitry Andric unsigned NumTZ = llvm::countr_zero<uint8_t>(Mask);
7558b69754SDimitry Andric unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
7658b69754SDimitry Andric assert(NumTZ <= 3 && "Invalid IT mask!");
7758b69754SDimitry Andric // push condition codes onto the stack the correct order for the pops
7858b69754SDimitry Andric for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
79e6d15924SDimitry Andric unsigned Else = (Mask >> Pos) & 1;
80e6d15924SDimitry Andric ITStates.push_back(CCBits ^ Else);
8158b69754SDimitry Andric }
8258b69754SDimitry Andric ITStates.push_back(CCBits);
8358b69754SDimitry Andric }
8458b69754SDimitry Andric
8558b69754SDimitry Andric private:
8658b69754SDimitry Andric std::vector<unsigned char> ITStates;
8758b69754SDimitry Andric };
8858b69754SDimitry Andric
89e6d15924SDimitry Andric class VPTStatus
90e6d15924SDimitry Andric {
91e6d15924SDimitry Andric public:
getVPTPred()92e6d15924SDimitry Andric unsigned getVPTPred() {
93e6d15924SDimitry Andric unsigned Pred = ARMVCC::None;
94e6d15924SDimitry Andric if (instrInVPTBlock())
95e6d15924SDimitry Andric Pred = VPTStates.back();
96e6d15924SDimitry Andric return Pred;
97e6d15924SDimitry Andric }
98e6d15924SDimitry Andric
advanceVPTState()99e6d15924SDimitry Andric void advanceVPTState() {
100e6d15924SDimitry Andric VPTStates.pop_back();
101e6d15924SDimitry Andric }
102e6d15924SDimitry Andric
instrInVPTBlock()103e6d15924SDimitry Andric bool instrInVPTBlock() {
104e6d15924SDimitry Andric return !VPTStates.empty();
105e6d15924SDimitry Andric }
106e6d15924SDimitry Andric
instrLastInVPTBlock()107e6d15924SDimitry Andric bool instrLastInVPTBlock() {
108e6d15924SDimitry Andric return VPTStates.size() == 1;
109e6d15924SDimitry Andric }
110e6d15924SDimitry Andric
setVPTState(char Mask)111e6d15924SDimitry Andric void setVPTState(char Mask) {
112e6d15924SDimitry Andric // (3 - the number of trailing zeros) is the number of then / else.
1137fa27ce4SDimitry Andric unsigned NumTZ = llvm::countr_zero<uint8_t>(Mask);
114e6d15924SDimitry Andric assert(NumTZ <= 3 && "Invalid VPT mask!");
115e6d15924SDimitry Andric // push predicates onto the stack the correct order for the pops
116e6d15924SDimitry Andric for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
117e6d15924SDimitry Andric bool T = ((Mask >> Pos) & 1) == 0;
118e6d15924SDimitry Andric if (T)
119e6d15924SDimitry Andric VPTStates.push_back(ARMVCC::Then);
120e6d15924SDimitry Andric else
121e6d15924SDimitry Andric VPTStates.push_back(ARMVCC::Else);
122e6d15924SDimitry Andric }
123e6d15924SDimitry Andric VPTStates.push_back(ARMVCC::Then);
124e6d15924SDimitry Andric }
125e6d15924SDimitry Andric
126e6d15924SDimitry Andric private:
127e6d15924SDimitry Andric SmallVector<unsigned char, 4> VPTStates;
128e6d15924SDimitry Andric };
129e6d15924SDimitry Andric
13067c32a98SDimitry Andric /// ARM disassembler for all ARM platforms.
13130815c53SDimitry Andric class ARMDisassembler : public MCDisassembler {
13230815c53SDimitry Andric public:
133e3b55780SDimitry Andric std::unique_ptr<const MCInstrInfo> MCII;
134e3b55780SDimitry Andric
ARMDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,const MCInstrInfo * MCII)135e3b55780SDimitry Andric ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
136e3b55780SDimitry Andric const MCInstrInfo *MCII)
137e3b55780SDimitry Andric : MCDisassembler(STI, Ctx), MCII(MCII) {
1387fa27ce4SDimitry Andric InstructionEndianness = STI.hasFeature(ARM::ModeBigEndianInstructions)
139b1c73532SDimitry Andric ? llvm::endianness::big
140b1c73532SDimitry Andric : llvm::endianness::little;
141b5efedafSRoman Divacky }
142b5efedafSRoman Divacky
14371d5a254SDimitry Andric ~ARMDisassembler() override = default;
144b5efedafSRoman Divacky
14567c32a98SDimitry Andric DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
14667c32a98SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
14767c32a98SDimitry Andric raw_ostream &CStream) const override;
14830815c53SDimitry Andric
14908e8dd7bSDimitry Andric uint64_t suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
15008e8dd7bSDimitry Andric uint64_t Address) const override;
15108e8dd7bSDimitry Andric
15230815c53SDimitry Andric private:
153e6d15924SDimitry Andric DecodeStatus getARMInstruction(MCInst &Instr, uint64_t &Size,
154e6d15924SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
155e6d15924SDimitry Andric raw_ostream &CStream) const;
156e6d15924SDimitry Andric
157e6d15924SDimitry Andric DecodeStatus getThumbInstruction(MCInst &Instr, uint64_t &Size,
158e6d15924SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
159e6d15924SDimitry Andric raw_ostream &CStream) const;
160e6d15924SDimitry Andric
16158b69754SDimitry Andric mutable ITStatus ITBlock;
162e6d15924SDimitry Andric mutable VPTStatus VPTBlock;
163044eb2f6SDimitry Andric
164e3b55780SDimitry Andric void AddThumb1SBit(MCInst &MI, bool InITBlock) const;
165e3b55780SDimitry Andric bool isVectorPredicable(const MCInst &MI) const;
16630815c53SDimitry Andric DecodeStatus AddThumbPredicate(MCInst&) const;
167e6d15924SDimitry Andric void UpdateThumbVFPPredicate(DecodeStatus &, MCInst&) const;
168e3b55780SDimitry Andric
169b1c73532SDimitry Andric llvm::endianness InstructionEndianness;
17030815c53SDimitry Andric };
17171d5a254SDimitry Andric
17271d5a254SDimitry Andric } // end anonymous namespace
173b5efedafSRoman Divacky
17430815c53SDimitry Andric // Forward declare these because the autogenerated code will reference them.
17530815c53SDimitry Andric // Definitions are further down.
17663faed5bSDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
177145449b1SDimitry Andric uint64_t Address,
178145449b1SDimitry Andric const MCDisassembler *Decoder);
179e6d15924SDimitry Andric static DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo,
180145449b1SDimitry Andric uint64_t Address,
181145449b1SDimitry Andric const MCDisassembler *Decoder);
182e6d15924SDimitry Andric static DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo,
183145449b1SDimitry Andric uint64_t Address,
184145449b1SDimitry Andric const MCDisassembler *Decoder);
185e6d15924SDimitry Andric static DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo,
186145449b1SDimitry Andric uint64_t Address,
187145449b1SDimitry Andric const MCDisassembler *Decoder);
188cfca06d7SDimitry Andric static DecodeStatus
189cfca06d7SDimitry Andric DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst &Inst, unsigned RegNo,
190145449b1SDimitry Andric uint64_t Address,
191145449b1SDimitry Andric const MCDisassembler *Decoder);
192f65dcba8SDimitry Andric static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
193f65dcba8SDimitry Andric uint64_t Address,
194145449b1SDimitry Andric const MCDisassembler *Decoder);
195f65dcba8SDimitry Andric static DecodeStatus DecodeGPRnospRegisterClass(MCInst &Inst, unsigned RegNo,
196f65dcba8SDimitry Andric uint64_t Address,
197145449b1SDimitry Andric const MCDisassembler *Decoder);
198145449b1SDimitry Andric static DecodeStatus
199145449b1SDimitry Andric DecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
200145449b1SDimitry Andric const MCDisassembler *Decoder);
201145449b1SDimitry Andric static DecodeStatus DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo,
202145449b1SDimitry Andric uint64_t Address,
203145449b1SDimitry Andric const MCDisassembler *Decoder);
204145449b1SDimitry Andric static DecodeStatus
205145449b1SDimitry Andric DecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
206145449b1SDimitry Andric const MCDisassembler *Decoder);
20763faed5bSDimitry Andric static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
208145449b1SDimitry Andric uint64_t Address,
209145449b1SDimitry Andric const MCDisassembler *Decoder);
21063faed5bSDimitry Andric static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
211145449b1SDimitry Andric uint64_t Address,
212145449b1SDimitry Andric const MCDisassembler *Decoder);
21363faed5bSDimitry Andric static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
214145449b1SDimitry Andric uint64_t Address,
215145449b1SDimitry Andric const MCDisassembler *Decoder);
216f8af5cf6SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
217145449b1SDimitry Andric uint64_t Address,
218145449b1SDimitry Andric const MCDisassembler *Decoder);
219145449b1SDimitry Andric static DecodeStatus
220145449b1SDimitry Andric DecodeGPRPairnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
221145449b1SDimitry Andric const MCDisassembler *Decoder);
222706b4fc4SDimitry Andric static DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
223706b4fc4SDimitry Andric uint64_t Address,
224145449b1SDimitry Andric const MCDisassembler *Decoder);
225eb11fae6SDimitry Andric static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
226b5efedafSRoman Divacky uint64_t Address,
227145449b1SDimitry Andric const MCDisassembler *Decoder);
228145449b1SDimitry Andric static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
229145449b1SDimitry Andric uint64_t Address,
230145449b1SDimitry Andric const MCDisassembler *Decoder);
231145449b1SDimitry Andric static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
232145449b1SDimitry Andric uint64_t Address,
233145449b1SDimitry Andric const MCDisassembler *Decoder);
234145449b1SDimitry Andric static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
235145449b1SDimitry Andric uint64_t Address,
236145449b1SDimitry Andric const MCDisassembler *Decoder);
237145449b1SDimitry Andric static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
238145449b1SDimitry Andric uint64_t Address,
239145449b1SDimitry Andric const MCDisassembler *Decoder);
240145449b1SDimitry Andric static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
241145449b1SDimitry Andric uint64_t Address,
242145449b1SDimitry Andric const MCDisassembler *Decoder);
24363faed5bSDimitry Andric static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
244145449b1SDimitry Andric uint64_t Address,
245145449b1SDimitry Andric const MCDisassembler *Decoder);
246e6d15924SDimitry Andric static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
247145449b1SDimitry Andric uint64_t Address,
248145449b1SDimitry Andric const MCDisassembler *Decoder);
249c0981da4SDimitry Andric static DecodeStatus DecodeMQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
250c0981da4SDimitry Andric uint64_t Address,
251145449b1SDimitry Andric const MCDisassembler *Decoder);
252c0981da4SDimitry Andric static DecodeStatus DecodeMQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
253c0981da4SDimitry Andric uint64_t Address,
254145449b1SDimitry Andric const MCDisassembler *Decoder);
25563faed5bSDimitry Andric static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
256145449b1SDimitry Andric uint64_t Address,
257145449b1SDimitry Andric const MCDisassembler *Decoder);
258145449b1SDimitry Andric static DecodeStatus
259145449b1SDimitry Andric DecodeDPairSpacedRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
260145449b1SDimitry Andric const MCDisassembler *Decoder);
26163faed5bSDimitry Andric
26263faed5bSDimitry Andric static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
263145449b1SDimitry Andric uint64_t Address,
264145449b1SDimitry Andric const MCDisassembler *Decoder);
26563faed5bSDimitry Andric static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
266145449b1SDimitry Andric uint64_t Address,
267145449b1SDimitry Andric const MCDisassembler *Decoder);
26863faed5bSDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
269145449b1SDimitry Andric uint64_t Address,
270145449b1SDimitry Andric const MCDisassembler *Decoder);
27163faed5bSDimitry Andric static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
272145449b1SDimitry Andric uint64_t Address,
273145449b1SDimitry Andric const MCDisassembler *Decoder);
27463faed5bSDimitry Andric static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
275145449b1SDimitry Andric uint64_t Address,
276145449b1SDimitry Andric const MCDisassembler *Decoder);
277b5efedafSRoman Divacky
27863faed5bSDimitry Andric static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
279b5efedafSRoman Divacky uint64_t Address,
280145449b1SDimitry Andric const MCDisassembler *Decoder);
281145449b1SDimitry Andric static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
282145449b1SDimitry Andric uint64_t Address,
283145449b1SDimitry Andric const MCDisassembler *Decoder);
284145449b1SDimitry Andric static DecodeStatus
285145449b1SDimitry Andric DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
286145449b1SDimitry Andric const MCDisassembler *Decoder);
28763faed5bSDimitry Andric static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
288145449b1SDimitry Andric uint64_t Address,
289145449b1SDimitry Andric const MCDisassembler *Decoder);
29063faed5bSDimitry Andric static DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
291145449b1SDimitry Andric uint64_t Address,
292145449b1SDimitry Andric const MCDisassembler *Decoder);
293145449b1SDimitry Andric static DecodeStatus DecodeTSBInstruction(MCInst &Inst, unsigned Insn,
294145449b1SDimitry Andric uint64_t Address,
295145449b1SDimitry Andric const MCDisassembler *Decoder);
29663faed5bSDimitry Andric static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
297145449b1SDimitry Andric uint64_t Address,
298145449b1SDimitry Andric const MCDisassembler *Decoder);
29963faed5bSDimitry Andric static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
300145449b1SDimitry Andric uint64_t Address,
301145449b1SDimitry Andric const MCDisassembler *Decoder);
3029f4a1da9SRoman Divacky
303145449b1SDimitry Andric static DecodeStatus
304145449b1SDimitry Andric DecodeMemMultipleWritebackInstruction(MCInst &Inst, unsigned Insn,
30530815c53SDimitry Andric uint64_t Adddress,
306145449b1SDimitry Andric const MCDisassembler *Decoder);
30763faed5bSDimitry Andric static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
308145449b1SDimitry Andric uint64_t Address,
309145449b1SDimitry Andric const MCDisassembler *Decoder);
31063faed5bSDimitry Andric static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
311145449b1SDimitry Andric uint64_t Address,
312145449b1SDimitry Andric const MCDisassembler *Decoder);
31363faed5bSDimitry Andric static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
314145449b1SDimitry Andric uint64_t Address,
315145449b1SDimitry Andric const MCDisassembler *Decoder);
31601095a5dSDimitry Andric static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
317145449b1SDimitry Andric uint64_t Address,
318145449b1SDimitry Andric const MCDisassembler *Decoder);
31963faed5bSDimitry Andric static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
320145449b1SDimitry Andric uint64_t Address,
321145449b1SDimitry Andric const MCDisassembler *Decoder);
3225a5ac124SDimitry Andric static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
323145449b1SDimitry Andric uint64_t Address,
324145449b1SDimitry Andric const MCDisassembler *Decoder);
3255a5ac124SDimitry Andric static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
326145449b1SDimitry Andric uint64_t Address,
327145449b1SDimitry Andric const MCDisassembler *Decoder);
32863faed5bSDimitry Andric static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
329145449b1SDimitry Andric uint64_t Address,
330145449b1SDimitry Andric const MCDisassembler *Decoder);
331f65dcba8SDimitry Andric static DecodeStatus DecodeT2HintSpaceInstruction(MCInst &Inst, unsigned Insn,
332f65dcba8SDimitry Andric uint64_t Address,
333145449b1SDimitry Andric const MCDisassembler *Decoder);
33463faed5bSDimitry Andric static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
335145449b1SDimitry Andric uint64_t Address,
336145449b1SDimitry Andric const MCDisassembler *Decoder);
33763faed5bSDimitry Andric static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
338145449b1SDimitry Andric uint64_t Address,
339145449b1SDimitry Andric const MCDisassembler *Decoder);
34001095a5dSDimitry Andric static DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
341145449b1SDimitry Andric uint64_t Address,
342145449b1SDimitry Andric const MCDisassembler *Decoder);
34363faed5bSDimitry Andric static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
344145449b1SDimitry Andric uint64_t Address,
345145449b1SDimitry Andric const MCDisassembler *Decoder);
34663faed5bSDimitry Andric static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
347145449b1SDimitry Andric uint64_t Address,
348145449b1SDimitry Andric const MCDisassembler *Decoder);
34963faed5bSDimitry Andric static DecodeStatus DecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
350145449b1SDimitry Andric uint64_t Address,
351145449b1SDimitry Andric const MCDisassembler *Decoder);
35263faed5bSDimitry Andric static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
353145449b1SDimitry Andric uint64_t Address,
354145449b1SDimitry Andric const MCDisassembler *Decoder);
355f8af5cf6SDimitry Andric static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val,
356145449b1SDimitry Andric uint64_t Address,
357145449b1SDimitry Andric const MCDisassembler *Decoder);
358f8af5cf6SDimitry Andric static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val,
359145449b1SDimitry Andric uint64_t Address,
360145449b1SDimitry Andric const MCDisassembler *Decoder);
361f8af5cf6SDimitry Andric static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val,
362145449b1SDimitry Andric uint64_t Address,
363145449b1SDimitry Andric const MCDisassembler *Decoder);
364f8af5cf6SDimitry Andric static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val,
365145449b1SDimitry Andric uint64_t Address,
366145449b1SDimitry Andric const MCDisassembler *Decoder);
36763faed5bSDimitry Andric static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
368145449b1SDimitry Andric uint64_t Address,
369145449b1SDimitry Andric const MCDisassembler *Decoder);
37063faed5bSDimitry Andric static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
371145449b1SDimitry Andric uint64_t Address,
372145449b1SDimitry Andric const MCDisassembler *Decoder);
37363faed5bSDimitry Andric static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
374145449b1SDimitry Andric uint64_t Address,
375145449b1SDimitry Andric const MCDisassembler *Decoder);
37663faed5bSDimitry Andric static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
377145449b1SDimitry Andric uint64_t Address,
378145449b1SDimitry Andric const MCDisassembler *Decoder);
37963faed5bSDimitry Andric static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
380145449b1SDimitry Andric uint64_t Address,
381145449b1SDimitry Andric const MCDisassembler *Decoder);
38263faed5bSDimitry Andric static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
383145449b1SDimitry Andric uint64_t Address,
384145449b1SDimitry Andric const MCDisassembler *Decoder);
3851d5ae102SDimitry Andric static DecodeStatus DecodeVMOVModImmInstruction(MCInst &Inst, unsigned Val,
386145449b1SDimitry Andric uint64_t Address,
387145449b1SDimitry Andric const MCDisassembler *Decoder);
388e6d15924SDimitry Andric static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst, unsigned Val,
389145449b1SDimitry Andric uint64_t Address,
390145449b1SDimitry Andric const MCDisassembler *Decoder);
391e6d15924SDimitry Andric static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
392145449b1SDimitry Andric uint64_t Address,
393145449b1SDimitry Andric const MCDisassembler *Decoder);
39463faed5bSDimitry Andric static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
395145449b1SDimitry Andric uint64_t Address,
396145449b1SDimitry Andric const MCDisassembler *Decoder);
39763faed5bSDimitry Andric static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
398145449b1SDimitry Andric uint64_t Address,
399145449b1SDimitry Andric const MCDisassembler *Decoder);
40063faed5bSDimitry Andric static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
401145449b1SDimitry Andric uint64_t Address,
402145449b1SDimitry Andric const MCDisassembler *Decoder);
40363faed5bSDimitry Andric static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
404145449b1SDimitry Andric uint64_t Address,
405145449b1SDimitry Andric const MCDisassembler *Decoder);
40663faed5bSDimitry Andric static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
407145449b1SDimitry Andric uint64_t Address,
408145449b1SDimitry Andric const MCDisassembler *Decoder);
40963faed5bSDimitry Andric static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
410145449b1SDimitry Andric uint64_t Address,
411145449b1SDimitry Andric const MCDisassembler *Decoder);
41263faed5bSDimitry Andric static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
413145449b1SDimitry Andric uint64_t Address,
414145449b1SDimitry Andric const MCDisassembler *Decoder);
415e6d15924SDimitry Andric static DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn,
416145449b1SDimitry Andric uint64_t Address,
417145449b1SDimitry Andric const MCDisassembler *Decoder);
418e6d15924SDimitry Andric template <int shift>
419e6d15924SDimitry Andric static DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn,
420044eb2f6SDimitry Andric uint64_t Address,
421145449b1SDimitry Andric const MCDisassembler *Decoder);
422145449b1SDimitry Andric static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
423145449b1SDimitry Andric uint64_t Address,
424145449b1SDimitry Andric const MCDisassembler *Decoder);
425145449b1SDimitry Andric static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
426145449b1SDimitry Andric uint64_t Address,
427145449b1SDimitry Andric const MCDisassembler *Decoder);
428145449b1SDimitry Andric static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
429145449b1SDimitry Andric uint64_t Address,
430145449b1SDimitry Andric const MCDisassembler *Decoder);
431145449b1SDimitry Andric static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn, uint64_t Address,
432145449b1SDimitry Andric const MCDisassembler *Decoder);
433145449b1SDimitry Andric static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Insn,
434145449b1SDimitry Andric uint64_t Address,
435145449b1SDimitry Andric const MCDisassembler *Decoder);
436145449b1SDimitry Andric static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
437145449b1SDimitry Andric uint64_t Address,
438145449b1SDimitry Andric const MCDisassembler *Decoder);
439145449b1SDimitry Andric static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
440145449b1SDimitry Andric uint64_t Address,
441145449b1SDimitry Andric const MCDisassembler *Decoder);
442145449b1SDimitry Andric static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
443145449b1SDimitry Andric uint64_t Address,
444145449b1SDimitry Andric const MCDisassembler *Decoder);
445145449b1SDimitry Andric static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
446145449b1SDimitry Andric uint64_t Address,
447145449b1SDimitry Andric const MCDisassembler *Decoder);
448145449b1SDimitry Andric static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
449145449b1SDimitry Andric uint64_t Address,
450145449b1SDimitry Andric const MCDisassembler *Decoder);
451145449b1SDimitry Andric static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
452145449b1SDimitry Andric uint64_t Address,
453145449b1SDimitry Andric const MCDisassembler *Decoder);
454145449b1SDimitry Andric static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
455145449b1SDimitry Andric const MCDisassembler *Decoder);
456145449b1SDimitry Andric static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
457145449b1SDimitry Andric const MCDisassembler *Decoder);
458145449b1SDimitry Andric static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
459145449b1SDimitry Andric const MCDisassembler *Decoder);
460145449b1SDimitry Andric static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
461145449b1SDimitry Andric const MCDisassembler *Decoder);
462145449b1SDimitry Andric static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
463145449b1SDimitry Andric const MCDisassembler *Decoder);
464145449b1SDimitry Andric static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
465145449b1SDimitry Andric const MCDisassembler *Decoder);
466145449b1SDimitry Andric static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
467145449b1SDimitry Andric const MCDisassembler *Decoder);
468145449b1SDimitry Andric static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
469145449b1SDimitry Andric const MCDisassembler *Decoder);
470145449b1SDimitry Andric static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, uint64_t Address,
471145449b1SDimitry Andric const MCDisassembler *Decoder);
472145449b1SDimitry Andric static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, uint64_t Address,
473145449b1SDimitry Andric const MCDisassembler *Decoder);
474145449b1SDimitry Andric static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, uint64_t Address,
475145449b1SDimitry Andric const MCDisassembler *Decoder);
476145449b1SDimitry Andric static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, uint64_t Address,
477145449b1SDimitry Andric const MCDisassembler *Decoder);
478145449b1SDimitry Andric static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, uint64_t Address,
479145449b1SDimitry Andric const MCDisassembler *Decoder);
480145449b1SDimitry Andric static DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Insn,
481145449b1SDimitry Andric uint64_t Address,
482145449b1SDimitry Andric const MCDisassembler *Decoder);
483145449b1SDimitry Andric static DecodeStatus
484145449b1SDimitry Andric DecodeNEONComplexLane64Instruction(MCInst &Inst, unsigned Val, uint64_t Address,
485145449b1SDimitry Andric const MCDisassembler *Decoder);
486b5efedafSRoman Divacky
48763faed5bSDimitry Andric static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
488145449b1SDimitry Andric uint64_t Address,
489145449b1SDimitry Andric const MCDisassembler *Decoder);
49063faed5bSDimitry Andric static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
491145449b1SDimitry Andric uint64_t Address,
492145449b1SDimitry Andric const MCDisassembler *Decoder);
49363faed5bSDimitry Andric static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
494145449b1SDimitry Andric uint64_t Address,
495145449b1SDimitry Andric const MCDisassembler *Decoder);
49663faed5bSDimitry Andric static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
497145449b1SDimitry Andric uint64_t Address,
498145449b1SDimitry Andric const MCDisassembler *Decoder);
49963faed5bSDimitry Andric static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
500145449b1SDimitry Andric uint64_t Address,
501145449b1SDimitry Andric const MCDisassembler *Decoder);
50263faed5bSDimitry Andric static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
503145449b1SDimitry Andric uint64_t Address,
504145449b1SDimitry Andric const MCDisassembler *Decoder);
50563faed5bSDimitry Andric static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
506145449b1SDimitry Andric uint64_t Address,
507145449b1SDimitry Andric const MCDisassembler *Decoder);
50863faed5bSDimitry Andric static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
509145449b1SDimitry Andric uint64_t Address,
510145449b1SDimitry Andric const MCDisassembler *Decoder);
51163faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
512145449b1SDimitry Andric uint64_t Address,
513145449b1SDimitry Andric const MCDisassembler *Decoder);
51463faed5bSDimitry Andric static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
515145449b1SDimitry Andric uint64_t Address,
516145449b1SDimitry Andric const MCDisassembler *Decoder);
517f8af5cf6SDimitry Andric static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
518145449b1SDimitry Andric uint64_t Address,
519145449b1SDimitry Andric const MCDisassembler *Decoder);
520f8af5cf6SDimitry Andric static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
521145449b1SDimitry Andric uint64_t Address,
522145449b1SDimitry Andric const MCDisassembler *Decoder);
523145449b1SDimitry Andric static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, uint64_t Address,
524145449b1SDimitry Andric const MCDisassembler *Decoder);
525f8af5cf6SDimitry Andric static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
526145449b1SDimitry Andric uint64_t Address,
527145449b1SDimitry Andric const MCDisassembler *Decoder);
528145449b1SDimitry Andric static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, uint64_t Address,
529145449b1SDimitry Andric const MCDisassembler *Decoder);
530145449b1SDimitry Andric static DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val, uint64_t Address,
531145449b1SDimitry Andric const MCDisassembler *Decoder);
53263faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
533145449b1SDimitry Andric uint64_t Address,
534145449b1SDimitry Andric const MCDisassembler *Decoder);
535e6d15924SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val,
536e6d15924SDimitry Andric uint64_t Address,
537145449b1SDimitry Andric const MCDisassembler *Decoder);
53863faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst, unsigned Val,
539145449b1SDimitry Andric uint64_t Address,
540145449b1SDimitry Andric const MCDisassembler *Decoder);
541145449b1SDimitry Andric static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, uint64_t Address,
542145449b1SDimitry Andric const MCDisassembler *Decoder);
543e6d15924SDimitry Andric template <int shift>
544145449b1SDimitry Andric static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, uint64_t Address,
545145449b1SDimitry Andric const MCDisassembler *Decoder);
54663faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
547145449b1SDimitry Andric uint64_t Address,
548145449b1SDimitry Andric const MCDisassembler *Decoder);
549e6d15924SDimitry Andric template <int shift>
550e6d15924SDimitry Andric static DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val,
551145449b1SDimitry Andric uint64_t Address,
552145449b1SDimitry Andric const MCDisassembler *Decoder);
553e6d15924SDimitry Andric template <int shift, int WriteBack>
554e6d15924SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val,
555145449b1SDimitry Andric uint64_t Address,
556145449b1SDimitry Andric const MCDisassembler *Decoder);
55763faed5bSDimitry Andric static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
558145449b1SDimitry Andric uint64_t Address,
559145449b1SDimitry Andric const MCDisassembler *Decoder);
56063faed5bSDimitry Andric static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
561145449b1SDimitry Andric uint64_t Address,
562145449b1SDimitry Andric const MCDisassembler *Decoder);
56363faed5bSDimitry Andric static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
564145449b1SDimitry Andric uint64_t Address,
565145449b1SDimitry Andric const MCDisassembler *Decoder);
566f8af5cf6SDimitry Andric static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
567145449b1SDimitry Andric uint64_t Address,
568145449b1SDimitry Andric const MCDisassembler *Decoder);
56963faed5bSDimitry Andric static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
570145449b1SDimitry Andric uint64_t Address,
571145449b1SDimitry Andric const MCDisassembler *Decoder);
57263faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
573145449b1SDimitry Andric uint64_t Address,
574145449b1SDimitry Andric const MCDisassembler *Decoder);
57563faed5bSDimitry Andric static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
576145449b1SDimitry Andric uint64_t Address,
577145449b1SDimitry Andric const MCDisassembler *Decoder);
57863faed5bSDimitry Andric static DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
579145449b1SDimitry Andric uint64_t Address,
580145449b1SDimitry Andric const MCDisassembler *Decoder);
581145449b1SDimitry Andric static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, uint64_t Address,
582145449b1SDimitry Andric const MCDisassembler *Decoder);
58363faed5bSDimitry Andric static DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
584145449b1SDimitry Andric uint64_t Address,
585145449b1SDimitry Andric const MCDisassembler *Decoder);
58663faed5bSDimitry Andric static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
587145449b1SDimitry Andric uint64_t Address,
588145449b1SDimitry Andric const MCDisassembler *Decoder);
589145449b1SDimitry Andric static DecodeStatus DecodeIT(MCInst &Inst, unsigned Val, uint64_t Address,
590145449b1SDimitry Andric const MCDisassembler *Decoder);
59163faed5bSDimitry Andric static DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
592145449b1SDimitry Andric uint64_t Address,
593145449b1SDimitry Andric const MCDisassembler *Decoder);
59463faed5bSDimitry Andric static DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
595145449b1SDimitry Andric uint64_t Address,
596145449b1SDimitry Andric const MCDisassembler *Decoder);
597145449b1SDimitry Andric static DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val, uint64_t Address,
598145449b1SDimitry Andric const MCDisassembler *Decoder);
59963faed5bSDimitry Andric static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
600145449b1SDimitry Andric uint64_t Address,
601145449b1SDimitry Andric const MCDisassembler *Decoder);
60263faed5bSDimitry Andric static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
603145449b1SDimitry Andric uint64_t Address,
604145449b1SDimitry Andric const MCDisassembler *Decoder);
605b5efedafSRoman Divacky
606145449b1SDimitry Andric static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, uint64_t Address,
607145449b1SDimitry Andric const MCDisassembler *Decoder);
60871d5a254SDimitry Andric static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
609145449b1SDimitry Andric uint64_t Address,
610145449b1SDimitry Andric const MCDisassembler *Decoder);
611044eb2f6SDimitry Andric static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
612145449b1SDimitry Andric uint64_t Address,
613145449b1SDimitry Andric const MCDisassembler *Decoder);
61471d5a254SDimitry Andric
615e6d15924SDimitry Andric template <bool isSigned, bool isNeg, bool zeroPermitted, int size>
616e6d15924SDimitry Andric static DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned val,
617145449b1SDimitry Andric uint64_t Address,
618145449b1SDimitry Andric const MCDisassembler *Decoder);
619e6d15924SDimitry Andric static DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned val,
620e6d15924SDimitry Andric uint64_t Address,
621145449b1SDimitry Andric const MCDisassembler *Decoder);
622e6d15924SDimitry Andric static DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val,
623e6d15924SDimitry Andric uint64_t Address,
624145449b1SDimitry Andric const MCDisassembler *Decoder);
625e6d15924SDimitry Andric static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address,
626145449b1SDimitry Andric const MCDisassembler *Decoder);
627e6d15924SDimitry Andric static DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val,
628e6d15924SDimitry Andric uint64_t Address,
629145449b1SDimitry Andric const MCDisassembler *Decoder);
630e6d15924SDimitry Andric static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
631145449b1SDimitry Andric const MCDisassembler *Decoder);
632e6d15924SDimitry Andric static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
633145449b1SDimitry Andric uint64_t Address,
634145449b1SDimitry Andric const MCDisassembler *Decoder);
635e6d15924SDimitry Andric static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned Val,
636e6d15924SDimitry Andric uint64_t Address,
637145449b1SDimitry Andric const MCDisassembler *Decoder);
638e3b55780SDimitry Andric static DecodeStatus DecodeVpredNOperand(MCInst &Inst, unsigned Val,
639e3b55780SDimitry Andric uint64_t Address,
640e3b55780SDimitry Andric const MCDisassembler *Decoder);
641145449b1SDimitry Andric static DecodeStatus
642145449b1SDimitry Andric DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
643145449b1SDimitry Andric const MCDisassembler *Decoder);
644145449b1SDimitry Andric static DecodeStatus
645145449b1SDimitry Andric DecodeRestrictedSPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
646145449b1SDimitry Andric const MCDisassembler *Decoder);
647145449b1SDimitry Andric static DecodeStatus
648145449b1SDimitry Andric DecodeRestrictedUPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
649145449b1SDimitry Andric const MCDisassembler *Decoder);
650145449b1SDimitry Andric static DecodeStatus
651145449b1SDimitry Andric DecodeRestrictedFPPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
652145449b1SDimitry Andric const MCDisassembler *Decoder);
653e6d15924SDimitry Andric template <bool Writeback>
654e6d15924SDimitry Andric static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Insn,
655e6d15924SDimitry Andric uint64_t Address,
656145449b1SDimitry Andric const MCDisassembler *Decoder);
657e6d15924SDimitry Andric template <int shift>
658e6d15924SDimitry Andric static DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val,
659145449b1SDimitry Andric uint64_t Address,
660145449b1SDimitry Andric const MCDisassembler *Decoder);
661e6d15924SDimitry Andric template <int shift>
662e6d15924SDimitry Andric static DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val,
663145449b1SDimitry Andric uint64_t Address,
664145449b1SDimitry Andric const MCDisassembler *Decoder);
665e6d15924SDimitry Andric template <int shift>
666e6d15924SDimitry Andric static DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val,
667145449b1SDimitry Andric uint64_t Address,
668145449b1SDimitry Andric const MCDisassembler *Decoder);
669e6d15924SDimitry Andric template <unsigned MinLog, unsigned MaxLog>
670e6d15924SDimitry Andric static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
671e6d15924SDimitry Andric uint64_t Address,
672145449b1SDimitry Andric const MCDisassembler *Decoder);
673e6d15924SDimitry Andric template <unsigned start>
674145449b1SDimitry Andric static DecodeStatus
675145449b1SDimitry Andric DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val, uint64_t Address,
676145449b1SDimitry Andric const MCDisassembler *Decoder);
677e6d15924SDimitry Andric static DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn,
678e6d15924SDimitry Andric uint64_t Address,
679145449b1SDimitry Andric const MCDisassembler *Decoder);
680e6d15924SDimitry Andric static DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn,
681e6d15924SDimitry Andric uint64_t Address,
682145449b1SDimitry Andric const MCDisassembler *Decoder);
683e6d15924SDimitry Andric static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
684e6d15924SDimitry Andric uint64_t Address,
685145449b1SDimitry Andric const MCDisassembler *Decoder);
686145449b1SDimitry Andric typedef DecodeStatus OperandDecoder(MCInst &Inst, unsigned Val,
687145449b1SDimitry Andric uint64_t Address,
688145449b1SDimitry Andric const MCDisassembler *Decoder);
689145449b1SDimitry Andric template <bool scalar, OperandDecoder predicate_decoder>
690145449b1SDimitry Andric static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
691145449b1SDimitry Andric const MCDisassembler *Decoder);
692145449b1SDimitry Andric static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
693145449b1SDimitry Andric const MCDisassembler *Decoder);
694145449b1SDimitry Andric static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
695145449b1SDimitry Andric uint64_t Address,
696145449b1SDimitry Andric const MCDisassembler *Decoder);
697145449b1SDimitry Andric static DecodeStatus
698145449b1SDimitry Andric DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn, uint64_t Address,
699145449b1SDimitry Andric const MCDisassembler *Decoder);
700706b4fc4SDimitry Andric static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
701145449b1SDimitry Andric uint64_t Address,
702145449b1SDimitry Andric const MCDisassembler *Decoder);
703ac9a064cSDimitry Andric static DecodeStatus DecodeLazyLoadStoreMul(MCInst &Inst, unsigned Insn,
704ac9a064cSDimitry Andric uint64_t Address,
705ac9a064cSDimitry Andric const MCDisassembler *Decoder);
706706b4fc4SDimitry Andric
70730815c53SDimitry Andric #include "ARMGenDisassemblerTables.inc"
70830815c53SDimitry Andric
createARMDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)7095ca98fd9SDimitry Andric static MCDisassembler *createARMDisassembler(const Target &T,
7105ca98fd9SDimitry Andric const MCSubtargetInfo &STI,
7115ca98fd9SDimitry Andric MCContext &Ctx) {
712e3b55780SDimitry Andric return new ARMDisassembler(STI, Ctx, T.createMCInstrInfo());
713b5efedafSRoman Divacky }
714b5efedafSRoman Divacky
71567c32a98SDimitry Andric // Post-decoding checks
checkDecodedInstruction(MCInst & MI,uint64_t & Size,uint64_t Address,raw_ostream & CS,uint32_t Insn,DecodeStatus Result)71667c32a98SDimitry Andric static DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,
717706b4fc4SDimitry Andric uint64_t Address, raw_ostream &CS,
71867c32a98SDimitry Andric uint32_t Insn,
71971d5a254SDimitry Andric DecodeStatus Result) {
72067c32a98SDimitry Andric switch (MI.getOpcode()) {
72167c32a98SDimitry Andric case ARM::HVC: {
72267c32a98SDimitry Andric // HVC is undefined if condition = 0xf otherwise upredictable
72367c32a98SDimitry Andric // if condition != 0xe
72467c32a98SDimitry Andric uint32_t Cond = (Insn >> 28) & 0xF;
72567c32a98SDimitry Andric if (Cond == 0xF)
72667c32a98SDimitry Andric return MCDisassembler::Fail;
72767c32a98SDimitry Andric if (Cond != 0xE)
72867c32a98SDimitry Andric return MCDisassembler::SoftFail;
72967c32a98SDimitry Andric return Result;
73067c32a98SDimitry Andric }
731e6d15924SDimitry Andric case ARM::t2ADDri:
732e6d15924SDimitry Andric case ARM::t2ADDri12:
733e6d15924SDimitry Andric case ARM::t2ADDrr:
734e6d15924SDimitry Andric case ARM::t2ADDrs:
735e6d15924SDimitry Andric case ARM::t2SUBri:
736e6d15924SDimitry Andric case ARM::t2SUBri12:
737e6d15924SDimitry Andric case ARM::t2SUBrr:
738e6d15924SDimitry Andric case ARM::t2SUBrs:
739e6d15924SDimitry Andric if (MI.getOperand(0).getReg() == ARM::SP &&
740e6d15924SDimitry Andric MI.getOperand(1).getReg() != ARM::SP)
741e6d15924SDimitry Andric return MCDisassembler::SoftFail;
742e6d15924SDimitry Andric return Result;
74367c32a98SDimitry Andric default: return Result;
74467c32a98SDimitry Andric }
74567c32a98SDimitry Andric }
74630815c53SDimitry Andric
suggestBytesToSkip(ArrayRef<uint8_t> Bytes,uint64_t Address) const74708e8dd7bSDimitry Andric uint64_t ARMDisassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
74808e8dd7bSDimitry Andric uint64_t Address) const {
74908e8dd7bSDimitry Andric // In Arm state, instructions are always 4 bytes wide, so there's no
75008e8dd7bSDimitry Andric // point in skipping any smaller number of bytes if an instruction
75108e8dd7bSDimitry Andric // can't be decoded.
7527fa27ce4SDimitry Andric if (!STI.hasFeature(ARM::ModeThumb))
75308e8dd7bSDimitry Andric return 4;
75408e8dd7bSDimitry Andric
75508e8dd7bSDimitry Andric // In a Thumb instruction stream, a halfword is a standalone 2-byte
75608e8dd7bSDimitry Andric // instruction if and only if its value is less than 0xE800.
75708e8dd7bSDimitry Andric // Otherwise, it's the first halfword of a 4-byte instruction.
75808e8dd7bSDimitry Andric //
75908e8dd7bSDimitry Andric // So, if we can see the upcoming halfword, we can judge on that
76008e8dd7bSDimitry Andric // basis, and maybe skip a whole 4-byte instruction that we don't
76108e8dd7bSDimitry Andric // know how to decode, without accidentally trying to interpret its
76208e8dd7bSDimitry Andric // second half as something else.
76308e8dd7bSDimitry Andric //
76408e8dd7bSDimitry Andric // If we don't have the instruction data available, we just have to
76508e8dd7bSDimitry Andric // recommend skipping the minimum sensible distance, which is 2
76608e8dd7bSDimitry Andric // bytes.
76708e8dd7bSDimitry Andric if (Bytes.size() < 2)
76808e8dd7bSDimitry Andric return 2;
76908e8dd7bSDimitry Andric
770e3b55780SDimitry Andric uint16_t Insn16 = llvm::support::endian::read<uint16_t>(
771e3b55780SDimitry Andric Bytes.data(), InstructionEndianness);
77208e8dd7bSDimitry Andric return Insn16 < 0xE800 ? 2 : 4;
77308e8dd7bSDimitry Andric }
77408e8dd7bSDimitry Andric
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const77567c32a98SDimitry Andric DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
77667c32a98SDimitry Andric ArrayRef<uint8_t> Bytes,
777706b4fc4SDimitry Andric uint64_t Address,
77867c32a98SDimitry Andric raw_ostream &CS) const {
7797fa27ce4SDimitry Andric if (STI.hasFeature(ARM::ModeThumb))
780706b4fc4SDimitry Andric return getThumbInstruction(MI, Size, Bytes, Address, CS);
781706b4fc4SDimitry Andric return getARMInstruction(MI, Size, Bytes, Address, CS);
782e6d15924SDimitry Andric }
783e6d15924SDimitry Andric
getARMInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const784e6d15924SDimitry Andric DecodeStatus ARMDisassembler::getARMInstruction(MCInst &MI, uint64_t &Size,
785e6d15924SDimitry Andric ArrayRef<uint8_t> Bytes,
786e6d15924SDimitry Andric uint64_t Address,
787e6d15924SDimitry Andric raw_ostream &CS) const {
78867c32a98SDimitry Andric CommentStream = &CS;
78930815c53SDimitry Andric
7907fa27ce4SDimitry Andric assert(!STI.hasFeature(ARM::ModeThumb) &&
79167c32a98SDimitry Andric "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
79267c32a98SDimitry Andric "mode!");
79330815c53SDimitry Andric
79430815c53SDimitry Andric // We want to read exactly 4 bytes of data.
79567c32a98SDimitry Andric if (Bytes.size() < 4) {
79630815c53SDimitry Andric Size = 0;
79730815c53SDimitry Andric return MCDisassembler::Fail;
79830815c53SDimitry Andric }
79930815c53SDimitry Andric
800e3b55780SDimitry Andric // Encoded as a 32-bit word in the stream.
801e3b55780SDimitry Andric uint32_t Insn = llvm::support::endian::read<uint32_t>(Bytes.data(),
802e3b55780SDimitry Andric InstructionEndianness);
80330815c53SDimitry Andric
80430815c53SDimitry Andric // Calling the auto-generated decoder function.
80567c32a98SDimitry Andric DecodeStatus Result =
80667c32a98SDimitry Andric decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI);
80767c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
80830815c53SDimitry Andric Size = 4;
809706b4fc4SDimitry Andric return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
81030815c53SDimitry Andric }
81130815c53SDimitry Andric
81271d5a254SDimitry Andric struct DecodeTable {
81371d5a254SDimitry Andric const uint8_t *P;
81471d5a254SDimitry Andric bool DecodePred;
81571d5a254SDimitry Andric };
81630815c53SDimitry Andric
81771d5a254SDimitry Andric const DecodeTable Tables[] = {
81871d5a254SDimitry Andric {DecoderTableVFP32, false}, {DecoderTableVFPV832, false},
81971d5a254SDimitry Andric {DecoderTableNEONData32, true}, {DecoderTableNEONLoadStore32, true},
82071d5a254SDimitry Andric {DecoderTableNEONDup32, true}, {DecoderTablev8NEON32, false},
82171d5a254SDimitry Andric {DecoderTablev8Crypto32, false},
82271d5a254SDimitry Andric };
823f8af5cf6SDimitry Andric
82471d5a254SDimitry Andric for (auto Table : Tables) {
82571d5a254SDimitry Andric Result = decodeInstruction(Table.P, MI, Insn, Address, this, STI);
82667c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
82730815c53SDimitry Andric Size = 4;
82830815c53SDimitry Andric // Add a fake predicate operand, because we share these instruction
82930815c53SDimitry Andric // definitions with Thumb2 where these instructions are predicable.
83071d5a254SDimitry Andric if (Table.DecodePred && !DecodePredicateOperand(MI, 0xE, Address, this))
83130815c53SDimitry Andric return MCDisassembler::Fail;
83267c32a98SDimitry Andric return Result;
83330815c53SDimitry Andric }
834f8af5cf6SDimitry Andric }
835f8af5cf6SDimitry Andric
836044eb2f6SDimitry Andric Result =
837044eb2f6SDimitry Andric decodeInstruction(DecoderTableCoProc32, MI, Insn, Address, this, STI);
838044eb2f6SDimitry Andric if (Result != MCDisassembler::Fail) {
839044eb2f6SDimitry Andric Size = 4;
840706b4fc4SDimitry Andric return checkDecodedInstruction(MI, Size, Address, CS, Insn, Result);
841044eb2f6SDimitry Andric }
842044eb2f6SDimitry Andric
8439df3605dSDimitry Andric Size = 4;
84430815c53SDimitry Andric return MCDisassembler::Fail;
84530815c53SDimitry Andric }
84630815c53SDimitry Andric
84730815c53SDimitry Andric /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
84830815c53SDimitry Andric /// immediate Value in the MCInst. The immediate Value has had any PC
84930815c53SDimitry Andric /// adjustment made by the caller. If the instruction is a branch instruction
85030815c53SDimitry Andric /// then isBranch is true, else false. If the getOpInfo() function was set as
85130815c53SDimitry Andric /// part of the setupForSymbolicDisassembly() call then that function is called
85230815c53SDimitry Andric /// to get any symbolic information at the Address for this instruction. If
85330815c53SDimitry Andric /// that returns non-zero then the symbolic information it returns is used to
85430815c53SDimitry Andric /// create an MCExpr and that is added as an operand to the MCInst. If
85530815c53SDimitry Andric /// getOpInfo() returns zero and isBranch is true then a symbol look up for
85630815c53SDimitry Andric /// Value is done and if a symbol is found an MCExpr is created with that, else
85730815c53SDimitry Andric /// an MCExpr with Value is created. This function returns true if it adds an
85830815c53SDimitry Andric /// operand to the MCInst and false otherwise.
tryAddingSymbolicOperand(uint64_t Address,int32_t Value,bool isBranch,uint64_t InstSize,MCInst & MI,const MCDisassembler * Decoder)85930815c53SDimitry Andric static bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
86030815c53SDimitry Andric bool isBranch, uint64_t InstSize,
861145449b1SDimitry Andric MCInst &MI,
862145449b1SDimitry Andric const MCDisassembler *Decoder) {
863f8af5cf6SDimitry Andric // FIXME: Does it make sense for value to be negative?
864145449b1SDimitry Andric return Decoder->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address,
865145449b1SDimitry Andric isBranch, /*Offset=*/0, /*OpSize=*/0,
866145449b1SDimitry Andric InstSize);
86730815c53SDimitry Andric }
86830815c53SDimitry Andric
86930815c53SDimitry Andric /// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
87030815c53SDimitry Andric /// referenced by a load instruction with the base register that is the Pc.
87130815c53SDimitry Andric /// These can often be values in a literal pool near the Address of the
87230815c53SDimitry Andric /// instruction. The Address of the instruction and its immediate Value are
87330815c53SDimitry Andric /// used as a possible literal pool entry. The SymbolLookUp call back will
87458b69754SDimitry Andric /// return the name of a symbol referenced by the literal pool's entry if
87530815c53SDimitry Andric /// the referenced address is that of a symbol. Or it will return a pointer to
87630815c53SDimitry Andric /// a literal 'C' string if the referenced address of the literal pool's entry
87730815c53SDimitry Andric /// is an address into a section with 'C' string literals.
tryAddingPcLoadReferenceComment(uint64_t Address,int Value,const MCDisassembler * Decoder)87830815c53SDimitry Andric static void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
879145449b1SDimitry Andric const MCDisassembler *Decoder) {
88030815c53SDimitry Andric const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
881f8af5cf6SDimitry Andric Dis->tryAddingPcLoadReferenceComment(Value, Address);
88230815c53SDimitry Andric }
88330815c53SDimitry Andric
88430815c53SDimitry Andric // Thumb1 instructions don't have explicit S bits. Rather, they
88530815c53SDimitry Andric // implicitly set CPSR. Since it's not represented in the encoding, the
88630815c53SDimitry Andric // auto-generated decoder won't inject the CPSR operand. We need to fix
88730815c53SDimitry Andric // that as a post-pass.
AddThumb1SBit(MCInst & MI,bool InITBlock) const888e3b55780SDimitry Andric void ARMDisassembler::AddThumb1SBit(MCInst &MI, bool InITBlock) const {
889e3b55780SDimitry Andric const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
89030815c53SDimitry Andric MCInst::iterator I = MI.begin();
891e3b55780SDimitry Andric for (unsigned i = 0; i < MCID.NumOperands; ++i, ++I) {
89230815c53SDimitry Andric if (I == MI.end()) break;
893e3b55780SDimitry Andric if (MCID.operands()[i].isOptionalDef() &&
894e3b55780SDimitry Andric MCID.operands()[i].RegClass == ARM::CCRRegClassID) {
895e3b55780SDimitry Andric if (i > 0 && MCID.operands()[i - 1].isPredicate())
896e3b55780SDimitry Andric continue;
8975a5ac124SDimitry Andric MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
89830815c53SDimitry Andric return;
89930815c53SDimitry Andric }
90030815c53SDimitry Andric }
90130815c53SDimitry Andric
9025a5ac124SDimitry Andric MI.insert(I, MCOperand::createReg(InITBlock ? 0 : ARM::CPSR));
90330815c53SDimitry Andric }
90430815c53SDimitry Andric
isVectorPredicable(const MCInst & MI) const905e3b55780SDimitry Andric bool ARMDisassembler::isVectorPredicable(const MCInst &MI) const {
906e3b55780SDimitry Andric const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
907e3b55780SDimitry Andric for (unsigned i = 0; i < MCID.NumOperands; ++i) {
908e3b55780SDimitry Andric if (ARM::isVpred(MCID.operands()[i].OperandType))
909e6d15924SDimitry Andric return true;
910e6d15924SDimitry Andric }
911e6d15924SDimitry Andric return false;
912e6d15924SDimitry Andric }
913e6d15924SDimitry Andric
91430815c53SDimitry Andric // Most Thumb instructions don't have explicit predicates in the
91530815c53SDimitry Andric // encoding, but rather get their predicates from IT context. We need
91630815c53SDimitry Andric // to fix up the predicate operands using this context information as a
91730815c53SDimitry Andric // post-pass.
91830815c53SDimitry Andric MCDisassembler::DecodeStatus
AddThumbPredicate(MCInst & MI) const919e6d15924SDimitry Andric ARMDisassembler::AddThumbPredicate(MCInst &MI) const {
92030815c53SDimitry Andric MCDisassembler::DecodeStatus S = Success;
92130815c53SDimitry Andric
92201095a5dSDimitry Andric const FeatureBitset &FeatureBits = getSubtargetInfo().getFeatureBits();
92301095a5dSDimitry Andric
92430815c53SDimitry Andric // A few instructions actually have predicates encoded in them. Don't
92530815c53SDimitry Andric // try to overwrite it if we're seeing one of those.
92630815c53SDimitry Andric switch (MI.getOpcode()) {
92730815c53SDimitry Andric case ARM::tBcc:
92830815c53SDimitry Andric case ARM::t2Bcc:
92930815c53SDimitry Andric case ARM::tCBZ:
93030815c53SDimitry Andric case ARM::tCBNZ:
93130815c53SDimitry Andric case ARM::tCPS:
93230815c53SDimitry Andric case ARM::t2CPS3p:
93330815c53SDimitry Andric case ARM::t2CPS2p:
93430815c53SDimitry Andric case ARM::t2CPS1p:
935e6d15924SDimitry Andric case ARM::t2CSEL:
936e6d15924SDimitry Andric case ARM::t2CSINC:
937e6d15924SDimitry Andric case ARM::t2CSINV:
938e6d15924SDimitry Andric case ARM::t2CSNEG:
93930815c53SDimitry Andric case ARM::tMOVSr:
94030815c53SDimitry Andric case ARM::tSETEND:
94130815c53SDimitry Andric // Some instructions (mostly conditional branches) are not
94230815c53SDimitry Andric // allowed in IT blocks.
94358b69754SDimitry Andric if (ITBlock.instrInITBlock())
94430815c53SDimitry Andric S = SoftFail;
94530815c53SDimitry Andric else
94630815c53SDimitry Andric return Success;
94730815c53SDimitry Andric break;
94801095a5dSDimitry Andric case ARM::t2HINT:
94901095a5dSDimitry Andric if (MI.getOperand(0).getImm() == 0x10 && (FeatureBits[ARM::FeatureRAS]) != 0)
95001095a5dSDimitry Andric S = SoftFail;
95101095a5dSDimitry Andric break;
95230815c53SDimitry Andric case ARM::tB:
95330815c53SDimitry Andric case ARM::t2B:
95430815c53SDimitry Andric case ARM::t2TBB:
95530815c53SDimitry Andric case ARM::t2TBH:
95630815c53SDimitry Andric // Some instructions (mostly unconditional branches) can
95730815c53SDimitry Andric // only appears at the end of, or outside of, an IT.
95858b69754SDimitry Andric if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
95930815c53SDimitry Andric S = SoftFail;
96030815c53SDimitry Andric break;
96130815c53SDimitry Andric default:
96230815c53SDimitry Andric break;
96330815c53SDimitry Andric }
96430815c53SDimitry Andric
965e6d15924SDimitry Andric // Warn on non-VPT predicable instruction in a VPT block and a VPT
966e6d15924SDimitry Andric // predicable instruction in an IT block
967e3b55780SDimitry Andric if ((!isVectorPredicable(MI) && VPTBlock.instrInVPTBlock()) ||
968e3b55780SDimitry Andric (isVectorPredicable(MI) && ITBlock.instrInITBlock()))
969e6d15924SDimitry Andric S = SoftFail;
970e6d15924SDimitry Andric
971e6d15924SDimitry Andric // If we're in an IT/VPT block, base the predicate on that. Otherwise,
97230815c53SDimitry Andric // assume a predicate of AL.
973e6d15924SDimitry Andric unsigned CC = ARMCC::AL;
974e6d15924SDimitry Andric unsigned VCC = ARMVCC::None;
975e6d15924SDimitry Andric if (ITBlock.instrInITBlock()) {
97658b69754SDimitry Andric CC = ITBlock.getITCC();
97758b69754SDimitry Andric ITBlock.advanceITState();
978e6d15924SDimitry Andric } else if (VPTBlock.instrInVPTBlock()) {
979e6d15924SDimitry Andric VCC = VPTBlock.getVPTPred();
980e6d15924SDimitry Andric VPTBlock.advanceVPTState();
981e6d15924SDimitry Andric }
98230815c53SDimitry Andric
983e3b55780SDimitry Andric const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
984e6d15924SDimitry Andric
985e6d15924SDimitry Andric MCInst::iterator CCI = MI.begin();
986e3b55780SDimitry Andric for (unsigned i = 0; i < MCID.NumOperands; ++i, ++CCI) {
987e3b55780SDimitry Andric if (MCID.operands()[i].isPredicate() || CCI == MI.end())
988e3b55780SDimitry Andric break;
98930815c53SDimitry Andric }
99030815c53SDimitry Andric
991e3b55780SDimitry Andric if (MCID.isPredicable()) {
992e6d15924SDimitry Andric CCI = MI.insert(CCI, MCOperand::createImm(CC));
993e6d15924SDimitry Andric ++CCI;
99430815c53SDimitry Andric if (CC == ARMCC::AL)
995e6d15924SDimitry Andric MI.insert(CCI, MCOperand::createReg(0));
99630815c53SDimitry Andric else
997e6d15924SDimitry Andric MI.insert(CCI, MCOperand::createReg(ARM::CPSR));
998e6d15924SDimitry Andric } else if (CC != ARMCC::AL) {
999e6d15924SDimitry Andric Check(S, SoftFail);
1000e6d15924SDimitry Andric }
1001e6d15924SDimitry Andric
1002e6d15924SDimitry Andric MCInst::iterator VCCI = MI.begin();
1003e6d15924SDimitry Andric unsigned VCCPos;
1004e3b55780SDimitry Andric for (VCCPos = 0; VCCPos < MCID.NumOperands; ++VCCPos, ++VCCI) {
1005e3b55780SDimitry Andric if (ARM::isVpred(MCID.operands()[VCCPos].OperandType) || VCCI == MI.end())
1006e3b55780SDimitry Andric break;
1007e6d15924SDimitry Andric }
1008e6d15924SDimitry Andric
1009e3b55780SDimitry Andric if (isVectorPredicable(MI)) {
1010e6d15924SDimitry Andric VCCI = MI.insert(VCCI, MCOperand::createImm(VCC));
1011e6d15924SDimitry Andric ++VCCI;
1012e6d15924SDimitry Andric if (VCC == ARMVCC::None)
1013c0981da4SDimitry Andric VCCI = MI.insert(VCCI, MCOperand::createReg(0));
1014e6d15924SDimitry Andric else
1015c0981da4SDimitry Andric VCCI = MI.insert(VCCI, MCOperand::createReg(ARM::P0));
1016c0981da4SDimitry Andric ++VCCI;
1017c0981da4SDimitry Andric VCCI = MI.insert(VCCI, MCOperand::createReg(0));
1018c0981da4SDimitry Andric ++VCCI;
1019e3b55780SDimitry Andric if (MCID.operands()[VCCPos].OperandType == ARM::OPERAND_VPRED_R) {
1020e3b55780SDimitry Andric int TiedOp = MCID.getOperandConstraint(VCCPos + 3, MCOI::TIED_TO);
1021e6d15924SDimitry Andric assert(TiedOp >= 0 &&
1022e6d15924SDimitry Andric "Inactive register in vpred_r is not tied to an output!");
1023b60736ecSDimitry Andric // Copy the operand to ensure it's not invalidated when MI grows.
1024b60736ecSDimitry Andric MI.insert(VCCI, MCOperand(MI.getOperand(TiedOp)));
1025e6d15924SDimitry Andric }
1026e6d15924SDimitry Andric } else if (VCC != ARMVCC::None) {
1027e6d15924SDimitry Andric Check(S, SoftFail);
1028e6d15924SDimitry Andric }
102930815c53SDimitry Andric
103030815c53SDimitry Andric return S;
103130815c53SDimitry Andric }
103230815c53SDimitry Andric
103330815c53SDimitry Andric // Thumb VFP instructions are a special case. Because we share their
103430815c53SDimitry Andric // encodings between ARM and Thumb modes, and they are predicable in ARM
103530815c53SDimitry Andric // mode, the auto-generated decoder will give them an (incorrect)
103630815c53SDimitry Andric // predicate operand. We need to rewrite these operands based on the IT
103730815c53SDimitry Andric // context as a post-pass.
UpdateThumbVFPPredicate(DecodeStatus & S,MCInst & MI) const1038e6d15924SDimitry Andric void ARMDisassembler::UpdateThumbVFPPredicate(
1039e6d15924SDimitry Andric DecodeStatus &S, MCInst &MI) const {
104030815c53SDimitry Andric unsigned CC;
104158b69754SDimitry Andric CC = ITBlock.getITCC();
1042eb11fae6SDimitry Andric if (CC == 0xF)
1043eb11fae6SDimitry Andric CC = ARMCC::AL;
104458b69754SDimitry Andric if (ITBlock.instrInITBlock())
104558b69754SDimitry Andric ITBlock.advanceITState();
1046e6d15924SDimitry Andric else if (VPTBlock.instrInVPTBlock()) {
1047e6d15924SDimitry Andric CC = VPTBlock.getVPTPred();
1048e6d15924SDimitry Andric VPTBlock.advanceVPTState();
1049e6d15924SDimitry Andric }
105030815c53SDimitry Andric
1051e3b55780SDimitry Andric const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
1052e3b55780SDimitry Andric ArrayRef<MCOperandInfo> OpInfo = MCID.operands();
105330815c53SDimitry Andric MCInst::iterator I = MI.begin();
1054e3b55780SDimitry Andric unsigned short NumOps = MCID.NumOperands;
105530815c53SDimitry Andric for (unsigned i = 0; i < NumOps; ++i, ++I) {
105630815c53SDimitry Andric if (OpInfo[i].isPredicate() ) {
1057e3b55780SDimitry Andric if (CC != ARMCC::AL && !MCID.isPredicable())
1058e6d15924SDimitry Andric Check(S, SoftFail);
105930815c53SDimitry Andric I->setImm(CC);
106030815c53SDimitry Andric ++I;
106130815c53SDimitry Andric if (CC == ARMCC::AL)
106230815c53SDimitry Andric I->setReg(0);
106330815c53SDimitry Andric else
106430815c53SDimitry Andric I->setReg(ARM::CPSR);
106530815c53SDimitry Andric return;
106630815c53SDimitry Andric }
106730815c53SDimitry Andric }
106830815c53SDimitry Andric }
106930815c53SDimitry Andric
getThumbInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const1070e6d15924SDimitry Andric DecodeStatus ARMDisassembler::getThumbInstruction(MCInst &MI, uint64_t &Size,
107167c32a98SDimitry Andric ArrayRef<uint8_t> Bytes,
107230815c53SDimitry Andric uint64_t Address,
107367c32a98SDimitry Andric raw_ostream &CS) const {
107467c32a98SDimitry Andric CommentStream = &CS;
107530815c53SDimitry Andric
10767fa27ce4SDimitry Andric assert(STI.hasFeature(ARM::ModeThumb) &&
107730815c53SDimitry Andric "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
107830815c53SDimitry Andric
107930815c53SDimitry Andric // We want to read exactly 2 bytes of data.
108067c32a98SDimitry Andric if (Bytes.size() < 2) {
108130815c53SDimitry Andric Size = 0;
108230815c53SDimitry Andric return MCDisassembler::Fail;
108330815c53SDimitry Andric }
108430815c53SDimitry Andric
1085e3b55780SDimitry Andric uint16_t Insn16 = llvm::support::endian::read<uint16_t>(
1086e3b55780SDimitry Andric Bytes.data(), InstructionEndianness);
108767c32a98SDimitry Andric DecodeStatus Result =
108867c32a98SDimitry Andric decodeInstruction(DecoderTableThumb16, MI, Insn16, Address, this, STI);
108967c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
109030815c53SDimitry Andric Size = 2;
109167c32a98SDimitry Andric Check(Result, AddThumbPredicate(MI));
109267c32a98SDimitry Andric return Result;
109330815c53SDimitry Andric }
109430815c53SDimitry Andric
109567c32a98SDimitry Andric Result = decodeInstruction(DecoderTableThumbSBit16, MI, Insn16, Address, this,
109667c32a98SDimitry Andric STI);
109767c32a98SDimitry Andric if (Result) {
109830815c53SDimitry Andric Size = 2;
109958b69754SDimitry Andric bool InITBlock = ITBlock.instrInITBlock();
110067c32a98SDimitry Andric Check(Result, AddThumbPredicate(MI));
110130815c53SDimitry Andric AddThumb1SBit(MI, InITBlock);
110267c32a98SDimitry Andric return Result;
110330815c53SDimitry Andric }
110430815c53SDimitry Andric
110567c32a98SDimitry Andric Result =
110667c32a98SDimitry Andric decodeInstruction(DecoderTableThumb216, MI, Insn16, Address, this, STI);
110767c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
110830815c53SDimitry Andric Size = 2;
110930815c53SDimitry Andric
111030815c53SDimitry Andric // Nested IT blocks are UNPREDICTABLE. Must be checked before we add
111130815c53SDimitry Andric // the Thumb predicate.
111258b69754SDimitry Andric if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
111367c32a98SDimitry Andric Result = MCDisassembler::SoftFail;
111430815c53SDimitry Andric
111567c32a98SDimitry Andric Check(Result, AddThumbPredicate(MI));
111630815c53SDimitry Andric
111730815c53SDimitry Andric // If we find an IT instruction, we need to parse its condition
111830815c53SDimitry Andric // code and mask operands so that we can apply them correctly
111930815c53SDimitry Andric // to the subsequent instructions.
112030815c53SDimitry Andric if (MI.getOpcode() == ARM::t2IT) {
112158b69754SDimitry Andric unsigned Firstcond = MI.getOperand(0).getImm();
112230815c53SDimitry Andric unsigned Mask = MI.getOperand(1).getImm();
112358b69754SDimitry Andric ITBlock.setITState(Firstcond, Mask);
1124eb11fae6SDimitry Andric
1125eb11fae6SDimitry Andric // An IT instruction that would give a 'NV' predicate is unpredictable.
1126eb11fae6SDimitry Andric if (Firstcond == ARMCC::AL && !isPowerOf2_32(Mask))
1127eb11fae6SDimitry Andric CS << "unpredictable IT predicate sequence";
112830815c53SDimitry Andric }
112930815c53SDimitry Andric
113067c32a98SDimitry Andric return Result;
113130815c53SDimitry Andric }
113230815c53SDimitry Andric
113330815c53SDimitry Andric // We want to read exactly 4 bytes of data.
113467c32a98SDimitry Andric if (Bytes.size() < 4) {
113530815c53SDimitry Andric Size = 0;
113630815c53SDimitry Andric return MCDisassembler::Fail;
113730815c53SDimitry Andric }
113830815c53SDimitry Andric
113967c32a98SDimitry Andric uint32_t Insn32 =
1140e3b55780SDimitry Andric (uint32_t(Insn16) << 16) | llvm::support::endian::read<uint16_t>(
1141e3b55780SDimitry Andric Bytes.data() + 2, InstructionEndianness);
1142e6d15924SDimitry Andric
1143e6d15924SDimitry Andric Result =
1144e6d15924SDimitry Andric decodeInstruction(DecoderTableMVE32, MI, Insn32, Address, this, STI);
1145e6d15924SDimitry Andric if (Result != MCDisassembler::Fail) {
1146e6d15924SDimitry Andric Size = 4;
1147e6d15924SDimitry Andric
1148e6d15924SDimitry Andric // Nested VPT blocks are UNPREDICTABLE. Must be checked before we add
1149e6d15924SDimitry Andric // the VPT predicate.
1150e6d15924SDimitry Andric if (isVPTOpcode(MI.getOpcode()) && VPTBlock.instrInVPTBlock())
1151e6d15924SDimitry Andric Result = MCDisassembler::SoftFail;
1152e6d15924SDimitry Andric
1153e6d15924SDimitry Andric Check(Result, AddThumbPredicate(MI));
1154e6d15924SDimitry Andric
1155e6d15924SDimitry Andric if (isVPTOpcode(MI.getOpcode())) {
1156e6d15924SDimitry Andric unsigned Mask = MI.getOperand(0).getImm();
1157e6d15924SDimitry Andric VPTBlock.setVPTState(Mask);
1158e6d15924SDimitry Andric }
1159e6d15924SDimitry Andric
1160e6d15924SDimitry Andric return Result;
1161e6d15924SDimitry Andric }
1162e6d15924SDimitry Andric
116367c32a98SDimitry Andric Result =
116467c32a98SDimitry Andric decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
116567c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
116630815c53SDimitry Andric Size = 4;
116758b69754SDimitry Andric bool InITBlock = ITBlock.instrInITBlock();
116867c32a98SDimitry Andric Check(Result, AddThumbPredicate(MI));
116930815c53SDimitry Andric AddThumb1SBit(MI, InITBlock);
117067c32a98SDimitry Andric return Result;
117130815c53SDimitry Andric }
117230815c53SDimitry Andric
117367c32a98SDimitry Andric Result =
117467c32a98SDimitry Andric decodeInstruction(DecoderTableThumb232, MI, Insn32, Address, this, STI);
117567c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
117630815c53SDimitry Andric Size = 4;
117767c32a98SDimitry Andric Check(Result, AddThumbPredicate(MI));
1178706b4fc4SDimitry Andric return checkDecodedInstruction(MI, Size, Address, CS, Insn32, Result);
117930815c53SDimitry Andric }
118030815c53SDimitry Andric
118167c32a98SDimitry Andric if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
118267c32a98SDimitry Andric Result =
118367c32a98SDimitry Andric decodeInstruction(DecoderTableVFP32, MI, Insn32, Address, this, STI);
118467c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
118530815c53SDimitry Andric Size = 4;
1186e6d15924SDimitry Andric UpdateThumbVFPPredicate(Result, MI);
118767c32a98SDimitry Andric return Result;
118830815c53SDimitry Andric }
1189f8af5cf6SDimitry Andric }
119030815c53SDimitry Andric
119167c32a98SDimitry Andric Result =
119267c32a98SDimitry Andric decodeInstruction(DecoderTableVFPV832, MI, Insn32, Address, this, STI);
119367c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
1194f8af5cf6SDimitry Andric Size = 4;
119567c32a98SDimitry Andric return Result;
1196f8af5cf6SDimitry Andric }
1197f8af5cf6SDimitry Andric
119867c32a98SDimitry Andric if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
119967c32a98SDimitry Andric Result = decodeInstruction(DecoderTableNEONDup32, MI, Insn32, Address, this,
120067c32a98SDimitry Andric STI);
120167c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
120230815c53SDimitry Andric Size = 4;
120367c32a98SDimitry Andric Check(Result, AddThumbPredicate(MI));
120467c32a98SDimitry Andric return Result;
120530815c53SDimitry Andric }
1206f8af5cf6SDimitry Andric }
120730815c53SDimitry Andric
120867c32a98SDimitry Andric if (fieldFromInstruction(Insn32, 24, 8) == 0xF9) {
120967c32a98SDimitry Andric uint32_t NEONLdStInsn = Insn32;
121030815c53SDimitry Andric NEONLdStInsn &= 0xF0FFFFFF;
121130815c53SDimitry Andric NEONLdStInsn |= 0x04000000;
121267c32a98SDimitry Andric Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
1213902a7b52SDimitry Andric Address, this, STI);
121467c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
121530815c53SDimitry Andric Size = 4;
121667c32a98SDimitry Andric Check(Result, AddThumbPredicate(MI));
121767c32a98SDimitry Andric return Result;
121830815c53SDimitry Andric }
121930815c53SDimitry Andric }
122030815c53SDimitry Andric
122167c32a98SDimitry Andric if (fieldFromInstruction(Insn32, 24, 4) == 0xF) {
122267c32a98SDimitry Andric uint32_t NEONDataInsn = Insn32;
122330815c53SDimitry Andric NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
122430815c53SDimitry Andric NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
122530815c53SDimitry Andric NEONDataInsn |= 0x12000000; // Set bits 28 and 25
122667c32a98SDimitry Andric Result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
1227902a7b52SDimitry Andric Address, this, STI);
122867c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
122930815c53SDimitry Andric Size = 4;
123067c32a98SDimitry Andric Check(Result, AddThumbPredicate(MI));
123167c32a98SDimitry Andric return Result;
123230815c53SDimitry Andric }
1233f8af5cf6SDimitry Andric
123467c32a98SDimitry Andric uint32_t NEONCryptoInsn = Insn32;
1235f8af5cf6SDimitry Andric NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
1236f8af5cf6SDimitry Andric NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
1237f8af5cf6SDimitry Andric NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
123867c32a98SDimitry Andric Result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
1239f8af5cf6SDimitry Andric Address, this, STI);
124067c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
1241f8af5cf6SDimitry Andric Size = 4;
124267c32a98SDimitry Andric return Result;
124330815c53SDimitry Andric }
124430815c53SDimitry Andric
124567c32a98SDimitry Andric uint32_t NEONv8Insn = Insn32;
1246f8af5cf6SDimitry Andric NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
124767c32a98SDimitry Andric Result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
1248f8af5cf6SDimitry Andric this, STI);
124967c32a98SDimitry Andric if (Result != MCDisassembler::Fail) {
1250f8af5cf6SDimitry Andric Size = 4;
125167c32a98SDimitry Andric return Result;
1252f8af5cf6SDimitry Andric }
1253f8af5cf6SDimitry Andric }
1254f8af5cf6SDimitry Andric
1255cfca06d7SDimitry Andric uint32_t Coproc = fieldFromInstruction(Insn32, 8, 4);
1256cfca06d7SDimitry Andric const uint8_t *DecoderTable = ARM::isCDECoproc(Coproc, STI)
1257cfca06d7SDimitry Andric ? DecoderTableThumb2CDE32
1258cfca06d7SDimitry Andric : DecoderTableThumb2CoProc32;
1259044eb2f6SDimitry Andric Result =
1260cfca06d7SDimitry Andric decodeInstruction(DecoderTable, MI, Insn32, Address, this, STI);
1261044eb2f6SDimitry Andric if (Result != MCDisassembler::Fail) {
1262044eb2f6SDimitry Andric Size = 4;
1263044eb2f6SDimitry Andric Check(Result, AddThumbPredicate(MI));
1264044eb2f6SDimitry Andric return Result;
1265044eb2f6SDimitry Andric }
1266044eb2f6SDimitry Andric
126730815c53SDimitry Andric Size = 0;
126830815c53SDimitry Andric return MCDisassembler::Fail;
126930815c53SDimitry Andric }
127030815c53SDimitry Andric
LLVMInitializeARMDisassembler()1271706b4fc4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMDisassembler() {
1272b915e9e0SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheARMLETarget(),
127330815c53SDimitry Andric createARMDisassembler);
1274b915e9e0SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheARMBETarget(),
12755ca98fd9SDimitry Andric createARMDisassembler);
1276b915e9e0SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheThumbLETarget(),
1277e6d15924SDimitry Andric createARMDisassembler);
1278b915e9e0SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheThumbBETarget(),
1279e6d15924SDimitry Andric createARMDisassembler);
128030815c53SDimitry Andric }
128130815c53SDimitry Andric
128263faed5bSDimitry Andric static const uint16_t GPRDecoderTable[] = {
128330815c53SDimitry Andric ARM::R0, ARM::R1, ARM::R2, ARM::R3,
128430815c53SDimitry Andric ARM::R4, ARM::R5, ARM::R6, ARM::R7,
128530815c53SDimitry Andric ARM::R8, ARM::R9, ARM::R10, ARM::R11,
128630815c53SDimitry Andric ARM::R12, ARM::SP, ARM::LR, ARM::PC
128730815c53SDimitry Andric };
128830815c53SDimitry Andric
1289e6d15924SDimitry Andric static const uint16_t CLRMGPRDecoderTable[] = {
1290e6d15924SDimitry Andric ARM::R0, ARM::R1, ARM::R2, ARM::R3,
1291e6d15924SDimitry Andric ARM::R4, ARM::R5, ARM::R6, ARM::R7,
1292e6d15924SDimitry Andric ARM::R8, ARM::R9, ARM::R10, ARM::R11,
1293e6d15924SDimitry Andric ARM::R12, 0, ARM::LR, ARM::APSR
1294e6d15924SDimitry Andric };
1295e6d15924SDimitry Andric
DecodeGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)129663faed5bSDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1297145449b1SDimitry Andric uint64_t Address,
1298145449b1SDimitry Andric const MCDisassembler *Decoder) {
129930815c53SDimitry Andric if (RegNo > 15)
130030815c53SDimitry Andric return MCDisassembler::Fail;
130130815c53SDimitry Andric
130230815c53SDimitry Andric unsigned Register = GPRDecoderTable[RegNo];
13035a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
130430815c53SDimitry Andric return MCDisassembler::Success;
130530815c53SDimitry Andric }
130630815c53SDimitry Andric
DecodeCLRMGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1307e6d15924SDimitry Andric static DecodeStatus DecodeCLRMGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1308e6d15924SDimitry Andric uint64_t Address,
1309145449b1SDimitry Andric const MCDisassembler *Decoder) {
1310e6d15924SDimitry Andric if (RegNo > 15)
1311e6d15924SDimitry Andric return MCDisassembler::Fail;
1312e6d15924SDimitry Andric
1313e6d15924SDimitry Andric unsigned Register = CLRMGPRDecoderTable[RegNo];
1314e6d15924SDimitry Andric if (Register == 0)
1315e6d15924SDimitry Andric return MCDisassembler::Fail;
1316e6d15924SDimitry Andric
1317e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
1318e6d15924SDimitry Andric return MCDisassembler::Success;
1319e6d15924SDimitry Andric }
1320e6d15924SDimitry Andric
DecodeGPRnopcRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1321145449b1SDimitry Andric static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
1322145449b1SDimitry Andric uint64_t Address,
1323145449b1SDimitry Andric const MCDisassembler *Decoder) {
132463faed5bSDimitry Andric DecodeStatus S = MCDisassembler::Success;
132563faed5bSDimitry Andric
132663faed5bSDimitry Andric if (RegNo == 15)
132763faed5bSDimitry Andric S = MCDisassembler::SoftFail;
132863faed5bSDimitry Andric
132963faed5bSDimitry Andric Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
133063faed5bSDimitry Andric
133163faed5bSDimitry Andric return S;
133230815c53SDimitry Andric }
133330815c53SDimitry Andric
DecodeGPRnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1334f65dcba8SDimitry Andric static DecodeStatus DecodeGPRnospRegisterClass(MCInst &Inst, unsigned RegNo,
1335f65dcba8SDimitry Andric uint64_t Address,
1336145449b1SDimitry Andric const MCDisassembler *Decoder) {
1337f65dcba8SDimitry Andric DecodeStatus S = MCDisassembler::Success;
1338f65dcba8SDimitry Andric
1339f65dcba8SDimitry Andric if (RegNo == 13)
1340f65dcba8SDimitry Andric S = MCDisassembler::SoftFail;
1341f65dcba8SDimitry Andric
1342f65dcba8SDimitry Andric Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1343f65dcba8SDimitry Andric
1344f65dcba8SDimitry Andric return S;
1345f65dcba8SDimitry Andric }
1346f65dcba8SDimitry Andric
1347f8af5cf6SDimitry Andric static DecodeStatus
DecodeGPRwithAPSRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1348145449b1SDimitry Andric DecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1349145449b1SDimitry Andric const MCDisassembler *Decoder) {
1350f8af5cf6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
1351f8af5cf6SDimitry Andric
1352f8af5cf6SDimitry Andric if (RegNo == 15)
1353f8af5cf6SDimitry Andric {
13545a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
1355f8af5cf6SDimitry Andric return MCDisassembler::Success;
1356f8af5cf6SDimitry Andric }
1357f8af5cf6SDimitry Andric
1358f8af5cf6SDimitry Andric Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1359f8af5cf6SDimitry Andric return S;
1360f8af5cf6SDimitry Andric }
1361f8af5cf6SDimitry Andric
1362e6d15924SDimitry Andric static DecodeStatus
DecodeGPRwithZRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1363145449b1SDimitry Andric DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1364145449b1SDimitry Andric const MCDisassembler *Decoder) {
1365e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
1366e6d15924SDimitry Andric
1367e6d15924SDimitry Andric if (RegNo == 15)
1368e6d15924SDimitry Andric {
1369e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::ZR));
1370e6d15924SDimitry Andric return MCDisassembler::Success;
1371e6d15924SDimitry Andric }
1372e6d15924SDimitry Andric
1373e6d15924SDimitry Andric if (RegNo == 13)
1374e6d15924SDimitry Andric Check(S, MCDisassembler::SoftFail);
1375e6d15924SDimitry Andric
1376e6d15924SDimitry Andric Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1377e6d15924SDimitry Andric return S;
1378e6d15924SDimitry Andric }
1379e6d15924SDimitry Andric
1380e6d15924SDimitry Andric static DecodeStatus
DecodeGPRwithZRnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1381145449b1SDimitry Andric DecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1382145449b1SDimitry Andric const MCDisassembler *Decoder) {
1383e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
1384e6d15924SDimitry Andric if (RegNo == 13)
1385e6d15924SDimitry Andric return MCDisassembler::Fail;
1386e6d15924SDimitry Andric Check(S, DecodeGPRwithZRRegisterClass(Inst, RegNo, Address, Decoder));
1387e6d15924SDimitry Andric return S;
1388e6d15924SDimitry Andric }
1389e6d15924SDimitry Andric
DecodetGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)139063faed5bSDimitry Andric static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1391145449b1SDimitry Andric uint64_t Address,
1392145449b1SDimitry Andric const MCDisassembler *Decoder) {
139330815c53SDimitry Andric if (RegNo > 7)
139430815c53SDimitry Andric return MCDisassembler::Fail;
139530815c53SDimitry Andric return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
139630815c53SDimitry Andric }
139730815c53SDimitry Andric
1398f8af5cf6SDimitry Andric static const uint16_t GPRPairDecoderTable[] = {
1399f8af5cf6SDimitry Andric ARM::R0_R1, ARM::R2_R3, ARM::R4_R5, ARM::R6_R7,
1400f8af5cf6SDimitry Andric ARM::R8_R9, ARM::R10_R11, ARM::R12_SP
1401f8af5cf6SDimitry Andric };
1402f8af5cf6SDimitry Andric
DecodeGPRPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1403f8af5cf6SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
1404145449b1SDimitry Andric uint64_t Address,
1405145449b1SDimitry Andric const MCDisassembler *Decoder) {
1406f8af5cf6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
1407f8af5cf6SDimitry Andric
1408cfca06d7SDimitry Andric // According to the Arm ARM RegNo = 14 is undefined, but we return fail
1409cfca06d7SDimitry Andric // rather than SoftFail as there is no GPRPair table entry for index 7.
1410f8af5cf6SDimitry Andric if (RegNo > 13)
1411f8af5cf6SDimitry Andric return MCDisassembler::Fail;
1412f8af5cf6SDimitry Andric
1413cfca06d7SDimitry Andric if (RegNo & 1)
1414f8af5cf6SDimitry Andric S = MCDisassembler::SoftFail;
1415f8af5cf6SDimitry Andric
1416f8af5cf6SDimitry Andric unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
14175a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(RegisterPair));
1418f8af5cf6SDimitry Andric return S;
1419f8af5cf6SDimitry Andric }
1420f8af5cf6SDimitry Andric
1421145449b1SDimitry Andric static DecodeStatus
DecodeGPRPairnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1422145449b1SDimitry Andric DecodeGPRPairnospRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1423145449b1SDimitry Andric const MCDisassembler *Decoder) {
1424cfca06d7SDimitry Andric if (RegNo > 13)
1425cfca06d7SDimitry Andric return MCDisassembler::Fail;
1426cfca06d7SDimitry Andric
1427cfca06d7SDimitry Andric unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
1428cfca06d7SDimitry Andric Inst.addOperand(MCOperand::createReg(RegisterPair));
1429cfca06d7SDimitry Andric
1430cfca06d7SDimitry Andric if ((RegNo & 1) || RegNo > 10)
1431cfca06d7SDimitry Andric return MCDisassembler::SoftFail;
1432cfca06d7SDimitry Andric return MCDisassembler::Success;
1433cfca06d7SDimitry Andric }
1434cfca06d7SDimitry Andric
DecodeGPRspRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1435706b4fc4SDimitry Andric static DecodeStatus DecodeGPRspRegisterClass(MCInst &Inst, unsigned RegNo,
1436706b4fc4SDimitry Andric uint64_t Address,
1437145449b1SDimitry Andric const MCDisassembler *Decoder) {
1438706b4fc4SDimitry Andric if (RegNo != 13)
1439706b4fc4SDimitry Andric return MCDisassembler::Fail;
1440706b4fc4SDimitry Andric
1441706b4fc4SDimitry Andric unsigned Register = GPRDecoderTable[RegNo];
1442706b4fc4SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
1443706b4fc4SDimitry Andric return MCDisassembler::Success;
1444706b4fc4SDimitry Andric }
1445706b4fc4SDimitry Andric
DecodetcGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)144663faed5bSDimitry Andric static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1447145449b1SDimitry Andric uint64_t Address,
1448145449b1SDimitry Andric const MCDisassembler *Decoder) {
144930815c53SDimitry Andric unsigned Register = 0;
145030815c53SDimitry Andric switch (RegNo) {
145130815c53SDimitry Andric case 0:
145230815c53SDimitry Andric Register = ARM::R0;
145330815c53SDimitry Andric break;
145430815c53SDimitry Andric case 1:
145530815c53SDimitry Andric Register = ARM::R1;
145630815c53SDimitry Andric break;
145730815c53SDimitry Andric case 2:
145830815c53SDimitry Andric Register = ARM::R2;
145930815c53SDimitry Andric break;
146030815c53SDimitry Andric case 3:
146130815c53SDimitry Andric Register = ARM::R3;
146230815c53SDimitry Andric break;
146330815c53SDimitry Andric case 9:
146430815c53SDimitry Andric Register = ARM::R9;
146530815c53SDimitry Andric break;
146630815c53SDimitry Andric case 12:
146730815c53SDimitry Andric Register = ARM::R12;
146830815c53SDimitry Andric break;
146930815c53SDimitry Andric default:
147030815c53SDimitry Andric return MCDisassembler::Fail;
147130815c53SDimitry Andric }
147230815c53SDimitry Andric
14735a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
147430815c53SDimitry Andric return MCDisassembler::Success;
147530815c53SDimitry Andric }
147630815c53SDimitry Andric
DecoderGPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)147763faed5bSDimitry Andric static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1478145449b1SDimitry Andric uint64_t Address,
1479145449b1SDimitry Andric const MCDisassembler *Decoder) {
1480f8af5cf6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
1481dd58ef01SDimitry Andric
1482dd58ef01SDimitry Andric const FeatureBitset &featureBits =
1483dd58ef01SDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
1484dd58ef01SDimitry Andric
1485dd58ef01SDimitry Andric if ((RegNo == 13 && !featureBits[ARM::HasV8Ops]) || RegNo == 15)
1486f8af5cf6SDimitry Andric S = MCDisassembler::SoftFail;
1487dd58ef01SDimitry Andric
1488f8af5cf6SDimitry Andric Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1489f8af5cf6SDimitry Andric return S;
149030815c53SDimitry Andric }
149130815c53SDimitry Andric
149263faed5bSDimitry Andric static const uint16_t SPRDecoderTable[] = {
149330815c53SDimitry Andric ARM::S0, ARM::S1, ARM::S2, ARM::S3,
149430815c53SDimitry Andric ARM::S4, ARM::S5, ARM::S6, ARM::S7,
149530815c53SDimitry Andric ARM::S8, ARM::S9, ARM::S10, ARM::S11,
149630815c53SDimitry Andric ARM::S12, ARM::S13, ARM::S14, ARM::S15,
149730815c53SDimitry Andric ARM::S16, ARM::S17, ARM::S18, ARM::S19,
149830815c53SDimitry Andric ARM::S20, ARM::S21, ARM::S22, ARM::S23,
149930815c53SDimitry Andric ARM::S24, ARM::S25, ARM::S26, ARM::S27,
150030815c53SDimitry Andric ARM::S28, ARM::S29, ARM::S30, ARM::S31
150130815c53SDimitry Andric };
150230815c53SDimitry Andric
DecodeSPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)150363faed5bSDimitry Andric static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
1504145449b1SDimitry Andric uint64_t Address,
1505145449b1SDimitry Andric const MCDisassembler *Decoder) {
150630815c53SDimitry Andric if (RegNo > 31)
150730815c53SDimitry Andric return MCDisassembler::Fail;
150830815c53SDimitry Andric
150930815c53SDimitry Andric unsigned Register = SPRDecoderTable[RegNo];
15105a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
151130815c53SDimitry Andric return MCDisassembler::Success;
151230815c53SDimitry Andric }
151330815c53SDimitry Andric
DecodeHPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1514eb11fae6SDimitry Andric static DecodeStatus DecodeHPRRegisterClass(MCInst &Inst, unsigned RegNo,
1515145449b1SDimitry Andric uint64_t Address,
1516145449b1SDimitry Andric const MCDisassembler *Decoder) {
1517eb11fae6SDimitry Andric return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
1518eb11fae6SDimitry Andric }
1519eb11fae6SDimitry Andric
152063faed5bSDimitry Andric static const uint16_t DPRDecoderTable[] = {
152130815c53SDimitry Andric ARM::D0, ARM::D1, ARM::D2, ARM::D3,
152230815c53SDimitry Andric ARM::D4, ARM::D5, ARM::D6, ARM::D7,
152330815c53SDimitry Andric ARM::D8, ARM::D9, ARM::D10, ARM::D11,
152430815c53SDimitry Andric ARM::D12, ARM::D13, ARM::D14, ARM::D15,
152530815c53SDimitry Andric ARM::D16, ARM::D17, ARM::D18, ARM::D19,
152630815c53SDimitry Andric ARM::D20, ARM::D21, ARM::D22, ARM::D23,
152730815c53SDimitry Andric ARM::D24, ARM::D25, ARM::D26, ARM::D27,
152830815c53SDimitry Andric ARM::D28, ARM::D29, ARM::D30, ARM::D31
152930815c53SDimitry Andric };
153030815c53SDimitry Andric
DecodeDPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)153163faed5bSDimitry Andric static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
1532145449b1SDimitry Andric uint64_t Address,
1533145449b1SDimitry Andric const MCDisassembler *Decoder) {
15345a5ac124SDimitry Andric const FeatureBitset &featureBits =
15355a5ac124SDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
15365a5ac124SDimitry Andric
1537e6d15924SDimitry Andric bool hasD32 = featureBits[ARM::FeatureD32];
153867c32a98SDimitry Andric
1539e6d15924SDimitry Andric if (RegNo > 31 || (!hasD32 && RegNo > 15))
154030815c53SDimitry Andric return MCDisassembler::Fail;
154130815c53SDimitry Andric
154230815c53SDimitry Andric unsigned Register = DPRDecoderTable[RegNo];
15435a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
154430815c53SDimitry Andric return MCDisassembler::Success;
154530815c53SDimitry Andric }
154630815c53SDimitry Andric
DecodeDPR_8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)154763faed5bSDimitry Andric static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1548145449b1SDimitry Andric uint64_t Address,
1549145449b1SDimitry Andric const MCDisassembler *Decoder) {
155030815c53SDimitry Andric if (RegNo > 7)
155130815c53SDimitry Andric return MCDisassembler::Fail;
155230815c53SDimitry Andric return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
155330815c53SDimitry Andric }
155430815c53SDimitry Andric
DecodeSPR_8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1555e6d15924SDimitry Andric static DecodeStatus DecodeSPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1556145449b1SDimitry Andric uint64_t Address,
1557145449b1SDimitry Andric const MCDisassembler *Decoder) {
1558e6d15924SDimitry Andric if (RegNo > 15)
1559e6d15924SDimitry Andric return MCDisassembler::Fail;
1560e6d15924SDimitry Andric return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
1561e6d15924SDimitry Andric }
1562e6d15924SDimitry Andric
DecodeDPR_VFP2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1563145449b1SDimitry Andric static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
1564145449b1SDimitry Andric uint64_t Address,
1565145449b1SDimitry Andric const MCDisassembler *Decoder) {
156630815c53SDimitry Andric if (RegNo > 15)
156730815c53SDimitry Andric return MCDisassembler::Fail;
156830815c53SDimitry Andric return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
156930815c53SDimitry Andric }
157030815c53SDimitry Andric
157163faed5bSDimitry Andric static const uint16_t QPRDecoderTable[] = {
157230815c53SDimitry Andric ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3,
157330815c53SDimitry Andric ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7,
157430815c53SDimitry Andric ARM::Q8, ARM::Q9, ARM::Q10, ARM::Q11,
157530815c53SDimitry Andric ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
157630815c53SDimitry Andric };
157730815c53SDimitry Andric
DecodeQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)157863faed5bSDimitry Andric static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
1579145449b1SDimitry Andric uint64_t Address,
1580145449b1SDimitry Andric const MCDisassembler *Decoder) {
1581f8af5cf6SDimitry Andric if (RegNo > 31 || (RegNo & 1) != 0)
158230815c53SDimitry Andric return MCDisassembler::Fail;
158330815c53SDimitry Andric RegNo >>= 1;
158430815c53SDimitry Andric
158530815c53SDimitry Andric unsigned Register = QPRDecoderTable[RegNo];
15865a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
158730815c53SDimitry Andric return MCDisassembler::Success;
158830815c53SDimitry Andric }
158930815c53SDimitry Andric
159063faed5bSDimitry Andric static const uint16_t DPairDecoderTable[] = {
159163faed5bSDimitry Andric ARM::Q0, ARM::D1_D2, ARM::Q1, ARM::D3_D4, ARM::Q2, ARM::D5_D6,
159263faed5bSDimitry Andric ARM::Q3, ARM::D7_D8, ARM::Q4, ARM::D9_D10, ARM::Q5, ARM::D11_D12,
159363faed5bSDimitry Andric ARM::Q6, ARM::D13_D14, ARM::Q7, ARM::D15_D16, ARM::Q8, ARM::D17_D18,
159463faed5bSDimitry Andric ARM::Q9, ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
159563faed5bSDimitry Andric ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
159663faed5bSDimitry Andric ARM::Q15
159763faed5bSDimitry Andric };
159863faed5bSDimitry Andric
DecodeDPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)159963faed5bSDimitry Andric static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
1600145449b1SDimitry Andric uint64_t Address,
1601145449b1SDimitry Andric const MCDisassembler *Decoder) {
160263faed5bSDimitry Andric if (RegNo > 30)
160363faed5bSDimitry Andric return MCDisassembler::Fail;
160463faed5bSDimitry Andric
160563faed5bSDimitry Andric unsigned Register = DPairDecoderTable[RegNo];
16065a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
160763faed5bSDimitry Andric return MCDisassembler::Success;
160863faed5bSDimitry Andric }
160963faed5bSDimitry Andric
161063faed5bSDimitry Andric static const uint16_t DPairSpacedDecoderTable[] = {
161163faed5bSDimitry Andric ARM::D0_D2, ARM::D1_D3, ARM::D2_D4, ARM::D3_D5,
161263faed5bSDimitry Andric ARM::D4_D6, ARM::D5_D7, ARM::D6_D8, ARM::D7_D9,
161363faed5bSDimitry Andric ARM::D8_D10, ARM::D9_D11, ARM::D10_D12, ARM::D11_D13,
161463faed5bSDimitry Andric ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
161563faed5bSDimitry Andric ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
161663faed5bSDimitry Andric ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
161763faed5bSDimitry Andric ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
161863faed5bSDimitry Andric ARM::D28_D30, ARM::D29_D31
161963faed5bSDimitry Andric };
162063faed5bSDimitry Andric
1621145449b1SDimitry Andric static DecodeStatus
DecodeDPairSpacedRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)1622145449b1SDimitry Andric DecodeDPairSpacedRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
1623145449b1SDimitry Andric const MCDisassembler *Decoder) {
162463faed5bSDimitry Andric if (RegNo > 29)
162563faed5bSDimitry Andric return MCDisassembler::Fail;
162663faed5bSDimitry Andric
162763faed5bSDimitry Andric unsigned Register = DPairSpacedDecoderTable[RegNo];
16285a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
162963faed5bSDimitry Andric return MCDisassembler::Success;
163063faed5bSDimitry Andric }
163163faed5bSDimitry Andric
DecodePredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)163263faed5bSDimitry Andric static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
1633145449b1SDimitry Andric uint64_t Address,
1634145449b1SDimitry Andric const MCDisassembler *Decoder) {
1635e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
163630815c53SDimitry Andric if (Val == 0xF) return MCDisassembler::Fail;
163730815c53SDimitry Andric // AL predicate is not allowed on Thumb1 branches.
163830815c53SDimitry Andric if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
163930815c53SDimitry Andric return MCDisassembler::Fail;
1640e3b55780SDimitry Andric const MCInstrInfo *MCII =
1641e3b55780SDimitry Andric static_cast<const ARMDisassembler *>(Decoder)->MCII.get();
1642e3b55780SDimitry Andric if (Val != ARMCC::AL && !MCII->get(Inst.getOpcode()).isPredicable())
1643e6d15924SDimitry Andric Check(S, MCDisassembler::SoftFail);
16445a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
164530815c53SDimitry Andric if (Val == ARMCC::AL) {
16465a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
164730815c53SDimitry Andric } else
16485a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::CPSR));
1649e6d15924SDimitry Andric return S;
165030815c53SDimitry Andric }
165130815c53SDimitry Andric
DecodeCCOutOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)165263faed5bSDimitry Andric static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
1653145449b1SDimitry Andric uint64_t Address,
1654145449b1SDimitry Andric const MCDisassembler *Decoder) {
165530815c53SDimitry Andric if (Val)
16565a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::CPSR));
165730815c53SDimitry Andric else
16585a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
165930815c53SDimitry Andric return MCDisassembler::Success;
166030815c53SDimitry Andric }
166130815c53SDimitry Andric
DecodeSORegImmOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)166263faed5bSDimitry Andric static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
1663145449b1SDimitry Andric uint64_t Address,
1664145449b1SDimitry Andric const MCDisassembler *Decoder) {
166530815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
166630815c53SDimitry Andric
1667902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Val, 0, 4);
1668902a7b52SDimitry Andric unsigned type = fieldFromInstruction(Val, 5, 2);
1669902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 7, 5);
167030815c53SDimitry Andric
167130815c53SDimitry Andric // Register-immediate
1672dd58ef01SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
167330815c53SDimitry Andric return MCDisassembler::Fail;
167430815c53SDimitry Andric
167530815c53SDimitry Andric ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
167630815c53SDimitry Andric switch (type) {
167730815c53SDimitry Andric case 0:
167830815c53SDimitry Andric Shift = ARM_AM::lsl;
167930815c53SDimitry Andric break;
168030815c53SDimitry Andric case 1:
168130815c53SDimitry Andric Shift = ARM_AM::lsr;
168230815c53SDimitry Andric break;
168330815c53SDimitry Andric case 2:
168430815c53SDimitry Andric Shift = ARM_AM::asr;
168530815c53SDimitry Andric break;
168630815c53SDimitry Andric case 3:
168730815c53SDimitry Andric Shift = ARM_AM::ror;
168830815c53SDimitry Andric break;
168930815c53SDimitry Andric }
169030815c53SDimitry Andric
169130815c53SDimitry Andric if (Shift == ARM_AM::ror && imm == 0)
169230815c53SDimitry Andric Shift = ARM_AM::rrx;
169330815c53SDimitry Andric
169430815c53SDimitry Andric unsigned Op = Shift | (imm << 3);
16955a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Op));
169630815c53SDimitry Andric
169730815c53SDimitry Andric return S;
169830815c53SDimitry Andric }
169930815c53SDimitry Andric
DecodeSORegRegOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)170063faed5bSDimitry Andric static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
1701145449b1SDimitry Andric uint64_t Address,
1702145449b1SDimitry Andric const MCDisassembler *Decoder) {
170330815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
170430815c53SDimitry Andric
1705902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Val, 0, 4);
1706902a7b52SDimitry Andric unsigned type = fieldFromInstruction(Val, 5, 2);
1707902a7b52SDimitry Andric unsigned Rs = fieldFromInstruction(Val, 8, 4);
170830815c53SDimitry Andric
170930815c53SDimitry Andric // Register-register
171030815c53SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
171130815c53SDimitry Andric return MCDisassembler::Fail;
171230815c53SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
171330815c53SDimitry Andric return MCDisassembler::Fail;
171430815c53SDimitry Andric
171530815c53SDimitry Andric ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
171630815c53SDimitry Andric switch (type) {
171730815c53SDimitry Andric case 0:
171830815c53SDimitry Andric Shift = ARM_AM::lsl;
171930815c53SDimitry Andric break;
172030815c53SDimitry Andric case 1:
172130815c53SDimitry Andric Shift = ARM_AM::lsr;
172230815c53SDimitry Andric break;
172330815c53SDimitry Andric case 2:
172430815c53SDimitry Andric Shift = ARM_AM::asr;
172530815c53SDimitry Andric break;
172630815c53SDimitry Andric case 3:
172730815c53SDimitry Andric Shift = ARM_AM::ror;
172830815c53SDimitry Andric break;
172930815c53SDimitry Andric }
173030815c53SDimitry Andric
17315a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Shift));
173230815c53SDimitry Andric
173330815c53SDimitry Andric return S;
173430815c53SDimitry Andric }
173530815c53SDimitry Andric
DecodeRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)173663faed5bSDimitry Andric static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
1737145449b1SDimitry Andric uint64_t Address,
1738145449b1SDimitry Andric const MCDisassembler *Decoder) {
173930815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
174030815c53SDimitry Andric
1741f8af5cf6SDimitry Andric bool NeedDisjointWriteback = false;
1742f8af5cf6SDimitry Andric unsigned WritebackReg = 0;
1743e6d15924SDimitry Andric bool CLRM = false;
174430815c53SDimitry Andric switch (Inst.getOpcode()) {
174530815c53SDimitry Andric default:
174630815c53SDimitry Andric break;
174730815c53SDimitry Andric case ARM::LDMIA_UPD:
174830815c53SDimitry Andric case ARM::LDMDB_UPD:
174930815c53SDimitry Andric case ARM::LDMIB_UPD:
175030815c53SDimitry Andric case ARM::LDMDA_UPD:
175130815c53SDimitry Andric case ARM::t2LDMIA_UPD:
175230815c53SDimitry Andric case ARM::t2LDMDB_UPD:
1753f8af5cf6SDimitry Andric case ARM::t2STMIA_UPD:
1754f8af5cf6SDimitry Andric case ARM::t2STMDB_UPD:
1755f8af5cf6SDimitry Andric NeedDisjointWriteback = true;
1756f8af5cf6SDimitry Andric WritebackReg = Inst.getOperand(0).getReg();
175730815c53SDimitry Andric break;
1758e6d15924SDimitry Andric case ARM::t2CLRM:
1759e6d15924SDimitry Andric CLRM = true;
1760e6d15924SDimitry Andric break;
176130815c53SDimitry Andric }
176230815c53SDimitry Andric
176330815c53SDimitry Andric // Empty register lists are not allowed.
1764f8af5cf6SDimitry Andric if (Val == 0) return MCDisassembler::Fail;
176530815c53SDimitry Andric for (unsigned i = 0; i < 16; ++i) {
176630815c53SDimitry Andric if (Val & (1 << i)) {
1767e6d15924SDimitry Andric if (CLRM) {
1768e6d15924SDimitry Andric if (!Check(S, DecodeCLRMGPRRegisterClass(Inst, i, Address, Decoder))) {
1769e6d15924SDimitry Andric return MCDisassembler::Fail;
1770e6d15924SDimitry Andric }
1771e6d15924SDimitry Andric } else {
177230815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
177330815c53SDimitry Andric return MCDisassembler::Fail;
177430815c53SDimitry Andric // Writeback not allowed if Rn is in the target list.
1775f8af5cf6SDimitry Andric if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg())
177630815c53SDimitry Andric Check(S, MCDisassembler::SoftFail);
177730815c53SDimitry Andric }
177830815c53SDimitry Andric }
1779e6d15924SDimitry Andric }
178030815c53SDimitry Andric
178130815c53SDimitry Andric return S;
178230815c53SDimitry Andric }
178330815c53SDimitry Andric
DecodeSPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)178463faed5bSDimitry Andric static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
1785145449b1SDimitry Andric uint64_t Address,
1786145449b1SDimitry Andric const MCDisassembler *Decoder) {
178730815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
178830815c53SDimitry Andric
1789902a7b52SDimitry Andric unsigned Vd = fieldFromInstruction(Val, 8, 5);
1790902a7b52SDimitry Andric unsigned regs = fieldFromInstruction(Val, 0, 8);
179130815c53SDimitry Andric
1792f8af5cf6SDimitry Andric // In case of unpredictable encoding, tweak the operands.
1793f8af5cf6SDimitry Andric if (regs == 0 || (Vd + regs) > 32) {
1794f8af5cf6SDimitry Andric regs = Vd + regs > 32 ? 32 - Vd : regs;
1795f8af5cf6SDimitry Andric regs = std::max( 1u, regs);
1796f8af5cf6SDimitry Andric S = MCDisassembler::SoftFail;
1797f8af5cf6SDimitry Andric }
1798f8af5cf6SDimitry Andric
179930815c53SDimitry Andric if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
180030815c53SDimitry Andric return MCDisassembler::Fail;
180130815c53SDimitry Andric for (unsigned i = 0; i < (regs - 1); ++i) {
180230815c53SDimitry Andric if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
180330815c53SDimitry Andric return MCDisassembler::Fail;
180430815c53SDimitry Andric }
180530815c53SDimitry Andric
180630815c53SDimitry Andric return S;
180730815c53SDimitry Andric }
180830815c53SDimitry Andric
DecodeDPRRegListOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)180963faed5bSDimitry Andric static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
1810145449b1SDimitry Andric uint64_t Address,
1811145449b1SDimitry Andric const MCDisassembler *Decoder) {
181230815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
181330815c53SDimitry Andric
1814902a7b52SDimitry Andric unsigned Vd = fieldFromInstruction(Val, 8, 5);
1815f8af5cf6SDimitry Andric unsigned regs = fieldFromInstruction(Val, 1, 7);
181658b69754SDimitry Andric
1817f8af5cf6SDimitry Andric // In case of unpredictable encoding, tweak the operands.
1818f8af5cf6SDimitry Andric if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
1819f8af5cf6SDimitry Andric regs = Vd + regs > 32 ? 32 - Vd : regs;
1820f8af5cf6SDimitry Andric regs = std::max( 1u, regs);
1821f8af5cf6SDimitry Andric regs = std::min(16u, regs);
1822f8af5cf6SDimitry Andric S = MCDisassembler::SoftFail;
1823f8af5cf6SDimitry Andric }
182430815c53SDimitry Andric
182530815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
182630815c53SDimitry Andric return MCDisassembler::Fail;
182730815c53SDimitry Andric for (unsigned i = 0; i < (regs - 1); ++i) {
182830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
182930815c53SDimitry Andric return MCDisassembler::Fail;
183030815c53SDimitry Andric }
183130815c53SDimitry Andric
183230815c53SDimitry Andric return S;
183330815c53SDimitry Andric }
183430815c53SDimitry Andric
DecodeBitfieldMaskOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)183563faed5bSDimitry Andric static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
1836145449b1SDimitry Andric uint64_t Address,
1837145449b1SDimitry Andric const MCDisassembler *Decoder) {
183830815c53SDimitry Andric // This operand encodes a mask of contiguous zeros between a specified MSB
183930815c53SDimitry Andric // and LSB. To decode it, we create the mask of all bits MSB-and-lower,
184030815c53SDimitry Andric // the mask of all bits LSB-and-lower, and then xor them to create
184130815c53SDimitry Andric // the mask of that's all ones on [msb, lsb]. Finally we not it to
184230815c53SDimitry Andric // create the final mask.
1843902a7b52SDimitry Andric unsigned msb = fieldFromInstruction(Val, 5, 5);
1844902a7b52SDimitry Andric unsigned lsb = fieldFromInstruction(Val, 0, 5);
184530815c53SDimitry Andric
184630815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
18474a16efa3SDimitry Andric if (lsb > msb) {
18484a16efa3SDimitry Andric Check(S, MCDisassembler::SoftFail);
18494a16efa3SDimitry Andric // The check above will cause the warning for the "potentially undefined
18504a16efa3SDimitry Andric // instruction encoding" but we can't build a bad MCOperand value here
18514a16efa3SDimitry Andric // with a lsb > msb or else printing the MCInst will cause a crash.
18524a16efa3SDimitry Andric lsb = msb;
18534a16efa3SDimitry Andric }
185430815c53SDimitry Andric
185530815c53SDimitry Andric uint32_t msb_mask = 0xFFFFFFFF;
185630815c53SDimitry Andric if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
185730815c53SDimitry Andric uint32_t lsb_mask = (1U << lsb) - 1;
185830815c53SDimitry Andric
18595a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(~(msb_mask ^ lsb_mask)));
186030815c53SDimitry Andric return S;
186130815c53SDimitry Andric }
186230815c53SDimitry Andric
DecodeCopMemInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)186363faed5bSDimitry Andric static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
1864145449b1SDimitry Andric uint64_t Address,
1865145449b1SDimitry Andric const MCDisassembler *Decoder) {
186630815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
186730815c53SDimitry Andric
1868902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
1869902a7b52SDimitry Andric unsigned CRd = fieldFromInstruction(Insn, 12, 4);
1870902a7b52SDimitry Andric unsigned coproc = fieldFromInstruction(Insn, 8, 4);
1871902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 8);
1872902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1873902a7b52SDimitry Andric unsigned U = fieldFromInstruction(Insn, 23, 1);
1874e6d15924SDimitry Andric const FeatureBitset &featureBits =
1875e6d15924SDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
187630815c53SDimitry Andric
187730815c53SDimitry Andric switch (Inst.getOpcode()) {
187830815c53SDimitry Andric case ARM::LDC_OFFSET:
187930815c53SDimitry Andric case ARM::LDC_PRE:
188030815c53SDimitry Andric case ARM::LDC_POST:
188130815c53SDimitry Andric case ARM::LDC_OPTION:
188230815c53SDimitry Andric case ARM::LDCL_OFFSET:
188330815c53SDimitry Andric case ARM::LDCL_PRE:
188430815c53SDimitry Andric case ARM::LDCL_POST:
188530815c53SDimitry Andric case ARM::LDCL_OPTION:
188630815c53SDimitry Andric case ARM::STC_OFFSET:
188730815c53SDimitry Andric case ARM::STC_PRE:
188830815c53SDimitry Andric case ARM::STC_POST:
188930815c53SDimitry Andric case ARM::STC_OPTION:
189030815c53SDimitry Andric case ARM::STCL_OFFSET:
189130815c53SDimitry Andric case ARM::STCL_PRE:
189230815c53SDimitry Andric case ARM::STCL_POST:
189330815c53SDimitry Andric case ARM::STCL_OPTION:
189430815c53SDimitry Andric case ARM::t2LDC_OFFSET:
189530815c53SDimitry Andric case ARM::t2LDC_PRE:
189630815c53SDimitry Andric case ARM::t2LDC_POST:
189730815c53SDimitry Andric case ARM::t2LDC_OPTION:
189830815c53SDimitry Andric case ARM::t2LDCL_OFFSET:
189930815c53SDimitry Andric case ARM::t2LDCL_PRE:
190030815c53SDimitry Andric case ARM::t2LDCL_POST:
190130815c53SDimitry Andric case ARM::t2LDCL_OPTION:
190230815c53SDimitry Andric case ARM::t2STC_OFFSET:
190330815c53SDimitry Andric case ARM::t2STC_PRE:
190430815c53SDimitry Andric case ARM::t2STC_POST:
190530815c53SDimitry Andric case ARM::t2STC_OPTION:
190630815c53SDimitry Andric case ARM::t2STCL_OFFSET:
190730815c53SDimitry Andric case ARM::t2STCL_PRE:
190830815c53SDimitry Andric case ARM::t2STCL_POST:
190930815c53SDimitry Andric case ARM::t2STCL_OPTION:
1910e6d15924SDimitry Andric case ARM::t2LDC2_OFFSET:
1911e6d15924SDimitry Andric case ARM::t2LDC2L_OFFSET:
1912e6d15924SDimitry Andric case ARM::t2LDC2_PRE:
1913e6d15924SDimitry Andric case ARM::t2LDC2L_PRE:
1914e6d15924SDimitry Andric case ARM::t2STC2_OFFSET:
1915e6d15924SDimitry Andric case ARM::t2STC2L_OFFSET:
1916e6d15924SDimitry Andric case ARM::t2STC2_PRE:
1917e6d15924SDimitry Andric case ARM::t2STC2L_PRE:
1918e6d15924SDimitry Andric case ARM::LDC2_OFFSET:
1919e6d15924SDimitry Andric case ARM::LDC2L_OFFSET:
1920e6d15924SDimitry Andric case ARM::LDC2_PRE:
1921e6d15924SDimitry Andric case ARM::LDC2L_PRE:
1922e6d15924SDimitry Andric case ARM::STC2_OFFSET:
1923e6d15924SDimitry Andric case ARM::STC2L_OFFSET:
1924e6d15924SDimitry Andric case ARM::STC2_PRE:
1925e6d15924SDimitry Andric case ARM::STC2L_PRE:
1926e6d15924SDimitry Andric case ARM::t2LDC2_OPTION:
1927e6d15924SDimitry Andric case ARM::t2STC2_OPTION:
1928e6d15924SDimitry Andric case ARM::t2LDC2_POST:
1929e6d15924SDimitry Andric case ARM::t2LDC2L_POST:
1930e6d15924SDimitry Andric case ARM::t2STC2_POST:
1931e6d15924SDimitry Andric case ARM::t2STC2L_POST:
1932e6d15924SDimitry Andric case ARM::LDC2_POST:
1933e6d15924SDimitry Andric case ARM::LDC2L_POST:
1934e6d15924SDimitry Andric case ARM::STC2_POST:
1935e6d15924SDimitry Andric case ARM::STC2L_POST:
1936e6d15924SDimitry Andric if (coproc == 0xA || coproc == 0xB ||
1937e6d15924SDimitry Andric (featureBits[ARM::HasV8_1MMainlineOps] &&
1938e6d15924SDimitry Andric (coproc == 0x8 || coproc == 0x9 || coproc == 0xA || coproc == 0xB ||
1939e6d15924SDimitry Andric coproc == 0xE || coproc == 0xF)))
194030815c53SDimitry Andric return MCDisassembler::Fail;
194130815c53SDimitry Andric break;
194230815c53SDimitry Andric default:
194330815c53SDimitry Andric break;
194430815c53SDimitry Andric }
194530815c53SDimitry Andric
19465a5ac124SDimitry Andric if (featureBits[ARM::HasV8Ops] && (coproc != 14))
1947f8af5cf6SDimitry Andric return MCDisassembler::Fail;
1948f8af5cf6SDimitry Andric
19495a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(coproc));
19505a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(CRd));
195130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
195230815c53SDimitry Andric return MCDisassembler::Fail;
195330815c53SDimitry Andric
195430815c53SDimitry Andric switch (Inst.getOpcode()) {
195530815c53SDimitry Andric case ARM::t2LDC2_OFFSET:
195630815c53SDimitry Andric case ARM::t2LDC2L_OFFSET:
195730815c53SDimitry Andric case ARM::t2LDC2_PRE:
195830815c53SDimitry Andric case ARM::t2LDC2L_PRE:
195930815c53SDimitry Andric case ARM::t2STC2_OFFSET:
196030815c53SDimitry Andric case ARM::t2STC2L_OFFSET:
196130815c53SDimitry Andric case ARM::t2STC2_PRE:
196230815c53SDimitry Andric case ARM::t2STC2L_PRE:
196330815c53SDimitry Andric case ARM::LDC2_OFFSET:
196430815c53SDimitry Andric case ARM::LDC2L_OFFSET:
196530815c53SDimitry Andric case ARM::LDC2_PRE:
196630815c53SDimitry Andric case ARM::LDC2L_PRE:
196730815c53SDimitry Andric case ARM::STC2_OFFSET:
196830815c53SDimitry Andric case ARM::STC2L_OFFSET:
196930815c53SDimitry Andric case ARM::STC2_PRE:
197030815c53SDimitry Andric case ARM::STC2L_PRE:
197130815c53SDimitry Andric case ARM::t2LDC_OFFSET:
197230815c53SDimitry Andric case ARM::t2LDCL_OFFSET:
197330815c53SDimitry Andric case ARM::t2LDC_PRE:
197430815c53SDimitry Andric case ARM::t2LDCL_PRE:
197530815c53SDimitry Andric case ARM::t2STC_OFFSET:
197630815c53SDimitry Andric case ARM::t2STCL_OFFSET:
197730815c53SDimitry Andric case ARM::t2STC_PRE:
197830815c53SDimitry Andric case ARM::t2STCL_PRE:
197930815c53SDimitry Andric case ARM::LDC_OFFSET:
198030815c53SDimitry Andric case ARM::LDCL_OFFSET:
198130815c53SDimitry Andric case ARM::LDC_PRE:
198230815c53SDimitry Andric case ARM::LDCL_PRE:
198330815c53SDimitry Andric case ARM::STC_OFFSET:
198430815c53SDimitry Andric case ARM::STCL_OFFSET:
198530815c53SDimitry Andric case ARM::STC_PRE:
198630815c53SDimitry Andric case ARM::STCL_PRE:
198730815c53SDimitry Andric imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
19885a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
198930815c53SDimitry Andric break;
199030815c53SDimitry Andric case ARM::t2LDC2_POST:
199130815c53SDimitry Andric case ARM::t2LDC2L_POST:
199230815c53SDimitry Andric case ARM::t2STC2_POST:
199330815c53SDimitry Andric case ARM::t2STC2L_POST:
199430815c53SDimitry Andric case ARM::LDC2_POST:
199530815c53SDimitry Andric case ARM::LDC2L_POST:
199630815c53SDimitry Andric case ARM::STC2_POST:
199730815c53SDimitry Andric case ARM::STC2L_POST:
199830815c53SDimitry Andric case ARM::t2LDC_POST:
199930815c53SDimitry Andric case ARM::t2LDCL_POST:
200030815c53SDimitry Andric case ARM::t2STC_POST:
200130815c53SDimitry Andric case ARM::t2STCL_POST:
200230815c53SDimitry Andric case ARM::LDC_POST:
200330815c53SDimitry Andric case ARM::LDCL_POST:
200430815c53SDimitry Andric case ARM::STC_POST:
200530815c53SDimitry Andric case ARM::STCL_POST:
200630815c53SDimitry Andric imm |= U << 8;
2007e3b55780SDimitry Andric [[fallthrough]];
200830815c53SDimitry Andric default:
200930815c53SDimitry Andric // The 'option' variant doesn't encode 'U' in the immediate since
201030815c53SDimitry Andric // the immediate is unsigned [0,255].
20115a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
201230815c53SDimitry Andric break;
201330815c53SDimitry Andric }
201430815c53SDimitry Andric
201530815c53SDimitry Andric switch (Inst.getOpcode()) {
201630815c53SDimitry Andric case ARM::LDC_OFFSET:
201730815c53SDimitry Andric case ARM::LDC_PRE:
201830815c53SDimitry Andric case ARM::LDC_POST:
201930815c53SDimitry Andric case ARM::LDC_OPTION:
202030815c53SDimitry Andric case ARM::LDCL_OFFSET:
202130815c53SDimitry Andric case ARM::LDCL_PRE:
202230815c53SDimitry Andric case ARM::LDCL_POST:
202330815c53SDimitry Andric case ARM::LDCL_OPTION:
202430815c53SDimitry Andric case ARM::STC_OFFSET:
202530815c53SDimitry Andric case ARM::STC_PRE:
202630815c53SDimitry Andric case ARM::STC_POST:
202730815c53SDimitry Andric case ARM::STC_OPTION:
202830815c53SDimitry Andric case ARM::STCL_OFFSET:
202930815c53SDimitry Andric case ARM::STCL_PRE:
203030815c53SDimitry Andric case ARM::STCL_POST:
203130815c53SDimitry Andric case ARM::STCL_OPTION:
203230815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
203330815c53SDimitry Andric return MCDisassembler::Fail;
203430815c53SDimitry Andric break;
203530815c53SDimitry Andric default:
203630815c53SDimitry Andric break;
203730815c53SDimitry Andric }
203830815c53SDimitry Andric
203930815c53SDimitry Andric return S;
204030815c53SDimitry Andric }
204130815c53SDimitry Andric
204230815c53SDimitry Andric static DecodeStatus
DecodeAddrMode2IdxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2043145449b1SDimitry Andric DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
2044145449b1SDimitry Andric const MCDisassembler *Decoder) {
204530815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
204630815c53SDimitry Andric
2047902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2048902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
2049902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2050902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 12);
2051902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
2052902a7b52SDimitry Andric unsigned reg = fieldFromInstruction(Insn, 25, 1);
2053902a7b52SDimitry Andric unsigned P = fieldFromInstruction(Insn, 24, 1);
2054902a7b52SDimitry Andric unsigned W = fieldFromInstruction(Insn, 21, 1);
205530815c53SDimitry Andric
205630815c53SDimitry Andric // On stores, the writeback operand precedes Rt.
205730815c53SDimitry Andric switch (Inst.getOpcode()) {
205830815c53SDimitry Andric case ARM::STR_POST_IMM:
205930815c53SDimitry Andric case ARM::STR_POST_REG:
206030815c53SDimitry Andric case ARM::STRB_POST_IMM:
206130815c53SDimitry Andric case ARM::STRB_POST_REG:
206230815c53SDimitry Andric case ARM::STRT_POST_REG:
206330815c53SDimitry Andric case ARM::STRT_POST_IMM:
206430815c53SDimitry Andric case ARM::STRBT_POST_REG:
206530815c53SDimitry Andric case ARM::STRBT_POST_IMM:
206630815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
206730815c53SDimitry Andric return MCDisassembler::Fail;
206830815c53SDimitry Andric break;
206930815c53SDimitry Andric default:
207030815c53SDimitry Andric break;
207130815c53SDimitry Andric }
207230815c53SDimitry Andric
207330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
207430815c53SDimitry Andric return MCDisassembler::Fail;
207530815c53SDimitry Andric
207630815c53SDimitry Andric // On loads, the writeback operand comes after Rt.
207730815c53SDimitry Andric switch (Inst.getOpcode()) {
207830815c53SDimitry Andric case ARM::LDR_POST_IMM:
207930815c53SDimitry Andric case ARM::LDR_POST_REG:
208030815c53SDimitry Andric case ARM::LDRB_POST_IMM:
208130815c53SDimitry Andric case ARM::LDRB_POST_REG:
208230815c53SDimitry Andric case ARM::LDRBT_POST_REG:
208330815c53SDimitry Andric case ARM::LDRBT_POST_IMM:
208430815c53SDimitry Andric case ARM::LDRT_POST_REG:
208530815c53SDimitry Andric case ARM::LDRT_POST_IMM:
208630815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
208730815c53SDimitry Andric return MCDisassembler::Fail;
208830815c53SDimitry Andric break;
208930815c53SDimitry Andric default:
209030815c53SDimitry Andric break;
209130815c53SDimitry Andric }
209230815c53SDimitry Andric
209330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
209430815c53SDimitry Andric return MCDisassembler::Fail;
209530815c53SDimitry Andric
209630815c53SDimitry Andric ARM_AM::AddrOpc Op = ARM_AM::add;
2097902a7b52SDimitry Andric if (!fieldFromInstruction(Insn, 23, 1))
209830815c53SDimitry Andric Op = ARM_AM::sub;
209930815c53SDimitry Andric
210030815c53SDimitry Andric bool writeback = (P == 0) || (W == 1);
210130815c53SDimitry Andric unsigned idx_mode = 0;
210230815c53SDimitry Andric if (P && writeback)
210330815c53SDimitry Andric idx_mode = ARMII::IndexModePre;
210430815c53SDimitry Andric else if (!P && writeback)
210530815c53SDimitry Andric idx_mode = ARMII::IndexModePost;
210630815c53SDimitry Andric
210730815c53SDimitry Andric if (writeback && (Rn == 15 || Rn == Rt))
210830815c53SDimitry Andric S = MCDisassembler::SoftFail; // UNPREDICTABLE
210930815c53SDimitry Andric
211030815c53SDimitry Andric if (reg) {
211130815c53SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
211230815c53SDimitry Andric return MCDisassembler::Fail;
211330815c53SDimitry Andric ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
2114902a7b52SDimitry Andric switch( fieldFromInstruction(Insn, 5, 2)) {
211530815c53SDimitry Andric case 0:
211630815c53SDimitry Andric Opc = ARM_AM::lsl;
211730815c53SDimitry Andric break;
211830815c53SDimitry Andric case 1:
211930815c53SDimitry Andric Opc = ARM_AM::lsr;
212030815c53SDimitry Andric break;
212130815c53SDimitry Andric case 2:
212230815c53SDimitry Andric Opc = ARM_AM::asr;
212330815c53SDimitry Andric break;
212430815c53SDimitry Andric case 3:
212530815c53SDimitry Andric Opc = ARM_AM::ror;
212630815c53SDimitry Andric break;
212730815c53SDimitry Andric default:
212830815c53SDimitry Andric return MCDisassembler::Fail;
212930815c53SDimitry Andric }
2130902a7b52SDimitry Andric unsigned amt = fieldFromInstruction(Insn, 7, 5);
2131522600a2SDimitry Andric if (Opc == ARM_AM::ror && amt == 0)
2132522600a2SDimitry Andric Opc = ARM_AM::rrx;
213330815c53SDimitry Andric unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
213430815c53SDimitry Andric
21355a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
213630815c53SDimitry Andric } else {
21375a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
213830815c53SDimitry Andric unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
21395a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(tmp));
214030815c53SDimitry Andric }
214130815c53SDimitry Andric
214230815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
214330815c53SDimitry Andric return MCDisassembler::Fail;
214430815c53SDimitry Andric
214530815c53SDimitry Andric return S;
214630815c53SDimitry Andric }
214730815c53SDimitry Andric
DecodeSORegMemOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)214863faed5bSDimitry Andric static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
2149145449b1SDimitry Andric uint64_t Address,
2150145449b1SDimitry Andric const MCDisassembler *Decoder) {
215130815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
215230815c53SDimitry Andric
2153902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 13, 4);
2154902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Val, 0, 4);
2155902a7b52SDimitry Andric unsigned type = fieldFromInstruction(Val, 5, 2);
2156902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 7, 5);
2157902a7b52SDimitry Andric unsigned U = fieldFromInstruction(Val, 12, 1);
215830815c53SDimitry Andric
215930815c53SDimitry Andric ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
216030815c53SDimitry Andric switch (type) {
216130815c53SDimitry Andric case 0:
216230815c53SDimitry Andric ShOp = ARM_AM::lsl;
216330815c53SDimitry Andric break;
216430815c53SDimitry Andric case 1:
216530815c53SDimitry Andric ShOp = ARM_AM::lsr;
216630815c53SDimitry Andric break;
216730815c53SDimitry Andric case 2:
216830815c53SDimitry Andric ShOp = ARM_AM::asr;
216930815c53SDimitry Andric break;
217030815c53SDimitry Andric case 3:
217130815c53SDimitry Andric ShOp = ARM_AM::ror;
217230815c53SDimitry Andric break;
217330815c53SDimitry Andric }
217430815c53SDimitry Andric
2175522600a2SDimitry Andric if (ShOp == ARM_AM::ror && imm == 0)
2176522600a2SDimitry Andric ShOp = ARM_AM::rrx;
2177522600a2SDimitry Andric
217830815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
217930815c53SDimitry Andric return MCDisassembler::Fail;
218030815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
218130815c53SDimitry Andric return MCDisassembler::Fail;
218230815c53SDimitry Andric unsigned shift;
218330815c53SDimitry Andric if (U)
218430815c53SDimitry Andric shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
218530815c53SDimitry Andric else
218630815c53SDimitry Andric shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
21875a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(shift));
218830815c53SDimitry Andric
218930815c53SDimitry Andric return S;
219030815c53SDimitry Andric }
219130815c53SDimitry Andric
DecodeTSBInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2192145449b1SDimitry Andric static DecodeStatus DecodeTSBInstruction(MCInst &Inst, unsigned Insn,
2193145449b1SDimitry Andric uint64_t Address,
2194145449b1SDimitry Andric const MCDisassembler *Decoder) {
2195145449b1SDimitry Andric if (Inst.getOpcode() != ARM::TSB && Inst.getOpcode() != ARM::t2TSB)
2196145449b1SDimitry Andric return MCDisassembler::Fail;
2197145449b1SDimitry Andric
2198145449b1SDimitry Andric // The "csync" operand is not encoded into the "tsb" instruction (as this is
2199145449b1SDimitry Andric // the only available operand), but LLVM expects the instruction to have one
2200145449b1SDimitry Andric // operand, so we need to add the csync when decoding.
2201145449b1SDimitry Andric Inst.addOperand(MCOperand::createImm(ARM_TSB::CSYNC));
2202145449b1SDimitry Andric return MCDisassembler::Success;
2203145449b1SDimitry Andric }
2204145449b1SDimitry Andric
DecodeAddrMode3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2205145449b1SDimitry Andric static DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
2206145449b1SDimitry Andric uint64_t Address,
2207145449b1SDimitry Andric const MCDisassembler *Decoder) {
220830815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
220930815c53SDimitry Andric
2210902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
2211902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2212902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2213902a7b52SDimitry Andric unsigned type = fieldFromInstruction(Insn, 22, 1);
2214902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 8, 4);
2215902a7b52SDimitry Andric unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
2216902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
2217902a7b52SDimitry Andric unsigned W = fieldFromInstruction(Insn, 21, 1);
2218902a7b52SDimitry Andric unsigned P = fieldFromInstruction(Insn, 24, 1);
221963faed5bSDimitry Andric unsigned Rt2 = Rt + 1;
222030815c53SDimitry Andric
222130815c53SDimitry Andric bool writeback = (W == 1) | (P == 0);
222230815c53SDimitry Andric
222330815c53SDimitry Andric // For {LD,ST}RD, Rt must be even, else undefined.
222430815c53SDimitry Andric switch (Inst.getOpcode()) {
222530815c53SDimitry Andric case ARM::STRD:
222630815c53SDimitry Andric case ARM::STRD_PRE:
222730815c53SDimitry Andric case ARM::STRD_POST:
222830815c53SDimitry Andric case ARM::LDRD:
222930815c53SDimitry Andric case ARM::LDRD_PRE:
223030815c53SDimitry Andric case ARM::LDRD_POST:
223163faed5bSDimitry Andric if (Rt & 0x1) S = MCDisassembler::SoftFail;
223263faed5bSDimitry Andric break;
223363faed5bSDimitry Andric default:
223463faed5bSDimitry Andric break;
223563faed5bSDimitry Andric }
223663faed5bSDimitry Andric switch (Inst.getOpcode()) {
223763faed5bSDimitry Andric case ARM::STRD:
223863faed5bSDimitry Andric case ARM::STRD_PRE:
223963faed5bSDimitry Andric case ARM::STRD_POST:
224063faed5bSDimitry Andric if (P == 0 && W == 1)
224163faed5bSDimitry Andric S = MCDisassembler::SoftFail;
224263faed5bSDimitry Andric
224363faed5bSDimitry Andric if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
224463faed5bSDimitry Andric S = MCDisassembler::SoftFail;
224563faed5bSDimitry Andric if (type && Rm == 15)
224663faed5bSDimitry Andric S = MCDisassembler::SoftFail;
224763faed5bSDimitry Andric if (Rt2 == 15)
224863faed5bSDimitry Andric S = MCDisassembler::SoftFail;
2249902a7b52SDimitry Andric if (!type && fieldFromInstruction(Insn, 8, 4))
225063faed5bSDimitry Andric S = MCDisassembler::SoftFail;
225163faed5bSDimitry Andric break;
225263faed5bSDimitry Andric case ARM::STRH:
225363faed5bSDimitry Andric case ARM::STRH_PRE:
225463faed5bSDimitry Andric case ARM::STRH_POST:
225563faed5bSDimitry Andric if (Rt == 15)
225663faed5bSDimitry Andric S = MCDisassembler::SoftFail;
225763faed5bSDimitry Andric if (writeback && (Rn == 15 || Rn == Rt))
225863faed5bSDimitry Andric S = MCDisassembler::SoftFail;
225963faed5bSDimitry Andric if (!type && Rm == 15)
226063faed5bSDimitry Andric S = MCDisassembler::SoftFail;
226163faed5bSDimitry Andric break;
226263faed5bSDimitry Andric case ARM::LDRD:
226363faed5bSDimitry Andric case ARM::LDRD_PRE:
226463faed5bSDimitry Andric case ARM::LDRD_POST:
226563faed5bSDimitry Andric if (type && Rn == 15) {
226663faed5bSDimitry Andric if (Rt2 == 15)
226763faed5bSDimitry Andric S = MCDisassembler::SoftFail;
226863faed5bSDimitry Andric break;
226963faed5bSDimitry Andric }
227063faed5bSDimitry Andric if (P == 0 && W == 1)
227163faed5bSDimitry Andric S = MCDisassembler::SoftFail;
227263faed5bSDimitry Andric if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
227363faed5bSDimitry Andric S = MCDisassembler::SoftFail;
227463faed5bSDimitry Andric if (!type && writeback && Rn == 15)
227563faed5bSDimitry Andric S = MCDisassembler::SoftFail;
227663faed5bSDimitry Andric if (writeback && (Rn == Rt || Rn == Rt2))
227763faed5bSDimitry Andric S = MCDisassembler::SoftFail;
227863faed5bSDimitry Andric break;
227963faed5bSDimitry Andric case ARM::LDRH:
228063faed5bSDimitry Andric case ARM::LDRH_PRE:
228163faed5bSDimitry Andric case ARM::LDRH_POST:
228263faed5bSDimitry Andric if (type && Rn == 15) {
228363faed5bSDimitry Andric if (Rt == 15)
228463faed5bSDimitry Andric S = MCDisassembler::SoftFail;
228563faed5bSDimitry Andric break;
228663faed5bSDimitry Andric }
228763faed5bSDimitry Andric if (Rt == 15)
228863faed5bSDimitry Andric S = MCDisassembler::SoftFail;
228963faed5bSDimitry Andric if (!type && Rm == 15)
229063faed5bSDimitry Andric S = MCDisassembler::SoftFail;
229163faed5bSDimitry Andric if (!type && writeback && (Rn == 15 || Rn == Rt))
229263faed5bSDimitry Andric S = MCDisassembler::SoftFail;
229363faed5bSDimitry Andric break;
229463faed5bSDimitry Andric case ARM::LDRSH:
229563faed5bSDimitry Andric case ARM::LDRSH_PRE:
229663faed5bSDimitry Andric case ARM::LDRSH_POST:
229763faed5bSDimitry Andric case ARM::LDRSB:
229863faed5bSDimitry Andric case ARM::LDRSB_PRE:
229963faed5bSDimitry Andric case ARM::LDRSB_POST:
230063faed5bSDimitry Andric if (type && Rn == 15) {
230163faed5bSDimitry Andric if (Rt == 15)
230263faed5bSDimitry Andric S = MCDisassembler::SoftFail;
230363faed5bSDimitry Andric break;
230463faed5bSDimitry Andric }
230563faed5bSDimitry Andric if (type && (Rt == 15 || (writeback && Rn == Rt)))
230663faed5bSDimitry Andric S = MCDisassembler::SoftFail;
230763faed5bSDimitry Andric if (!type && (Rt == 15 || Rm == 15))
230863faed5bSDimitry Andric S = MCDisassembler::SoftFail;
230963faed5bSDimitry Andric if (!type && writeback && (Rn == 15 || Rn == Rt))
231063faed5bSDimitry Andric S = MCDisassembler::SoftFail;
231130815c53SDimitry Andric break;
231230815c53SDimitry Andric default:
231330815c53SDimitry Andric break;
231430815c53SDimitry Andric }
231530815c53SDimitry Andric
231630815c53SDimitry Andric if (writeback) { // Writeback
231730815c53SDimitry Andric if (P)
231830815c53SDimitry Andric U |= ARMII::IndexModePre << 9;
231930815c53SDimitry Andric else
232030815c53SDimitry Andric U |= ARMII::IndexModePost << 9;
232130815c53SDimitry Andric
232230815c53SDimitry Andric // On stores, the writeback operand precedes Rt.
232330815c53SDimitry Andric switch (Inst.getOpcode()) {
232430815c53SDimitry Andric case ARM::STRD:
232530815c53SDimitry Andric case ARM::STRD_PRE:
232630815c53SDimitry Andric case ARM::STRD_POST:
232730815c53SDimitry Andric case ARM::STRH:
232830815c53SDimitry Andric case ARM::STRH_PRE:
232930815c53SDimitry Andric case ARM::STRH_POST:
233030815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
233130815c53SDimitry Andric return MCDisassembler::Fail;
233230815c53SDimitry Andric break;
233330815c53SDimitry Andric default:
233430815c53SDimitry Andric break;
233530815c53SDimitry Andric }
233630815c53SDimitry Andric }
233730815c53SDimitry Andric
233830815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
233930815c53SDimitry Andric return MCDisassembler::Fail;
234030815c53SDimitry Andric switch (Inst.getOpcode()) {
234130815c53SDimitry Andric case ARM::STRD:
234230815c53SDimitry Andric case ARM::STRD_PRE:
234330815c53SDimitry Andric case ARM::STRD_POST:
234430815c53SDimitry Andric case ARM::LDRD:
234530815c53SDimitry Andric case ARM::LDRD_PRE:
234630815c53SDimitry Andric case ARM::LDRD_POST:
234730815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
234830815c53SDimitry Andric return MCDisassembler::Fail;
234930815c53SDimitry Andric break;
235030815c53SDimitry Andric default:
235130815c53SDimitry Andric break;
235230815c53SDimitry Andric }
235330815c53SDimitry Andric
235430815c53SDimitry Andric if (writeback) {
235530815c53SDimitry Andric // On loads, the writeback operand comes after Rt.
235630815c53SDimitry Andric switch (Inst.getOpcode()) {
235730815c53SDimitry Andric case ARM::LDRD:
235830815c53SDimitry Andric case ARM::LDRD_PRE:
235930815c53SDimitry Andric case ARM::LDRD_POST:
236030815c53SDimitry Andric case ARM::LDRH:
236130815c53SDimitry Andric case ARM::LDRH_PRE:
236230815c53SDimitry Andric case ARM::LDRH_POST:
236330815c53SDimitry Andric case ARM::LDRSH:
236430815c53SDimitry Andric case ARM::LDRSH_PRE:
236530815c53SDimitry Andric case ARM::LDRSH_POST:
236630815c53SDimitry Andric case ARM::LDRSB:
236730815c53SDimitry Andric case ARM::LDRSB_PRE:
236830815c53SDimitry Andric case ARM::LDRSB_POST:
236930815c53SDimitry Andric case ARM::LDRHTr:
237030815c53SDimitry Andric case ARM::LDRSBTr:
237130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
237230815c53SDimitry Andric return MCDisassembler::Fail;
237330815c53SDimitry Andric break;
237430815c53SDimitry Andric default:
237530815c53SDimitry Andric break;
237630815c53SDimitry Andric }
237730815c53SDimitry Andric }
237830815c53SDimitry Andric
237930815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
238030815c53SDimitry Andric return MCDisassembler::Fail;
238130815c53SDimitry Andric
238230815c53SDimitry Andric if (type) {
23835a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
23845a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(U | (imm << 4) | Rm));
238530815c53SDimitry Andric } else {
238630815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
238730815c53SDimitry Andric return MCDisassembler::Fail;
23885a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(U));
238930815c53SDimitry Andric }
239030815c53SDimitry Andric
239130815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
239230815c53SDimitry Andric return MCDisassembler::Fail;
239330815c53SDimitry Andric
239430815c53SDimitry Andric return S;
239530815c53SDimitry Andric }
239630815c53SDimitry Andric
DecodeRFEInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)239763faed5bSDimitry Andric static DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
2398145449b1SDimitry Andric uint64_t Address,
2399145449b1SDimitry Andric const MCDisassembler *Decoder) {
240030815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
240130815c53SDimitry Andric
2402902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2403902a7b52SDimitry Andric unsigned mode = fieldFromInstruction(Insn, 23, 2);
240430815c53SDimitry Andric
240530815c53SDimitry Andric switch (mode) {
240630815c53SDimitry Andric case 0:
240730815c53SDimitry Andric mode = ARM_AM::da;
240830815c53SDimitry Andric break;
240930815c53SDimitry Andric case 1:
241030815c53SDimitry Andric mode = ARM_AM::ia;
241130815c53SDimitry Andric break;
241230815c53SDimitry Andric case 2:
241330815c53SDimitry Andric mode = ARM_AM::db;
241430815c53SDimitry Andric break;
241530815c53SDimitry Andric case 3:
241630815c53SDimitry Andric mode = ARM_AM::ib;
241730815c53SDimitry Andric break;
241830815c53SDimitry Andric }
241930815c53SDimitry Andric
24205a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(mode));
242130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
242230815c53SDimitry Andric return MCDisassembler::Fail;
242330815c53SDimitry Andric
242430815c53SDimitry Andric return S;
242530815c53SDimitry Andric }
242630815c53SDimitry Andric
DecodeQADDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2427f8af5cf6SDimitry Andric static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
2428145449b1SDimitry Andric uint64_t Address,
2429145449b1SDimitry Andric const MCDisassembler *Decoder) {
2430f8af5cf6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
2431f8af5cf6SDimitry Andric
2432f8af5cf6SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2433f8af5cf6SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2434f8af5cf6SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2435f8af5cf6SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
2436f8af5cf6SDimitry Andric
2437f8af5cf6SDimitry Andric if (pred == 0xF)
2438f8af5cf6SDimitry Andric return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
2439f8af5cf6SDimitry Andric
2440f8af5cf6SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2441f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2442f8af5cf6SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
2443f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2444f8af5cf6SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2445f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2446f8af5cf6SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2447f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2448f8af5cf6SDimitry Andric return S;
2449f8af5cf6SDimitry Andric }
2450f8af5cf6SDimitry Andric
2451145449b1SDimitry Andric static DecodeStatus
DecodeMemMultipleWritebackInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2452145449b1SDimitry Andric DecodeMemMultipleWritebackInstruction(MCInst &Inst, unsigned Insn,
2453145449b1SDimitry Andric uint64_t Address,
2454145449b1SDimitry Andric const MCDisassembler *Decoder) {
245530815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
245630815c53SDimitry Andric
2457902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2458902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
2459902a7b52SDimitry Andric unsigned reglist = fieldFromInstruction(Insn, 0, 16);
246030815c53SDimitry Andric
246130815c53SDimitry Andric if (pred == 0xF) {
2462f8af5cf6SDimitry Andric // Ambiguous with RFE and SRS
246330815c53SDimitry Andric switch (Inst.getOpcode()) {
246430815c53SDimitry Andric case ARM::LDMDA:
246530815c53SDimitry Andric Inst.setOpcode(ARM::RFEDA);
246630815c53SDimitry Andric break;
246730815c53SDimitry Andric case ARM::LDMDA_UPD:
246830815c53SDimitry Andric Inst.setOpcode(ARM::RFEDA_UPD);
246930815c53SDimitry Andric break;
247030815c53SDimitry Andric case ARM::LDMDB:
247130815c53SDimitry Andric Inst.setOpcode(ARM::RFEDB);
247230815c53SDimitry Andric break;
247330815c53SDimitry Andric case ARM::LDMDB_UPD:
247430815c53SDimitry Andric Inst.setOpcode(ARM::RFEDB_UPD);
247530815c53SDimitry Andric break;
247630815c53SDimitry Andric case ARM::LDMIA:
247730815c53SDimitry Andric Inst.setOpcode(ARM::RFEIA);
247830815c53SDimitry Andric break;
247930815c53SDimitry Andric case ARM::LDMIA_UPD:
248030815c53SDimitry Andric Inst.setOpcode(ARM::RFEIA_UPD);
248130815c53SDimitry Andric break;
248230815c53SDimitry Andric case ARM::LDMIB:
248330815c53SDimitry Andric Inst.setOpcode(ARM::RFEIB);
248430815c53SDimitry Andric break;
248530815c53SDimitry Andric case ARM::LDMIB_UPD:
248630815c53SDimitry Andric Inst.setOpcode(ARM::RFEIB_UPD);
248730815c53SDimitry Andric break;
248830815c53SDimitry Andric case ARM::STMDA:
248930815c53SDimitry Andric Inst.setOpcode(ARM::SRSDA);
249030815c53SDimitry Andric break;
249130815c53SDimitry Andric case ARM::STMDA_UPD:
249230815c53SDimitry Andric Inst.setOpcode(ARM::SRSDA_UPD);
249330815c53SDimitry Andric break;
249430815c53SDimitry Andric case ARM::STMDB:
249530815c53SDimitry Andric Inst.setOpcode(ARM::SRSDB);
249630815c53SDimitry Andric break;
249730815c53SDimitry Andric case ARM::STMDB_UPD:
249830815c53SDimitry Andric Inst.setOpcode(ARM::SRSDB_UPD);
249930815c53SDimitry Andric break;
250030815c53SDimitry Andric case ARM::STMIA:
250130815c53SDimitry Andric Inst.setOpcode(ARM::SRSIA);
250230815c53SDimitry Andric break;
250330815c53SDimitry Andric case ARM::STMIA_UPD:
250430815c53SDimitry Andric Inst.setOpcode(ARM::SRSIA_UPD);
250530815c53SDimitry Andric break;
250630815c53SDimitry Andric case ARM::STMIB:
250730815c53SDimitry Andric Inst.setOpcode(ARM::SRSIB);
250830815c53SDimitry Andric break;
250930815c53SDimitry Andric case ARM::STMIB_UPD:
251030815c53SDimitry Andric Inst.setOpcode(ARM::SRSIB_UPD);
251130815c53SDimitry Andric break;
251230815c53SDimitry Andric default:
2513f8af5cf6SDimitry Andric return MCDisassembler::Fail;
251430815c53SDimitry Andric }
251530815c53SDimitry Andric
251630815c53SDimitry Andric // For stores (which become SRS's, the only operand is the mode.
2517902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 20, 1) == 0) {
2518f8af5cf6SDimitry Andric // Check SRS encoding constraints
2519f8af5cf6SDimitry Andric if (!(fieldFromInstruction(Insn, 22, 1) == 1 &&
2520f8af5cf6SDimitry Andric fieldFromInstruction(Insn, 20, 1) == 0))
2521f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2522f8af5cf6SDimitry Andric
252330815c53SDimitry Andric Inst.addOperand(
25245a5ac124SDimitry Andric MCOperand::createImm(fieldFromInstruction(Insn, 0, 4)));
252530815c53SDimitry Andric return S;
252630815c53SDimitry Andric }
252730815c53SDimitry Andric
252830815c53SDimitry Andric return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
252930815c53SDimitry Andric }
253030815c53SDimitry Andric
253130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
253230815c53SDimitry Andric return MCDisassembler::Fail;
253330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
253430815c53SDimitry Andric return MCDisassembler::Fail; // Tied
253530815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
253630815c53SDimitry Andric return MCDisassembler::Fail;
253730815c53SDimitry Andric if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
253830815c53SDimitry Andric return MCDisassembler::Fail;
253930815c53SDimitry Andric
254030815c53SDimitry Andric return S;
254130815c53SDimitry Andric }
254230815c53SDimitry Andric
254301095a5dSDimitry Andric // Check for UNPREDICTABLE predicated ESB instruction
DecodeHINTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)254401095a5dSDimitry Andric static DecodeStatus DecodeHINTInstruction(MCInst &Inst, unsigned Insn,
2545145449b1SDimitry Andric uint64_t Address,
2546145449b1SDimitry Andric const MCDisassembler *Decoder) {
254701095a5dSDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
254801095a5dSDimitry Andric unsigned imm8 = fieldFromInstruction(Insn, 0, 8);
254901095a5dSDimitry Andric const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
255001095a5dSDimitry Andric const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
255101095a5dSDimitry Andric
255201095a5dSDimitry Andric DecodeStatus S = MCDisassembler::Success;
255301095a5dSDimitry Andric
255401095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(imm8));
255501095a5dSDimitry Andric
255601095a5dSDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
255701095a5dSDimitry Andric return MCDisassembler::Fail;
255801095a5dSDimitry Andric
255901095a5dSDimitry Andric // ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP,
256001095a5dSDimitry Andric // so all predicates should be allowed.
256101095a5dSDimitry Andric if (imm8 == 0x10 && pred != 0xe && ((FeatureBits[ARM::FeatureRAS]) != 0))
256201095a5dSDimitry Andric S = MCDisassembler::SoftFail;
256301095a5dSDimitry Andric
256401095a5dSDimitry Andric return S;
256501095a5dSDimitry Andric }
256601095a5dSDimitry Andric
DecodeCPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)256763faed5bSDimitry Andric static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
2568145449b1SDimitry Andric uint64_t Address,
2569145449b1SDimitry Andric const MCDisassembler *Decoder) {
2570902a7b52SDimitry Andric unsigned imod = fieldFromInstruction(Insn, 18, 2);
2571902a7b52SDimitry Andric unsigned M = fieldFromInstruction(Insn, 17, 1);
2572902a7b52SDimitry Andric unsigned iflags = fieldFromInstruction(Insn, 6, 3);
2573902a7b52SDimitry Andric unsigned mode = fieldFromInstruction(Insn, 0, 5);
257430815c53SDimitry Andric
257530815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
257630815c53SDimitry Andric
2577f8af5cf6SDimitry Andric // This decoder is called from multiple location that do not check
2578f8af5cf6SDimitry Andric // the full encoding is valid before they do.
2579f8af5cf6SDimitry Andric if (fieldFromInstruction(Insn, 5, 1) != 0 ||
2580f8af5cf6SDimitry Andric fieldFromInstruction(Insn, 16, 1) != 0 ||
2581f8af5cf6SDimitry Andric fieldFromInstruction(Insn, 20, 8) != 0x10)
2582f8af5cf6SDimitry Andric return MCDisassembler::Fail;
2583f8af5cf6SDimitry Andric
258430815c53SDimitry Andric // imod == '01' --> UNPREDICTABLE
258530815c53SDimitry Andric // NOTE: Even though this is technically UNPREDICTABLE, we choose to
258630815c53SDimitry Andric // return failure here. The '01' imod value is unprintable, so there's
258730815c53SDimitry Andric // nothing useful we could do even if we returned UNPREDICTABLE.
258830815c53SDimitry Andric
258930815c53SDimitry Andric if (imod == 1) return MCDisassembler::Fail;
259030815c53SDimitry Andric
259130815c53SDimitry Andric if (imod && M) {
259230815c53SDimitry Andric Inst.setOpcode(ARM::CPS3p);
25935a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imod));
25945a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(iflags));
25955a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(mode));
259630815c53SDimitry Andric } else if (imod && !M) {
259730815c53SDimitry Andric Inst.setOpcode(ARM::CPS2p);
25985a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imod));
25995a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(iflags));
260030815c53SDimitry Andric if (mode) S = MCDisassembler::SoftFail;
260130815c53SDimitry Andric } else if (!imod && M) {
260230815c53SDimitry Andric Inst.setOpcode(ARM::CPS1p);
26035a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(mode));
260430815c53SDimitry Andric if (iflags) S = MCDisassembler::SoftFail;
260530815c53SDimitry Andric } else {
260630815c53SDimitry Andric // imod == '00' && M == '0' --> UNPREDICTABLE
260730815c53SDimitry Andric Inst.setOpcode(ARM::CPS1p);
26085a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(mode));
260930815c53SDimitry Andric S = MCDisassembler::SoftFail;
261030815c53SDimitry Andric }
261130815c53SDimitry Andric
261230815c53SDimitry Andric return S;
261330815c53SDimitry Andric }
261430815c53SDimitry Andric
DecodeT2CPSInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)261563faed5bSDimitry Andric static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
2616145449b1SDimitry Andric uint64_t Address,
2617145449b1SDimitry Andric const MCDisassembler *Decoder) {
2618902a7b52SDimitry Andric unsigned imod = fieldFromInstruction(Insn, 9, 2);
2619902a7b52SDimitry Andric unsigned M = fieldFromInstruction(Insn, 8, 1);
2620902a7b52SDimitry Andric unsigned iflags = fieldFromInstruction(Insn, 5, 3);
2621902a7b52SDimitry Andric unsigned mode = fieldFromInstruction(Insn, 0, 5);
262230815c53SDimitry Andric
262330815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
262430815c53SDimitry Andric
262530815c53SDimitry Andric // imod == '01' --> UNPREDICTABLE
262630815c53SDimitry Andric // NOTE: Even though this is technically UNPREDICTABLE, we choose to
262730815c53SDimitry Andric // return failure here. The '01' imod value is unprintable, so there's
262830815c53SDimitry Andric // nothing useful we could do even if we returned UNPREDICTABLE.
262930815c53SDimitry Andric
263030815c53SDimitry Andric if (imod == 1) return MCDisassembler::Fail;
263130815c53SDimitry Andric
263230815c53SDimitry Andric if (imod && M) {
263330815c53SDimitry Andric Inst.setOpcode(ARM::t2CPS3p);
26345a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imod));
26355a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(iflags));
26365a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(mode));
263730815c53SDimitry Andric } else if (imod && !M) {
263830815c53SDimitry Andric Inst.setOpcode(ARM::t2CPS2p);
26395a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imod));
26405a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(iflags));
264130815c53SDimitry Andric if (mode) S = MCDisassembler::SoftFail;
264230815c53SDimitry Andric } else if (!imod && M) {
264330815c53SDimitry Andric Inst.setOpcode(ARM::t2CPS1p);
26445a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(mode));
264530815c53SDimitry Andric if (iflags) S = MCDisassembler::SoftFail;
264630815c53SDimitry Andric } else {
264759d6cff9SDimitry Andric // imod == '00' && M == '0' --> this is a HINT instruction
264859d6cff9SDimitry Andric int imm = fieldFromInstruction(Insn, 0, 8);
264959d6cff9SDimitry Andric // HINT are defined only for immediate in [0..4]
265059d6cff9SDimitry Andric if(imm > 4) return MCDisassembler::Fail;
265159d6cff9SDimitry Andric Inst.setOpcode(ARM::t2HINT);
26525a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
265330815c53SDimitry Andric }
265430815c53SDimitry Andric
265530815c53SDimitry Andric return S;
265630815c53SDimitry Andric }
265730815c53SDimitry Andric
2658145449b1SDimitry Andric static DecodeStatus
DecodeT2HintSpaceInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2659145449b1SDimitry Andric DecodeT2HintSpaceInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
2660145449b1SDimitry Andric const MCDisassembler *Decoder) {
2661f65dcba8SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 8);
2662f65dcba8SDimitry Andric
2663f65dcba8SDimitry Andric unsigned Opcode = ARM::t2HINT;
2664f65dcba8SDimitry Andric
2665f65dcba8SDimitry Andric if (imm == 0x0D) {
2666f65dcba8SDimitry Andric Opcode = ARM::t2PACBTI;
2667f65dcba8SDimitry Andric } else if (imm == 0x1D) {
2668f65dcba8SDimitry Andric Opcode = ARM::t2PAC;
2669f65dcba8SDimitry Andric } else if (imm == 0x2D) {
2670f65dcba8SDimitry Andric Opcode = ARM::t2AUT;
2671f65dcba8SDimitry Andric } else if (imm == 0x0F) {
2672f65dcba8SDimitry Andric Opcode = ARM::t2BTI;
2673f65dcba8SDimitry Andric }
2674f65dcba8SDimitry Andric
2675f65dcba8SDimitry Andric Inst.setOpcode(Opcode);
2676f65dcba8SDimitry Andric if (Opcode == ARM::t2HINT) {
2677f65dcba8SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
2678f65dcba8SDimitry Andric }
2679f65dcba8SDimitry Andric
2680f65dcba8SDimitry Andric return MCDisassembler::Success;
2681f65dcba8SDimitry Andric }
2682f65dcba8SDimitry Andric
DecodeT2MOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)268363faed5bSDimitry Andric static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
2684145449b1SDimitry Andric uint64_t Address,
2685145449b1SDimitry Andric const MCDisassembler *Decoder) {
268630815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
268730815c53SDimitry Andric
2688902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 8, 4);
268930815c53SDimitry Andric unsigned imm = 0;
269030815c53SDimitry Andric
2691902a7b52SDimitry Andric imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
2692902a7b52SDimitry Andric imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
2693902a7b52SDimitry Andric imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
2694902a7b52SDimitry Andric imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
269530815c53SDimitry Andric
269630815c53SDimitry Andric if (Inst.getOpcode() == ARM::t2MOVTi16)
269730815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
269830815c53SDimitry Andric return MCDisassembler::Fail;
269930815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
270030815c53SDimitry Andric return MCDisassembler::Fail;
270130815c53SDimitry Andric
270230815c53SDimitry Andric if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
27035a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
270430815c53SDimitry Andric
270530815c53SDimitry Andric return S;
270630815c53SDimitry Andric }
270730815c53SDimitry Andric
DecodeArmMOVTWInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)270863faed5bSDimitry Andric static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
2709145449b1SDimitry Andric uint64_t Address,
2710145449b1SDimitry Andric const MCDisassembler *Decoder) {
271130815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
271230815c53SDimitry Andric
2713902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2714902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
271530815c53SDimitry Andric unsigned imm = 0;
271630815c53SDimitry Andric
2717902a7b52SDimitry Andric imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
2718902a7b52SDimitry Andric imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
271930815c53SDimitry Andric
272030815c53SDimitry Andric if (Inst.getOpcode() == ARM::MOVTi16)
272159d6cff9SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
272230815c53SDimitry Andric return MCDisassembler::Fail;
272359d6cff9SDimitry Andric
272459d6cff9SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
272530815c53SDimitry Andric return MCDisassembler::Fail;
272630815c53SDimitry Andric
272730815c53SDimitry Andric if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
27285a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
272930815c53SDimitry Andric
273030815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
273130815c53SDimitry Andric return MCDisassembler::Fail;
273230815c53SDimitry Andric
273330815c53SDimitry Andric return S;
273430815c53SDimitry Andric }
273530815c53SDimitry Andric
DecodeSMLAInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)273663faed5bSDimitry Andric static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
2737145449b1SDimitry Andric uint64_t Address,
2738145449b1SDimitry Andric const MCDisassembler *Decoder) {
273930815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
274030815c53SDimitry Andric
2741902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 16, 4);
2742902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 0, 4);
2743902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 8, 4);
2744902a7b52SDimitry Andric unsigned Ra = fieldFromInstruction(Insn, 12, 4);
2745902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
274630815c53SDimitry Andric
274730815c53SDimitry Andric if (pred == 0xF)
274830815c53SDimitry Andric return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
274930815c53SDimitry Andric
275030815c53SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
275130815c53SDimitry Andric return MCDisassembler::Fail;
275230815c53SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
275330815c53SDimitry Andric return MCDisassembler::Fail;
275430815c53SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
275530815c53SDimitry Andric return MCDisassembler::Fail;
275630815c53SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
275730815c53SDimitry Andric return MCDisassembler::Fail;
275830815c53SDimitry Andric
275930815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
276030815c53SDimitry Andric return MCDisassembler::Fail;
276130815c53SDimitry Andric
276230815c53SDimitry Andric return S;
276330815c53SDimitry Andric }
276430815c53SDimitry Andric
DecodeTSTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)27655a5ac124SDimitry Andric static DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
2766145449b1SDimitry Andric uint64_t Address,
2767145449b1SDimitry Andric const MCDisassembler *Decoder) {
27685a5ac124SDimitry Andric DecodeStatus S = MCDisassembler::Success;
27695a5ac124SDimitry Andric
27705a5ac124SDimitry Andric unsigned Pred = fieldFromInstruction(Insn, 28, 4);
27715a5ac124SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
27725a5ac124SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
27735a5ac124SDimitry Andric
27745a5ac124SDimitry Andric if (Pred == 0xF)
27755a5ac124SDimitry Andric return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
27765a5ac124SDimitry Andric
27775a5ac124SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
27785a5ac124SDimitry Andric return MCDisassembler::Fail;
27795a5ac124SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
27805a5ac124SDimitry Andric return MCDisassembler::Fail;
27815a5ac124SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
27825a5ac124SDimitry Andric return MCDisassembler::Fail;
27835a5ac124SDimitry Andric
27845a5ac124SDimitry Andric return S;
27855a5ac124SDimitry Andric }
27865a5ac124SDimitry Andric
DecodeSETPANInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)27875a5ac124SDimitry Andric static DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
2788145449b1SDimitry Andric uint64_t Address,
2789145449b1SDimitry Andric const MCDisassembler *Decoder) {
27905a5ac124SDimitry Andric DecodeStatus S = MCDisassembler::Success;
27915a5ac124SDimitry Andric
27925a5ac124SDimitry Andric unsigned Imm = fieldFromInstruction(Insn, 9, 1);
27935a5ac124SDimitry Andric
27945a5ac124SDimitry Andric const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
27955a5ac124SDimitry Andric const FeatureBitset &FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
27965a5ac124SDimitry Andric
27975a5ac124SDimitry Andric if (!FeatureBits[ARM::HasV8_1aOps] ||
27985a5ac124SDimitry Andric !FeatureBits[ARM::HasV8Ops])
27995a5ac124SDimitry Andric return MCDisassembler::Fail;
28005a5ac124SDimitry Andric
28015a5ac124SDimitry Andric // Decoder can be called from DecodeTST, which does not check the full
28025a5ac124SDimitry Andric // encoding is valid.
28035a5ac124SDimitry Andric if (fieldFromInstruction(Insn, 20,12) != 0xf11 ||
28045a5ac124SDimitry Andric fieldFromInstruction(Insn, 4,4) != 0)
28055a5ac124SDimitry Andric return MCDisassembler::Fail;
28065a5ac124SDimitry Andric if (fieldFromInstruction(Insn, 10,10) != 0 ||
28075a5ac124SDimitry Andric fieldFromInstruction(Insn, 0,4) != 0)
28085a5ac124SDimitry Andric S = MCDisassembler::SoftFail;
28095a5ac124SDimitry Andric
28105a5ac124SDimitry Andric Inst.setOpcode(ARM::SETPAN);
28115a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm));
28125a5ac124SDimitry Andric
28135a5ac124SDimitry Andric return S;
28145a5ac124SDimitry Andric }
28155a5ac124SDimitry Andric
DecodeAddrModeImm12Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)281663faed5bSDimitry Andric static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
2817145449b1SDimitry Andric uint64_t Address,
2818145449b1SDimitry Andric const MCDisassembler *Decoder) {
281930815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
282030815c53SDimitry Andric
2821902a7b52SDimitry Andric unsigned add = fieldFromInstruction(Val, 12, 1);
2822902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 12);
2823902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 13, 4);
282430815c53SDimitry Andric
282530815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
282630815c53SDimitry Andric return MCDisassembler::Fail;
282730815c53SDimitry Andric
282830815c53SDimitry Andric if (!add) imm *= -1;
282930815c53SDimitry Andric if (imm == 0 && !add) imm = INT32_MIN;
28305a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
283130815c53SDimitry Andric if (Rn == 15)
283230815c53SDimitry Andric tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
283330815c53SDimitry Andric
283430815c53SDimitry Andric return S;
283530815c53SDimitry Andric }
283630815c53SDimitry Andric
DecodeAddrMode5Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)283763faed5bSDimitry Andric static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
2838145449b1SDimitry Andric uint64_t Address,
2839145449b1SDimitry Andric const MCDisassembler *Decoder) {
284030815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
284130815c53SDimitry Andric
2842902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 9, 4);
284301095a5dSDimitry Andric // U == 1 to add imm, 0 to subtract it.
2844902a7b52SDimitry Andric unsigned U = fieldFromInstruction(Val, 8, 1);
2845902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 8);
284630815c53SDimitry Andric
284730815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
284830815c53SDimitry Andric return MCDisassembler::Fail;
284930815c53SDimitry Andric
285030815c53SDimitry Andric if (U)
28515a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
285230815c53SDimitry Andric else
28535a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
285430815c53SDimitry Andric
285530815c53SDimitry Andric return S;
285630815c53SDimitry Andric }
285730815c53SDimitry Andric
DecodeAddrMode5FP16Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)285801095a5dSDimitry Andric static DecodeStatus DecodeAddrMode5FP16Operand(MCInst &Inst, unsigned Val,
2859145449b1SDimitry Andric uint64_t Address,
2860145449b1SDimitry Andric const MCDisassembler *Decoder) {
286101095a5dSDimitry Andric DecodeStatus S = MCDisassembler::Success;
286201095a5dSDimitry Andric
286301095a5dSDimitry Andric unsigned Rn = fieldFromInstruction(Val, 9, 4);
286401095a5dSDimitry Andric // U == 1 to add imm, 0 to subtract it.
286501095a5dSDimitry Andric unsigned U = fieldFromInstruction(Val, 8, 1);
286601095a5dSDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 8);
286701095a5dSDimitry Andric
286801095a5dSDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
286901095a5dSDimitry Andric return MCDisassembler::Fail;
287001095a5dSDimitry Andric
287101095a5dSDimitry Andric if (U)
287201095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::add, imm)));
287301095a5dSDimitry Andric else
287401095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(ARM_AM::getAM5FP16Opc(ARM_AM::sub, imm)));
287501095a5dSDimitry Andric
287601095a5dSDimitry Andric return S;
287701095a5dSDimitry Andric }
287801095a5dSDimitry Andric
DecodeAddrMode7Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)287963faed5bSDimitry Andric static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
2880145449b1SDimitry Andric uint64_t Address,
2881145449b1SDimitry Andric const MCDisassembler *Decoder) {
288230815c53SDimitry Andric return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
288330815c53SDimitry Andric }
288430815c53SDimitry Andric
DecodeT2BInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2885145449b1SDimitry Andric static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2886145449b1SDimitry Andric uint64_t Address,
2887145449b1SDimitry Andric const MCDisassembler *Decoder) {
2888522600a2SDimitry Andric DecodeStatus Status = MCDisassembler::Success;
2889522600a2SDimitry Andric
2890522600a2SDimitry Andric // Note the J1 and J2 values are from the encoded instruction. So here
2891522600a2SDimitry Andric // change them to I1 and I2 values via as documented:
2892522600a2SDimitry Andric // I1 = NOT(J1 EOR S);
2893522600a2SDimitry Andric // I2 = NOT(J2 EOR S);
2894522600a2SDimitry Andric // and build the imm32 with one trailing zero as documented:
2895522600a2SDimitry Andric // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
2896522600a2SDimitry Andric unsigned S = fieldFromInstruction(Insn, 26, 1);
2897522600a2SDimitry Andric unsigned J1 = fieldFromInstruction(Insn, 13, 1);
2898522600a2SDimitry Andric unsigned J2 = fieldFromInstruction(Insn, 11, 1);
2899522600a2SDimitry Andric unsigned I1 = !(J1 ^ S);
2900522600a2SDimitry Andric unsigned I2 = !(J2 ^ S);
2901522600a2SDimitry Andric unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
2902522600a2SDimitry Andric unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
2903522600a2SDimitry Andric unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
2904f8af5cf6SDimitry Andric int imm32 = SignExtend32<25>(tmp << 1);
2905522600a2SDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
290663faed5bSDimitry Andric true, 4, Inst, Decoder))
29075a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm32));
2908522600a2SDimitry Andric
2909522600a2SDimitry Andric return Status;
291063faed5bSDimitry Andric }
291163faed5bSDimitry Andric
DecodeBranchImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)2912145449b1SDimitry Andric static DecodeStatus DecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
2913145449b1SDimitry Andric uint64_t Address,
2914145449b1SDimitry Andric const MCDisassembler *Decoder) {
291530815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
291630815c53SDimitry Andric
2917902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
2918902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
291930815c53SDimitry Andric
292030815c53SDimitry Andric if (pred == 0xF) {
292130815c53SDimitry Andric Inst.setOpcode(ARM::BLXi);
2922902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 24, 1) << 1;
292363faed5bSDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
292463faed5bSDimitry Andric true, 4, Inst, Decoder))
29255a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
292630815c53SDimitry Andric return S;
292730815c53SDimitry Andric }
292830815c53SDimitry Andric
292963faed5bSDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
293063faed5bSDimitry Andric true, 4, Inst, Decoder))
29315a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<26>(imm)));
2932344a3780SDimitry Andric
2933344a3780SDimitry Andric // We already have BL_pred for BL w/ predicate, no need to add addition
2934344a3780SDimitry Andric // predicate opreands for BL
2935344a3780SDimitry Andric if (Inst.getOpcode() != ARM::BL)
293630815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
293730815c53SDimitry Andric return MCDisassembler::Fail;
293830815c53SDimitry Andric
293930815c53SDimitry Andric return S;
294030815c53SDimitry Andric }
294130815c53SDimitry Andric
DecodeAddrMode6Operand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)294263faed5bSDimitry Andric static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
2943145449b1SDimitry Andric uint64_t Address,
2944145449b1SDimitry Andric const MCDisassembler *Decoder) {
294530815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
294630815c53SDimitry Andric
2947902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Val, 0, 4);
2948902a7b52SDimitry Andric unsigned align = fieldFromInstruction(Val, 4, 2);
294930815c53SDimitry Andric
295030815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
295130815c53SDimitry Andric return MCDisassembler::Fail;
295230815c53SDimitry Andric if (!align)
29535a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
295430815c53SDimitry Andric else
29555a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(4 << align));
295630815c53SDimitry Andric
295730815c53SDimitry Andric return S;
295830815c53SDimitry Andric }
295930815c53SDimitry Andric
DecodeVLDInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)296063faed5bSDimitry Andric static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
2961145449b1SDimitry Andric uint64_t Address,
2962145449b1SDimitry Andric const MCDisassembler *Decoder) {
296330815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
296430815c53SDimitry Andric
2965902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2966902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2967902a7b52SDimitry Andric unsigned wb = fieldFromInstruction(Insn, 16, 4);
2968902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2969902a7b52SDimitry Andric Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2970902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
297130815c53SDimitry Andric
297230815c53SDimitry Andric // First output register
297363faed5bSDimitry Andric switch (Inst.getOpcode()) {
297463faed5bSDimitry Andric case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
297563faed5bSDimitry Andric case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
297663faed5bSDimitry Andric case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
297763faed5bSDimitry Andric case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
297863faed5bSDimitry Andric case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
297963faed5bSDimitry Andric case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
298063faed5bSDimitry Andric case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
298163faed5bSDimitry Andric case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
298263faed5bSDimitry Andric case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
298363faed5bSDimitry Andric if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
298463faed5bSDimitry Andric return MCDisassembler::Fail;
298563faed5bSDimitry Andric break;
298663faed5bSDimitry Andric case ARM::VLD2b16:
298763faed5bSDimitry Andric case ARM::VLD2b32:
298863faed5bSDimitry Andric case ARM::VLD2b8:
298963faed5bSDimitry Andric case ARM::VLD2b16wb_fixed:
299063faed5bSDimitry Andric case ARM::VLD2b16wb_register:
299163faed5bSDimitry Andric case ARM::VLD2b32wb_fixed:
299263faed5bSDimitry Andric case ARM::VLD2b32wb_register:
299363faed5bSDimitry Andric case ARM::VLD2b8wb_fixed:
299463faed5bSDimitry Andric case ARM::VLD2b8wb_register:
299563faed5bSDimitry Andric if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
299663faed5bSDimitry Andric return MCDisassembler::Fail;
299763faed5bSDimitry Andric break;
299863faed5bSDimitry Andric default:
299930815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
300030815c53SDimitry Andric return MCDisassembler::Fail;
300163faed5bSDimitry Andric }
300230815c53SDimitry Andric
300330815c53SDimitry Andric // Second output register
300430815c53SDimitry Andric switch (Inst.getOpcode()) {
300530815c53SDimitry Andric case ARM::VLD3d8:
300630815c53SDimitry Andric case ARM::VLD3d16:
300730815c53SDimitry Andric case ARM::VLD3d32:
300830815c53SDimitry Andric case ARM::VLD3d8_UPD:
300930815c53SDimitry Andric case ARM::VLD3d16_UPD:
301030815c53SDimitry Andric case ARM::VLD3d32_UPD:
301130815c53SDimitry Andric case ARM::VLD4d8:
301230815c53SDimitry Andric case ARM::VLD4d16:
301330815c53SDimitry Andric case ARM::VLD4d32:
301430815c53SDimitry Andric case ARM::VLD4d8_UPD:
301530815c53SDimitry Andric case ARM::VLD4d16_UPD:
301630815c53SDimitry Andric case ARM::VLD4d32_UPD:
301730815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
301830815c53SDimitry Andric return MCDisassembler::Fail;
301930815c53SDimitry Andric break;
302030815c53SDimitry Andric case ARM::VLD3q8:
302130815c53SDimitry Andric case ARM::VLD3q16:
302230815c53SDimitry Andric case ARM::VLD3q32:
302330815c53SDimitry Andric case ARM::VLD3q8_UPD:
302430815c53SDimitry Andric case ARM::VLD3q16_UPD:
302530815c53SDimitry Andric case ARM::VLD3q32_UPD:
302630815c53SDimitry Andric case ARM::VLD4q8:
302730815c53SDimitry Andric case ARM::VLD4q16:
302830815c53SDimitry Andric case ARM::VLD4q32:
302930815c53SDimitry Andric case ARM::VLD4q8_UPD:
303030815c53SDimitry Andric case ARM::VLD4q16_UPD:
303130815c53SDimitry Andric case ARM::VLD4q32_UPD:
303230815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
303330815c53SDimitry Andric return MCDisassembler::Fail;
3034c7dac04cSDimitry Andric break;
303530815c53SDimitry Andric default:
303630815c53SDimitry Andric break;
303730815c53SDimitry Andric }
303830815c53SDimitry Andric
303930815c53SDimitry Andric // Third output register
304030815c53SDimitry Andric switch(Inst.getOpcode()) {
304130815c53SDimitry Andric case ARM::VLD3d8:
304230815c53SDimitry Andric case ARM::VLD3d16:
304330815c53SDimitry Andric case ARM::VLD3d32:
304430815c53SDimitry Andric case ARM::VLD3d8_UPD:
304530815c53SDimitry Andric case ARM::VLD3d16_UPD:
304630815c53SDimitry Andric case ARM::VLD3d32_UPD:
304730815c53SDimitry Andric case ARM::VLD4d8:
304830815c53SDimitry Andric case ARM::VLD4d16:
304930815c53SDimitry Andric case ARM::VLD4d32:
305030815c53SDimitry Andric case ARM::VLD4d8_UPD:
305130815c53SDimitry Andric case ARM::VLD4d16_UPD:
305230815c53SDimitry Andric case ARM::VLD4d32_UPD:
305330815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
305430815c53SDimitry Andric return MCDisassembler::Fail;
305530815c53SDimitry Andric break;
305630815c53SDimitry Andric case ARM::VLD3q8:
305730815c53SDimitry Andric case ARM::VLD3q16:
305830815c53SDimitry Andric case ARM::VLD3q32:
305930815c53SDimitry Andric case ARM::VLD3q8_UPD:
306030815c53SDimitry Andric case ARM::VLD3q16_UPD:
306130815c53SDimitry Andric case ARM::VLD3q32_UPD:
306230815c53SDimitry Andric case ARM::VLD4q8:
306330815c53SDimitry Andric case ARM::VLD4q16:
306430815c53SDimitry Andric case ARM::VLD4q32:
306530815c53SDimitry Andric case ARM::VLD4q8_UPD:
306630815c53SDimitry Andric case ARM::VLD4q16_UPD:
306730815c53SDimitry Andric case ARM::VLD4q32_UPD:
306830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
306930815c53SDimitry Andric return MCDisassembler::Fail;
307030815c53SDimitry Andric break;
307130815c53SDimitry Andric default:
307230815c53SDimitry Andric break;
307330815c53SDimitry Andric }
307430815c53SDimitry Andric
307530815c53SDimitry Andric // Fourth output register
307630815c53SDimitry Andric switch (Inst.getOpcode()) {
307730815c53SDimitry Andric case ARM::VLD4d8:
307830815c53SDimitry Andric case ARM::VLD4d16:
307930815c53SDimitry Andric case ARM::VLD4d32:
308030815c53SDimitry Andric case ARM::VLD4d8_UPD:
308130815c53SDimitry Andric case ARM::VLD4d16_UPD:
308230815c53SDimitry Andric case ARM::VLD4d32_UPD:
308330815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
308430815c53SDimitry Andric return MCDisassembler::Fail;
308530815c53SDimitry Andric break;
308630815c53SDimitry Andric case ARM::VLD4q8:
308730815c53SDimitry Andric case ARM::VLD4q16:
308830815c53SDimitry Andric case ARM::VLD4q32:
308930815c53SDimitry Andric case ARM::VLD4q8_UPD:
309030815c53SDimitry Andric case ARM::VLD4q16_UPD:
309130815c53SDimitry Andric case ARM::VLD4q32_UPD:
309230815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
309330815c53SDimitry Andric return MCDisassembler::Fail;
309430815c53SDimitry Andric break;
309530815c53SDimitry Andric default:
309630815c53SDimitry Andric break;
309730815c53SDimitry Andric }
309830815c53SDimitry Andric
309930815c53SDimitry Andric // Writeback operand
310030815c53SDimitry Andric switch (Inst.getOpcode()) {
310163faed5bSDimitry Andric case ARM::VLD1d8wb_fixed:
310263faed5bSDimitry Andric case ARM::VLD1d16wb_fixed:
310363faed5bSDimitry Andric case ARM::VLD1d32wb_fixed:
310463faed5bSDimitry Andric case ARM::VLD1d64wb_fixed:
310563faed5bSDimitry Andric case ARM::VLD1d8wb_register:
310663faed5bSDimitry Andric case ARM::VLD1d16wb_register:
310763faed5bSDimitry Andric case ARM::VLD1d32wb_register:
310863faed5bSDimitry Andric case ARM::VLD1d64wb_register:
310963faed5bSDimitry Andric case ARM::VLD1q8wb_fixed:
311063faed5bSDimitry Andric case ARM::VLD1q16wb_fixed:
311163faed5bSDimitry Andric case ARM::VLD1q32wb_fixed:
311263faed5bSDimitry Andric case ARM::VLD1q64wb_fixed:
311363faed5bSDimitry Andric case ARM::VLD1q8wb_register:
311463faed5bSDimitry Andric case ARM::VLD1q16wb_register:
311563faed5bSDimitry Andric case ARM::VLD1q32wb_register:
311663faed5bSDimitry Andric case ARM::VLD1q64wb_register:
311763faed5bSDimitry Andric case ARM::VLD1d8Twb_fixed:
311863faed5bSDimitry Andric case ARM::VLD1d8Twb_register:
311963faed5bSDimitry Andric case ARM::VLD1d16Twb_fixed:
312063faed5bSDimitry Andric case ARM::VLD1d16Twb_register:
312163faed5bSDimitry Andric case ARM::VLD1d32Twb_fixed:
312263faed5bSDimitry Andric case ARM::VLD1d32Twb_register:
312363faed5bSDimitry Andric case ARM::VLD1d64Twb_fixed:
312463faed5bSDimitry Andric case ARM::VLD1d64Twb_register:
312563faed5bSDimitry Andric case ARM::VLD1d8Qwb_fixed:
312663faed5bSDimitry Andric case ARM::VLD1d8Qwb_register:
312763faed5bSDimitry Andric case ARM::VLD1d16Qwb_fixed:
312863faed5bSDimitry Andric case ARM::VLD1d16Qwb_register:
312963faed5bSDimitry Andric case ARM::VLD1d32Qwb_fixed:
313063faed5bSDimitry Andric case ARM::VLD1d32Qwb_register:
313163faed5bSDimitry Andric case ARM::VLD1d64Qwb_fixed:
313263faed5bSDimitry Andric case ARM::VLD1d64Qwb_register:
313363faed5bSDimitry Andric case ARM::VLD2d8wb_fixed:
313463faed5bSDimitry Andric case ARM::VLD2d16wb_fixed:
313563faed5bSDimitry Andric case ARM::VLD2d32wb_fixed:
313663faed5bSDimitry Andric case ARM::VLD2q8wb_fixed:
313763faed5bSDimitry Andric case ARM::VLD2q16wb_fixed:
313863faed5bSDimitry Andric case ARM::VLD2q32wb_fixed:
313963faed5bSDimitry Andric case ARM::VLD2d8wb_register:
314063faed5bSDimitry Andric case ARM::VLD2d16wb_register:
314163faed5bSDimitry Andric case ARM::VLD2d32wb_register:
314263faed5bSDimitry Andric case ARM::VLD2q8wb_register:
314363faed5bSDimitry Andric case ARM::VLD2q16wb_register:
314463faed5bSDimitry Andric case ARM::VLD2q32wb_register:
314563faed5bSDimitry Andric case ARM::VLD2b8wb_fixed:
314663faed5bSDimitry Andric case ARM::VLD2b16wb_fixed:
314763faed5bSDimitry Andric case ARM::VLD2b32wb_fixed:
314863faed5bSDimitry Andric case ARM::VLD2b8wb_register:
314963faed5bSDimitry Andric case ARM::VLD2b16wb_register:
315063faed5bSDimitry Andric case ARM::VLD2b32wb_register:
31515a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
315263faed5bSDimitry Andric break;
315330815c53SDimitry Andric case ARM::VLD3d8_UPD:
315430815c53SDimitry Andric case ARM::VLD3d16_UPD:
315530815c53SDimitry Andric case ARM::VLD3d32_UPD:
315630815c53SDimitry Andric case ARM::VLD3q8_UPD:
315730815c53SDimitry Andric case ARM::VLD3q16_UPD:
315830815c53SDimitry Andric case ARM::VLD3q32_UPD:
315930815c53SDimitry Andric case ARM::VLD4d8_UPD:
316030815c53SDimitry Andric case ARM::VLD4d16_UPD:
316130815c53SDimitry Andric case ARM::VLD4d32_UPD:
316230815c53SDimitry Andric case ARM::VLD4q8_UPD:
316330815c53SDimitry Andric case ARM::VLD4q16_UPD:
316430815c53SDimitry Andric case ARM::VLD4q32_UPD:
316530815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
316630815c53SDimitry Andric return MCDisassembler::Fail;
316730815c53SDimitry Andric break;
316830815c53SDimitry Andric default:
316930815c53SDimitry Andric break;
317030815c53SDimitry Andric }
317130815c53SDimitry Andric
317230815c53SDimitry Andric // AddrMode6 Base (register+alignment)
317330815c53SDimitry Andric if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
317430815c53SDimitry Andric return MCDisassembler::Fail;
317530815c53SDimitry Andric
317630815c53SDimitry Andric // AddrMode6 Offset (register)
317763faed5bSDimitry Andric switch (Inst.getOpcode()) {
317863faed5bSDimitry Andric default:
317963faed5bSDimitry Andric // The below have been updated to have explicit am6offset split
318063faed5bSDimitry Andric // between fixed and register offset. For those instructions not
318163faed5bSDimitry Andric // yet updated, we need to add an additional reg0 operand for the
318263faed5bSDimitry Andric // fixed variant.
318363faed5bSDimitry Andric //
318463faed5bSDimitry Andric // The fixed offset encodes as Rm == 0xd, so we check for that.
318563faed5bSDimitry Andric if (Rm == 0xd) {
31865a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
318763faed5bSDimitry Andric break;
318863faed5bSDimitry Andric }
318963faed5bSDimitry Andric // Fall through to handle the register offset variant.
3190e3b55780SDimitry Andric [[fallthrough]];
319163faed5bSDimitry Andric case ARM::VLD1d8wb_fixed:
319263faed5bSDimitry Andric case ARM::VLD1d16wb_fixed:
319363faed5bSDimitry Andric case ARM::VLD1d32wb_fixed:
319463faed5bSDimitry Andric case ARM::VLD1d64wb_fixed:
319563faed5bSDimitry Andric case ARM::VLD1d8Twb_fixed:
319663faed5bSDimitry Andric case ARM::VLD1d16Twb_fixed:
319763faed5bSDimitry Andric case ARM::VLD1d32Twb_fixed:
319863faed5bSDimitry Andric case ARM::VLD1d64Twb_fixed:
319963faed5bSDimitry Andric case ARM::VLD1d8Qwb_fixed:
320063faed5bSDimitry Andric case ARM::VLD1d16Qwb_fixed:
320163faed5bSDimitry Andric case ARM::VLD1d32Qwb_fixed:
320263faed5bSDimitry Andric case ARM::VLD1d64Qwb_fixed:
320363faed5bSDimitry Andric case ARM::VLD1d8wb_register:
320463faed5bSDimitry Andric case ARM::VLD1d16wb_register:
320563faed5bSDimitry Andric case ARM::VLD1d32wb_register:
320663faed5bSDimitry Andric case ARM::VLD1d64wb_register:
320763faed5bSDimitry Andric case ARM::VLD1q8wb_fixed:
320863faed5bSDimitry Andric case ARM::VLD1q16wb_fixed:
320963faed5bSDimitry Andric case ARM::VLD1q32wb_fixed:
321063faed5bSDimitry Andric case ARM::VLD1q64wb_fixed:
321163faed5bSDimitry Andric case ARM::VLD1q8wb_register:
321263faed5bSDimitry Andric case ARM::VLD1q16wb_register:
321363faed5bSDimitry Andric case ARM::VLD1q32wb_register:
321463faed5bSDimitry Andric case ARM::VLD1q64wb_register:
321563faed5bSDimitry Andric // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
321663faed5bSDimitry Andric // variant encodes Rm == 0xf. Anything else is a register offset post-
321763faed5bSDimitry Andric // increment and we need to add the register operand to the instruction.
321863faed5bSDimitry Andric if (Rm != 0xD && Rm != 0xF &&
321963faed5bSDimitry Andric !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
322030815c53SDimitry Andric return MCDisassembler::Fail;
322163faed5bSDimitry Andric break;
322263faed5bSDimitry Andric case ARM::VLD2d8wb_fixed:
322363faed5bSDimitry Andric case ARM::VLD2d16wb_fixed:
322463faed5bSDimitry Andric case ARM::VLD2d32wb_fixed:
322563faed5bSDimitry Andric case ARM::VLD2b8wb_fixed:
322663faed5bSDimitry Andric case ARM::VLD2b16wb_fixed:
322763faed5bSDimitry Andric case ARM::VLD2b32wb_fixed:
322863faed5bSDimitry Andric case ARM::VLD2q8wb_fixed:
322963faed5bSDimitry Andric case ARM::VLD2q16wb_fixed:
323063faed5bSDimitry Andric case ARM::VLD2q32wb_fixed:
323163faed5bSDimitry Andric break;
323230815c53SDimitry Andric }
323330815c53SDimitry Andric
323430815c53SDimitry Andric return S;
323530815c53SDimitry Andric }
323630815c53SDimitry Andric
DecodeVLDST1Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)3237f8af5cf6SDimitry Andric static DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
3238145449b1SDimitry Andric uint64_t Address,
3239145449b1SDimitry Andric const MCDisassembler *Decoder) {
3240f8af5cf6SDimitry Andric unsigned type = fieldFromInstruction(Insn, 8, 4);
3241f8af5cf6SDimitry Andric unsigned align = fieldFromInstruction(Insn, 4, 2);
3242f8af5cf6SDimitry Andric if (type == 6 && (align & 2)) return MCDisassembler::Fail;
3243f8af5cf6SDimitry Andric if (type == 7 && (align & 2)) return MCDisassembler::Fail;
3244f8af5cf6SDimitry Andric if (type == 10 && align == 3) return MCDisassembler::Fail;
3245f8af5cf6SDimitry Andric
3246f8af5cf6SDimitry Andric unsigned load = fieldFromInstruction(Insn, 21, 1);
3247f8af5cf6SDimitry Andric return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
3248f8af5cf6SDimitry Andric : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
3249f8af5cf6SDimitry Andric }
3250f8af5cf6SDimitry Andric
DecodeVLDST2Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)3251f8af5cf6SDimitry Andric static DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
3252145449b1SDimitry Andric uint64_t Address,
3253145449b1SDimitry Andric const MCDisassembler *Decoder) {
3254f8af5cf6SDimitry Andric unsigned size = fieldFromInstruction(Insn, 6, 2);
3255f8af5cf6SDimitry Andric if (size == 3) return MCDisassembler::Fail;
3256f8af5cf6SDimitry Andric
3257f8af5cf6SDimitry Andric unsigned type = fieldFromInstruction(Insn, 8, 4);
3258f8af5cf6SDimitry Andric unsigned align = fieldFromInstruction(Insn, 4, 2);
3259f8af5cf6SDimitry Andric if (type == 8 && align == 3) return MCDisassembler::Fail;
3260f8af5cf6SDimitry Andric if (type == 9 && align == 3) return MCDisassembler::Fail;
3261f8af5cf6SDimitry Andric
3262f8af5cf6SDimitry Andric unsigned load = fieldFromInstruction(Insn, 21, 1);
3263f8af5cf6SDimitry Andric return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
3264f8af5cf6SDimitry Andric : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
3265f8af5cf6SDimitry Andric }
3266f8af5cf6SDimitry Andric
DecodeVLDST3Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)3267f8af5cf6SDimitry Andric static DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
3268145449b1SDimitry Andric uint64_t Address,
3269145449b1SDimitry Andric const MCDisassembler *Decoder) {
3270f8af5cf6SDimitry Andric unsigned size = fieldFromInstruction(Insn, 6, 2);
3271f8af5cf6SDimitry Andric if (size == 3) return MCDisassembler::Fail;
3272f8af5cf6SDimitry Andric
3273f8af5cf6SDimitry Andric unsigned align = fieldFromInstruction(Insn, 4, 2);
3274f8af5cf6SDimitry Andric if (align & 2) return MCDisassembler::Fail;
3275f8af5cf6SDimitry Andric
3276f8af5cf6SDimitry Andric unsigned load = fieldFromInstruction(Insn, 21, 1);
3277f8af5cf6SDimitry Andric return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
3278f8af5cf6SDimitry Andric : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
3279f8af5cf6SDimitry Andric }
3280f8af5cf6SDimitry Andric
DecodeVLDST4Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)3281f8af5cf6SDimitry Andric static DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
3282145449b1SDimitry Andric uint64_t Address,
3283145449b1SDimitry Andric const MCDisassembler *Decoder) {
3284f8af5cf6SDimitry Andric unsigned size = fieldFromInstruction(Insn, 6, 2);
3285f8af5cf6SDimitry Andric if (size == 3) return MCDisassembler::Fail;
3286f8af5cf6SDimitry Andric
3287f8af5cf6SDimitry Andric unsigned load = fieldFromInstruction(Insn, 21, 1);
3288f8af5cf6SDimitry Andric return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
3289f8af5cf6SDimitry Andric : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
3290f8af5cf6SDimitry Andric }
3291f8af5cf6SDimitry Andric
DecodeVSTInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)329263faed5bSDimitry Andric static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
3293145449b1SDimitry Andric uint64_t Address,
3294145449b1SDimitry Andric const MCDisassembler *Decoder) {
329530815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
329630815c53SDimitry Andric
3297902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3298902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3299902a7b52SDimitry Andric unsigned wb = fieldFromInstruction(Insn, 16, 4);
3300902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3301902a7b52SDimitry Andric Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
3302902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
330330815c53SDimitry Andric
330430815c53SDimitry Andric // Writeback Operand
330530815c53SDimitry Andric switch (Inst.getOpcode()) {
330663faed5bSDimitry Andric case ARM::VST1d8wb_fixed:
330763faed5bSDimitry Andric case ARM::VST1d16wb_fixed:
330863faed5bSDimitry Andric case ARM::VST1d32wb_fixed:
330963faed5bSDimitry Andric case ARM::VST1d64wb_fixed:
331063faed5bSDimitry Andric case ARM::VST1d8wb_register:
331163faed5bSDimitry Andric case ARM::VST1d16wb_register:
331263faed5bSDimitry Andric case ARM::VST1d32wb_register:
331363faed5bSDimitry Andric case ARM::VST1d64wb_register:
331463faed5bSDimitry Andric case ARM::VST1q8wb_fixed:
331563faed5bSDimitry Andric case ARM::VST1q16wb_fixed:
331663faed5bSDimitry Andric case ARM::VST1q32wb_fixed:
331763faed5bSDimitry Andric case ARM::VST1q64wb_fixed:
331863faed5bSDimitry Andric case ARM::VST1q8wb_register:
331963faed5bSDimitry Andric case ARM::VST1q16wb_register:
332063faed5bSDimitry Andric case ARM::VST1q32wb_register:
332163faed5bSDimitry Andric case ARM::VST1q64wb_register:
332263faed5bSDimitry Andric case ARM::VST1d8Twb_fixed:
332363faed5bSDimitry Andric case ARM::VST1d16Twb_fixed:
332463faed5bSDimitry Andric case ARM::VST1d32Twb_fixed:
332563faed5bSDimitry Andric case ARM::VST1d64Twb_fixed:
332663faed5bSDimitry Andric case ARM::VST1d8Twb_register:
332763faed5bSDimitry Andric case ARM::VST1d16Twb_register:
332863faed5bSDimitry Andric case ARM::VST1d32Twb_register:
332963faed5bSDimitry Andric case ARM::VST1d64Twb_register:
333063faed5bSDimitry Andric case ARM::VST1d8Qwb_fixed:
333163faed5bSDimitry Andric case ARM::VST1d16Qwb_fixed:
333263faed5bSDimitry Andric case ARM::VST1d32Qwb_fixed:
333363faed5bSDimitry Andric case ARM::VST1d64Qwb_fixed:
333463faed5bSDimitry Andric case ARM::VST1d8Qwb_register:
333563faed5bSDimitry Andric case ARM::VST1d16Qwb_register:
333663faed5bSDimitry Andric case ARM::VST1d32Qwb_register:
333763faed5bSDimitry Andric case ARM::VST1d64Qwb_register:
333863faed5bSDimitry Andric case ARM::VST2d8wb_fixed:
333963faed5bSDimitry Andric case ARM::VST2d16wb_fixed:
334063faed5bSDimitry Andric case ARM::VST2d32wb_fixed:
334163faed5bSDimitry Andric case ARM::VST2d8wb_register:
334263faed5bSDimitry Andric case ARM::VST2d16wb_register:
334363faed5bSDimitry Andric case ARM::VST2d32wb_register:
334463faed5bSDimitry Andric case ARM::VST2q8wb_fixed:
334563faed5bSDimitry Andric case ARM::VST2q16wb_fixed:
334663faed5bSDimitry Andric case ARM::VST2q32wb_fixed:
334763faed5bSDimitry Andric case ARM::VST2q8wb_register:
334863faed5bSDimitry Andric case ARM::VST2q16wb_register:
334963faed5bSDimitry Andric case ARM::VST2q32wb_register:
335063faed5bSDimitry Andric case ARM::VST2b8wb_fixed:
335163faed5bSDimitry Andric case ARM::VST2b16wb_fixed:
335263faed5bSDimitry Andric case ARM::VST2b32wb_fixed:
335363faed5bSDimitry Andric case ARM::VST2b8wb_register:
335463faed5bSDimitry Andric case ARM::VST2b16wb_register:
335563faed5bSDimitry Andric case ARM::VST2b32wb_register:
335663faed5bSDimitry Andric if (Rm == 0xF)
335763faed5bSDimitry Andric return MCDisassembler::Fail;
33585a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
335963faed5bSDimitry Andric break;
336030815c53SDimitry Andric case ARM::VST3d8_UPD:
336130815c53SDimitry Andric case ARM::VST3d16_UPD:
336230815c53SDimitry Andric case ARM::VST3d32_UPD:
336330815c53SDimitry Andric case ARM::VST3q8_UPD:
336430815c53SDimitry Andric case ARM::VST3q16_UPD:
336530815c53SDimitry Andric case ARM::VST3q32_UPD:
336630815c53SDimitry Andric case ARM::VST4d8_UPD:
336730815c53SDimitry Andric case ARM::VST4d16_UPD:
336830815c53SDimitry Andric case ARM::VST4d32_UPD:
336930815c53SDimitry Andric case ARM::VST4q8_UPD:
337030815c53SDimitry Andric case ARM::VST4q16_UPD:
337130815c53SDimitry Andric case ARM::VST4q32_UPD:
337230815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
337330815c53SDimitry Andric return MCDisassembler::Fail;
337430815c53SDimitry Andric break;
337530815c53SDimitry Andric default:
337630815c53SDimitry Andric break;
337730815c53SDimitry Andric }
337830815c53SDimitry Andric
337930815c53SDimitry Andric // AddrMode6 Base (register+alignment)
338030815c53SDimitry Andric if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
338130815c53SDimitry Andric return MCDisassembler::Fail;
338230815c53SDimitry Andric
338330815c53SDimitry Andric // AddrMode6 Offset (register)
338463faed5bSDimitry Andric switch (Inst.getOpcode()) {
338563faed5bSDimitry Andric default:
338630815c53SDimitry Andric if (Rm == 0xD)
33875a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
338830815c53SDimitry Andric else if (Rm != 0xF) {
338930815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
339030815c53SDimitry Andric return MCDisassembler::Fail;
339130815c53SDimitry Andric }
339263faed5bSDimitry Andric break;
339363faed5bSDimitry Andric case ARM::VST1d8wb_fixed:
339463faed5bSDimitry Andric case ARM::VST1d16wb_fixed:
339563faed5bSDimitry Andric case ARM::VST1d32wb_fixed:
339663faed5bSDimitry Andric case ARM::VST1d64wb_fixed:
339763faed5bSDimitry Andric case ARM::VST1q8wb_fixed:
339863faed5bSDimitry Andric case ARM::VST1q16wb_fixed:
339963faed5bSDimitry Andric case ARM::VST1q32wb_fixed:
340063faed5bSDimitry Andric case ARM::VST1q64wb_fixed:
340163faed5bSDimitry Andric case ARM::VST1d8Twb_fixed:
340263faed5bSDimitry Andric case ARM::VST1d16Twb_fixed:
340363faed5bSDimitry Andric case ARM::VST1d32Twb_fixed:
340463faed5bSDimitry Andric case ARM::VST1d64Twb_fixed:
340563faed5bSDimitry Andric case ARM::VST1d8Qwb_fixed:
340663faed5bSDimitry Andric case ARM::VST1d16Qwb_fixed:
340763faed5bSDimitry Andric case ARM::VST1d32Qwb_fixed:
340863faed5bSDimitry Andric case ARM::VST1d64Qwb_fixed:
340963faed5bSDimitry Andric case ARM::VST2d8wb_fixed:
341063faed5bSDimitry Andric case ARM::VST2d16wb_fixed:
341163faed5bSDimitry Andric case ARM::VST2d32wb_fixed:
341263faed5bSDimitry Andric case ARM::VST2q8wb_fixed:
341363faed5bSDimitry Andric case ARM::VST2q16wb_fixed:
341463faed5bSDimitry Andric case ARM::VST2q32wb_fixed:
341563faed5bSDimitry Andric case ARM::VST2b8wb_fixed:
341663faed5bSDimitry Andric case ARM::VST2b16wb_fixed:
341763faed5bSDimitry Andric case ARM::VST2b32wb_fixed:
341863faed5bSDimitry Andric break;
341963faed5bSDimitry Andric }
342063faed5bSDimitry Andric
342130815c53SDimitry Andric // First input register
342230815c53SDimitry Andric switch (Inst.getOpcode()) {
342330815c53SDimitry Andric case ARM::VST1q16:
342430815c53SDimitry Andric case ARM::VST1q32:
342530815c53SDimitry Andric case ARM::VST1q64:
342663faed5bSDimitry Andric case ARM::VST1q8:
342763faed5bSDimitry Andric case ARM::VST1q16wb_fixed:
342863faed5bSDimitry Andric case ARM::VST1q16wb_register:
342963faed5bSDimitry Andric case ARM::VST1q32wb_fixed:
343063faed5bSDimitry Andric case ARM::VST1q32wb_register:
343163faed5bSDimitry Andric case ARM::VST1q64wb_fixed:
343263faed5bSDimitry Andric case ARM::VST1q64wb_register:
343363faed5bSDimitry Andric case ARM::VST1q8wb_fixed:
343463faed5bSDimitry Andric case ARM::VST1q8wb_register:
343530815c53SDimitry Andric case ARM::VST2d16:
343630815c53SDimitry Andric case ARM::VST2d32:
343763faed5bSDimitry Andric case ARM::VST2d8:
343863faed5bSDimitry Andric case ARM::VST2d16wb_fixed:
343963faed5bSDimitry Andric case ARM::VST2d16wb_register:
344063faed5bSDimitry Andric case ARM::VST2d32wb_fixed:
344163faed5bSDimitry Andric case ARM::VST2d32wb_register:
344263faed5bSDimitry Andric case ARM::VST2d8wb_fixed:
344363faed5bSDimitry Andric case ARM::VST2d8wb_register:
344463faed5bSDimitry Andric if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
344563faed5bSDimitry Andric return MCDisassembler::Fail;
344663faed5bSDimitry Andric break;
344763faed5bSDimitry Andric case ARM::VST2b16:
344863faed5bSDimitry Andric case ARM::VST2b32:
344963faed5bSDimitry Andric case ARM::VST2b8:
345063faed5bSDimitry Andric case ARM::VST2b16wb_fixed:
345163faed5bSDimitry Andric case ARM::VST2b16wb_register:
345263faed5bSDimitry Andric case ARM::VST2b32wb_fixed:
345363faed5bSDimitry Andric case ARM::VST2b32wb_register:
345463faed5bSDimitry Andric case ARM::VST2b8wb_fixed:
345563faed5bSDimitry Andric case ARM::VST2b8wb_register:
345663faed5bSDimitry Andric if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
345763faed5bSDimitry Andric return MCDisassembler::Fail;
345863faed5bSDimitry Andric break;
345963faed5bSDimitry Andric default:
346063faed5bSDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
346163faed5bSDimitry Andric return MCDisassembler::Fail;
346263faed5bSDimitry Andric }
346363faed5bSDimitry Andric
346463faed5bSDimitry Andric // Second input register
346563faed5bSDimitry Andric switch (Inst.getOpcode()) {
346630815c53SDimitry Andric case ARM::VST3d8:
346730815c53SDimitry Andric case ARM::VST3d16:
346830815c53SDimitry Andric case ARM::VST3d32:
346930815c53SDimitry Andric case ARM::VST3d8_UPD:
347030815c53SDimitry Andric case ARM::VST3d16_UPD:
347130815c53SDimitry Andric case ARM::VST3d32_UPD:
347230815c53SDimitry Andric case ARM::VST4d8:
347330815c53SDimitry Andric case ARM::VST4d16:
347430815c53SDimitry Andric case ARM::VST4d32:
347530815c53SDimitry Andric case ARM::VST4d8_UPD:
347630815c53SDimitry Andric case ARM::VST4d16_UPD:
347730815c53SDimitry Andric case ARM::VST4d32_UPD:
347830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
347930815c53SDimitry Andric return MCDisassembler::Fail;
348030815c53SDimitry Andric break;
348130815c53SDimitry Andric case ARM::VST3q8:
348230815c53SDimitry Andric case ARM::VST3q16:
348330815c53SDimitry Andric case ARM::VST3q32:
348430815c53SDimitry Andric case ARM::VST3q8_UPD:
348530815c53SDimitry Andric case ARM::VST3q16_UPD:
348630815c53SDimitry Andric case ARM::VST3q32_UPD:
348730815c53SDimitry Andric case ARM::VST4q8:
348830815c53SDimitry Andric case ARM::VST4q16:
348930815c53SDimitry Andric case ARM::VST4q32:
349030815c53SDimitry Andric case ARM::VST4q8_UPD:
349130815c53SDimitry Andric case ARM::VST4q16_UPD:
349230815c53SDimitry Andric case ARM::VST4q32_UPD:
349330815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
349430815c53SDimitry Andric return MCDisassembler::Fail;
349530815c53SDimitry Andric break;
349630815c53SDimitry Andric default:
349730815c53SDimitry Andric break;
349830815c53SDimitry Andric }
349930815c53SDimitry Andric
350030815c53SDimitry Andric // Third input register
350130815c53SDimitry Andric switch (Inst.getOpcode()) {
350230815c53SDimitry Andric case ARM::VST3d8:
350330815c53SDimitry Andric case ARM::VST3d16:
350430815c53SDimitry Andric case ARM::VST3d32:
350530815c53SDimitry Andric case ARM::VST3d8_UPD:
350630815c53SDimitry Andric case ARM::VST3d16_UPD:
350730815c53SDimitry Andric case ARM::VST3d32_UPD:
350830815c53SDimitry Andric case ARM::VST4d8:
350930815c53SDimitry Andric case ARM::VST4d16:
351030815c53SDimitry Andric case ARM::VST4d32:
351130815c53SDimitry Andric case ARM::VST4d8_UPD:
351230815c53SDimitry Andric case ARM::VST4d16_UPD:
351330815c53SDimitry Andric case ARM::VST4d32_UPD:
351430815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
351530815c53SDimitry Andric return MCDisassembler::Fail;
351630815c53SDimitry Andric break;
351730815c53SDimitry Andric case ARM::VST3q8:
351830815c53SDimitry Andric case ARM::VST3q16:
351930815c53SDimitry Andric case ARM::VST3q32:
352030815c53SDimitry Andric case ARM::VST3q8_UPD:
352130815c53SDimitry Andric case ARM::VST3q16_UPD:
352230815c53SDimitry Andric case ARM::VST3q32_UPD:
352330815c53SDimitry Andric case ARM::VST4q8:
352430815c53SDimitry Andric case ARM::VST4q16:
352530815c53SDimitry Andric case ARM::VST4q32:
352630815c53SDimitry Andric case ARM::VST4q8_UPD:
352730815c53SDimitry Andric case ARM::VST4q16_UPD:
352830815c53SDimitry Andric case ARM::VST4q32_UPD:
352930815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
353030815c53SDimitry Andric return MCDisassembler::Fail;
353130815c53SDimitry Andric break;
353230815c53SDimitry Andric default:
353330815c53SDimitry Andric break;
353430815c53SDimitry Andric }
353530815c53SDimitry Andric
353630815c53SDimitry Andric // Fourth input register
353730815c53SDimitry Andric switch (Inst.getOpcode()) {
353830815c53SDimitry Andric case ARM::VST4d8:
353930815c53SDimitry Andric case ARM::VST4d16:
354030815c53SDimitry Andric case ARM::VST4d32:
354130815c53SDimitry Andric case ARM::VST4d8_UPD:
354230815c53SDimitry Andric case ARM::VST4d16_UPD:
354330815c53SDimitry Andric case ARM::VST4d32_UPD:
354430815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
354530815c53SDimitry Andric return MCDisassembler::Fail;
354630815c53SDimitry Andric break;
354730815c53SDimitry Andric case ARM::VST4q8:
354830815c53SDimitry Andric case ARM::VST4q16:
354930815c53SDimitry Andric case ARM::VST4q32:
355030815c53SDimitry Andric case ARM::VST4q8_UPD:
355130815c53SDimitry Andric case ARM::VST4q16_UPD:
355230815c53SDimitry Andric case ARM::VST4q32_UPD:
355330815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
355430815c53SDimitry Andric return MCDisassembler::Fail;
355530815c53SDimitry Andric break;
355630815c53SDimitry Andric default:
355730815c53SDimitry Andric break;
355830815c53SDimitry Andric }
355930815c53SDimitry Andric
356030815c53SDimitry Andric return S;
356130815c53SDimitry Andric }
356230815c53SDimitry Andric
DecodeVLD1DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)356363faed5bSDimitry Andric static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
3564145449b1SDimitry Andric uint64_t Address,
3565145449b1SDimitry Andric const MCDisassembler *Decoder) {
356630815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
356730815c53SDimitry Andric
3568902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3569902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3570902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3571902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3572902a7b52SDimitry Andric unsigned align = fieldFromInstruction(Insn, 4, 1);
3573902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 6, 2);
357430815c53SDimitry Andric
3575522600a2SDimitry Andric if (size == 0 && align == 1)
3576522600a2SDimitry Andric return MCDisassembler::Fail;
357730815c53SDimitry Andric align *= (1 << size);
357830815c53SDimitry Andric
357963faed5bSDimitry Andric switch (Inst.getOpcode()) {
358063faed5bSDimitry Andric case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
358163faed5bSDimitry Andric case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
358263faed5bSDimitry Andric case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
358363faed5bSDimitry Andric case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
358463faed5bSDimitry Andric if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
358563faed5bSDimitry Andric return MCDisassembler::Fail;
358663faed5bSDimitry Andric break;
358763faed5bSDimitry Andric default:
358830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
358930815c53SDimitry Andric return MCDisassembler::Fail;
359063faed5bSDimitry Andric break;
359130815c53SDimitry Andric }
359230815c53SDimitry Andric if (Rm != 0xF) {
359330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
359430815c53SDimitry Andric return MCDisassembler::Fail;
359530815c53SDimitry Andric }
359630815c53SDimitry Andric
359730815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
359830815c53SDimitry Andric return MCDisassembler::Fail;
35995a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
360030815c53SDimitry Andric
360163faed5bSDimitry Andric // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
360263faed5bSDimitry Andric // variant encodes Rm == 0xf. Anything else is a register offset post-
360363faed5bSDimitry Andric // increment and we need to add the register operand to the instruction.
360463faed5bSDimitry Andric if (Rm != 0xD && Rm != 0xF &&
360563faed5bSDimitry Andric !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
360630815c53SDimitry Andric return MCDisassembler::Fail;
360730815c53SDimitry Andric
360830815c53SDimitry Andric return S;
360930815c53SDimitry Andric }
361030815c53SDimitry Andric
DecodeVLD2DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)361163faed5bSDimitry Andric static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
3612145449b1SDimitry Andric uint64_t Address,
3613145449b1SDimitry Andric const MCDisassembler *Decoder) {
361430815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
361530815c53SDimitry Andric
3616902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3617902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3618902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3619902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3620902a7b52SDimitry Andric unsigned align = fieldFromInstruction(Insn, 4, 1);
3621902a7b52SDimitry Andric unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
362230815c53SDimitry Andric align *= 2*size;
362330815c53SDimitry Andric
362463faed5bSDimitry Andric switch (Inst.getOpcode()) {
362563faed5bSDimitry Andric case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
362663faed5bSDimitry Andric case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
362763faed5bSDimitry Andric case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
362863faed5bSDimitry Andric case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
362963faed5bSDimitry Andric if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
363063faed5bSDimitry Andric return MCDisassembler::Fail;
363163faed5bSDimitry Andric break;
363263faed5bSDimitry Andric case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
363363faed5bSDimitry Andric case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
363463faed5bSDimitry Andric case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
363563faed5bSDimitry Andric case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
363663faed5bSDimitry Andric if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
363763faed5bSDimitry Andric return MCDisassembler::Fail;
363863faed5bSDimitry Andric break;
363963faed5bSDimitry Andric default:
364030815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
364130815c53SDimitry Andric return MCDisassembler::Fail;
364263faed5bSDimitry Andric break;
364330815c53SDimitry Andric }
364430815c53SDimitry Andric
364563faed5bSDimitry Andric if (Rm != 0xF)
36465a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
364763faed5bSDimitry Andric
364830815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
364930815c53SDimitry Andric return MCDisassembler::Fail;
36505a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
365130815c53SDimitry Andric
3652b61ab53cSDimitry Andric if (Rm != 0xD && Rm != 0xF) {
365330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
365430815c53SDimitry Andric return MCDisassembler::Fail;
365530815c53SDimitry Andric }
365630815c53SDimitry Andric
365730815c53SDimitry Andric return S;
365830815c53SDimitry Andric }
365930815c53SDimitry Andric
DecodeVLD3DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)366063faed5bSDimitry Andric static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
3661145449b1SDimitry Andric uint64_t Address,
3662145449b1SDimitry Andric const MCDisassembler *Decoder) {
366330815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
366430815c53SDimitry Andric
3665902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3666902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3667902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3668902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3669902a7b52SDimitry Andric unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
367030815c53SDimitry Andric
367130815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
367230815c53SDimitry Andric return MCDisassembler::Fail;
367330815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
367430815c53SDimitry Andric return MCDisassembler::Fail;
367530815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
367630815c53SDimitry Andric return MCDisassembler::Fail;
367730815c53SDimitry Andric if (Rm != 0xF) {
367830815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
367930815c53SDimitry Andric return MCDisassembler::Fail;
368030815c53SDimitry Andric }
368130815c53SDimitry Andric
368230815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
368330815c53SDimitry Andric return MCDisassembler::Fail;
36845a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
368530815c53SDimitry Andric
368630815c53SDimitry Andric if (Rm == 0xD)
36875a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
368830815c53SDimitry Andric else if (Rm != 0xF) {
368930815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
369030815c53SDimitry Andric return MCDisassembler::Fail;
369130815c53SDimitry Andric }
369230815c53SDimitry Andric
369330815c53SDimitry Andric return S;
369430815c53SDimitry Andric }
369530815c53SDimitry Andric
DecodeVLD4DupInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)369663faed5bSDimitry Andric static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
3697145449b1SDimitry Andric uint64_t Address,
3698145449b1SDimitry Andric const MCDisassembler *Decoder) {
369930815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
370030815c53SDimitry Andric
3701902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3702902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3703902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3704902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3705902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 6, 2);
3706902a7b52SDimitry Andric unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
3707902a7b52SDimitry Andric unsigned align = fieldFromInstruction(Insn, 4, 1);
370830815c53SDimitry Andric
370930815c53SDimitry Andric if (size == 0x3) {
3710522600a2SDimitry Andric if (align == 0)
3711522600a2SDimitry Andric return MCDisassembler::Fail;
371230815c53SDimitry Andric align = 16;
371330815c53SDimitry Andric } else {
371430815c53SDimitry Andric if (size == 2) {
371530815c53SDimitry Andric align *= 8;
371630815c53SDimitry Andric } else {
371730815c53SDimitry Andric size = 1 << size;
371830815c53SDimitry Andric align *= 4*size;
371930815c53SDimitry Andric }
372030815c53SDimitry Andric }
372130815c53SDimitry Andric
372230815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
372330815c53SDimitry Andric return MCDisassembler::Fail;
372430815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
372530815c53SDimitry Andric return MCDisassembler::Fail;
372630815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
372730815c53SDimitry Andric return MCDisassembler::Fail;
372830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
372930815c53SDimitry Andric return MCDisassembler::Fail;
373030815c53SDimitry Andric if (Rm != 0xF) {
373130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
373230815c53SDimitry Andric return MCDisassembler::Fail;
373330815c53SDimitry Andric }
373430815c53SDimitry Andric
373530815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
373630815c53SDimitry Andric return MCDisassembler::Fail;
37375a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
373830815c53SDimitry Andric
373930815c53SDimitry Andric if (Rm == 0xD)
37405a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
374130815c53SDimitry Andric else if (Rm != 0xF) {
374230815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
374330815c53SDimitry Andric return MCDisassembler::Fail;
374430815c53SDimitry Andric }
374530815c53SDimitry Andric
374630815c53SDimitry Andric return S;
374730815c53SDimitry Andric }
374830815c53SDimitry Andric
DecodeVMOVModImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)3749145449b1SDimitry Andric static DecodeStatus DecodeVMOVModImmInstruction(MCInst &Inst, unsigned Insn,
3750145449b1SDimitry Andric uint64_t Address,
3751145449b1SDimitry Andric const MCDisassembler *Decoder) {
375230815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
375330815c53SDimitry Andric
3754902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3755902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3756902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 4);
3757902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 16, 3) << 4;
3758902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 24, 1) << 7;
3759902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 8, 4) << 8;
3760902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 5, 1) << 12;
3761902a7b52SDimitry Andric unsigned Q = fieldFromInstruction(Insn, 6, 1);
376230815c53SDimitry Andric
376330815c53SDimitry Andric if (Q) {
376430815c53SDimitry Andric if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
376530815c53SDimitry Andric return MCDisassembler::Fail;
376630815c53SDimitry Andric } else {
376730815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
376830815c53SDimitry Andric return MCDisassembler::Fail;
376930815c53SDimitry Andric }
377030815c53SDimitry Andric
37715a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
377230815c53SDimitry Andric
377330815c53SDimitry Andric switch (Inst.getOpcode()) {
377430815c53SDimitry Andric case ARM::VORRiv4i16:
377530815c53SDimitry Andric case ARM::VORRiv2i32:
377630815c53SDimitry Andric case ARM::VBICiv4i16:
377730815c53SDimitry Andric case ARM::VBICiv2i32:
377830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
377930815c53SDimitry Andric return MCDisassembler::Fail;
378030815c53SDimitry Andric break;
378130815c53SDimitry Andric case ARM::VORRiv8i16:
378230815c53SDimitry Andric case ARM::VORRiv4i32:
378330815c53SDimitry Andric case ARM::VBICiv8i16:
378430815c53SDimitry Andric case ARM::VBICiv4i32:
378530815c53SDimitry Andric if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
378630815c53SDimitry Andric return MCDisassembler::Fail;
378730815c53SDimitry Andric break;
378830815c53SDimitry Andric default:
378930815c53SDimitry Andric break;
379030815c53SDimitry Andric }
379130815c53SDimitry Andric
379230815c53SDimitry Andric return S;
379330815c53SDimitry Andric }
379430815c53SDimitry Andric
DecodeMVEModImmInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)3795145449b1SDimitry Andric static DecodeStatus DecodeMVEModImmInstruction(MCInst &Inst, unsigned Insn,
3796145449b1SDimitry Andric uint64_t Address,
3797145449b1SDimitry Andric const MCDisassembler *Decoder) {
3798e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
3799e6d15924SDimitry Andric
3800e6d15924SDimitry Andric unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
3801e6d15924SDimitry Andric fieldFromInstruction(Insn, 13, 3));
3802e6d15924SDimitry Andric unsigned cmode = fieldFromInstruction(Insn, 8, 4);
3803e6d15924SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 4);
3804e6d15924SDimitry Andric imm |= fieldFromInstruction(Insn, 16, 3) << 4;
3805e6d15924SDimitry Andric imm |= fieldFromInstruction(Insn, 28, 1) << 7;
3806e6d15924SDimitry Andric imm |= cmode << 8;
3807e6d15924SDimitry Andric imm |= fieldFromInstruction(Insn, 5, 1) << 12;
3808e6d15924SDimitry Andric
3809e6d15924SDimitry Andric if (cmode == 0xF && Inst.getOpcode() == ARM::MVE_VMVNimmi32)
3810e6d15924SDimitry Andric return MCDisassembler::Fail;
3811e6d15924SDimitry Andric
3812e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
3813e6d15924SDimitry Andric return MCDisassembler::Fail;
3814e6d15924SDimitry Andric
3815e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
3816e6d15924SDimitry Andric
3817e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(ARMVCC::None));
3818e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
3819e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
3820e6d15924SDimitry Andric
3821e6d15924SDimitry Andric return S;
3822e6d15924SDimitry Andric }
3823e6d15924SDimitry Andric
DecodeMVEVADCInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)3824e6d15924SDimitry Andric static DecodeStatus DecodeMVEVADCInstruction(MCInst &Inst, unsigned Insn,
3825145449b1SDimitry Andric uint64_t Address,
3826145449b1SDimitry Andric const MCDisassembler *Decoder) {
3827e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
3828e6d15924SDimitry Andric
3829e6d15924SDimitry Andric unsigned Qd = fieldFromInstruction(Insn, 13, 3);
3830e6d15924SDimitry Andric Qd |= fieldFromInstruction(Insn, 22, 1) << 3;
3831e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
3832e6d15924SDimitry Andric return MCDisassembler::Fail;
3833e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
3834e6d15924SDimitry Andric
3835e6d15924SDimitry Andric unsigned Qn = fieldFromInstruction(Insn, 17, 3);
3836e6d15924SDimitry Andric Qn |= fieldFromInstruction(Insn, 7, 1) << 3;
3837e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
3838e6d15924SDimitry Andric return MCDisassembler::Fail;
3839e6d15924SDimitry Andric unsigned Qm = fieldFromInstruction(Insn, 1, 3);
3840e6d15924SDimitry Andric Qm |= fieldFromInstruction(Insn, 5, 1) << 3;
3841e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
3842e6d15924SDimitry Andric return MCDisassembler::Fail;
3843e6d15924SDimitry Andric if (!fieldFromInstruction(Insn, 12, 1)) // I bit clear => need input FPSCR
3844e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
3845e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(Qd));
3846e6d15924SDimitry Andric
3847e6d15924SDimitry Andric return S;
3848e6d15924SDimitry Andric }
3849e6d15924SDimitry Andric
DecodeVSHLMaxInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)385063faed5bSDimitry Andric static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
3851145449b1SDimitry Andric uint64_t Address,
3852145449b1SDimitry Andric const MCDisassembler *Decoder) {
385330815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
385430815c53SDimitry Andric
3855902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3856902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3857902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3858902a7b52SDimitry Andric Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3859902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 18, 2);
386030815c53SDimitry Andric
386130815c53SDimitry Andric if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
386230815c53SDimitry Andric return MCDisassembler::Fail;
386330815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
386430815c53SDimitry Andric return MCDisassembler::Fail;
38655a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(8 << size));
386630815c53SDimitry Andric
386730815c53SDimitry Andric return S;
386830815c53SDimitry Andric }
386930815c53SDimitry Andric
DecodeShiftRight8Imm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)387063faed5bSDimitry Andric static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
3871145449b1SDimitry Andric uint64_t Address,
3872145449b1SDimitry Andric const MCDisassembler *Decoder) {
38735a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(8 - Val));
387430815c53SDimitry Andric return MCDisassembler::Success;
387530815c53SDimitry Andric }
387630815c53SDimitry Andric
DecodeShiftRight16Imm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)387763faed5bSDimitry Andric static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
3878145449b1SDimitry Andric uint64_t Address,
3879145449b1SDimitry Andric const MCDisassembler *Decoder) {
38805a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(16 - Val));
388130815c53SDimitry Andric return MCDisassembler::Success;
388230815c53SDimitry Andric }
388330815c53SDimitry Andric
DecodeShiftRight32Imm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)388463faed5bSDimitry Andric static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
3885145449b1SDimitry Andric uint64_t Address,
3886145449b1SDimitry Andric const MCDisassembler *Decoder) {
38875a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(32 - Val));
388830815c53SDimitry Andric return MCDisassembler::Success;
388930815c53SDimitry Andric }
389030815c53SDimitry Andric
DecodeShiftRight64Imm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)389163faed5bSDimitry Andric static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
3892145449b1SDimitry Andric uint64_t Address,
3893145449b1SDimitry Andric const MCDisassembler *Decoder) {
38945a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(64 - Val));
389530815c53SDimitry Andric return MCDisassembler::Success;
389630815c53SDimitry Andric }
389730815c53SDimitry Andric
DecodeTBLInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)389863faed5bSDimitry Andric static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
3899145449b1SDimitry Andric uint64_t Address,
3900145449b1SDimitry Andric const MCDisassembler *Decoder) {
390130815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
390230815c53SDimitry Andric
3903902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3904902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3905902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3906902a7b52SDimitry Andric Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
3907902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3908902a7b52SDimitry Andric Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3909902a7b52SDimitry Andric unsigned op = fieldFromInstruction(Insn, 6, 1);
391030815c53SDimitry Andric
391130815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
391230815c53SDimitry Andric return MCDisassembler::Fail;
391330815c53SDimitry Andric if (op) {
391430815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
391530815c53SDimitry Andric return MCDisassembler::Fail; // Writeback
391630815c53SDimitry Andric }
391730815c53SDimitry Andric
391863faed5bSDimitry Andric switch (Inst.getOpcode()) {
391963faed5bSDimitry Andric case ARM::VTBL2:
392063faed5bSDimitry Andric case ARM::VTBX2:
392163faed5bSDimitry Andric if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
392263faed5bSDimitry Andric return MCDisassembler::Fail;
392363faed5bSDimitry Andric break;
392463faed5bSDimitry Andric default:
392563faed5bSDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
392630815c53SDimitry Andric return MCDisassembler::Fail;
392730815c53SDimitry Andric }
392830815c53SDimitry Andric
392930815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
393030815c53SDimitry Andric return MCDisassembler::Fail;
393130815c53SDimitry Andric
393230815c53SDimitry Andric return S;
393330815c53SDimitry Andric }
393430815c53SDimitry Andric
DecodeThumbAddSpecialReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const MCDisassembler * Decoder)393563faed5bSDimitry Andric static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
3936145449b1SDimitry Andric uint64_t Address,
3937145449b1SDimitry Andric const MCDisassembler *Decoder) {
393830815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
393930815c53SDimitry Andric
3940902a7b52SDimitry Andric unsigned dst = fieldFromInstruction(Insn, 8, 3);
3941902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 8);
394230815c53SDimitry Andric
394330815c53SDimitry Andric if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
394430815c53SDimitry Andric return MCDisassembler::Fail;
394530815c53SDimitry Andric
394630815c53SDimitry Andric switch(Inst.getOpcode()) {
394730815c53SDimitry Andric default:
394830815c53SDimitry Andric return MCDisassembler::Fail;
394930815c53SDimitry Andric case ARM::tADR:
395030815c53SDimitry Andric break; // tADR does not explicitly represent the PC as an operand.
395130815c53SDimitry Andric case ARM::tADDrSPi:
39525a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::SP));
395330815c53SDimitry Andric break;
395430815c53SDimitry Andric }
395530815c53SDimitry Andric
39565a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
395730815c53SDimitry Andric return S;
395830815c53SDimitry Andric }
395930815c53SDimitry Andric
DecodeThumbBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)396063faed5bSDimitry Andric static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
3961145449b1SDimitry Andric uint64_t Address,
3962145449b1SDimitry Andric const MCDisassembler *Decoder) {
396363faed5bSDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
396463faed5bSDimitry Andric true, 2, Inst, Decoder))
39655a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<12>(Val << 1)));
396630815c53SDimitry Andric return MCDisassembler::Success;
396730815c53SDimitry Andric }
396830815c53SDimitry Andric
DecodeT2BROperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)396963faed5bSDimitry Andric static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
3970145449b1SDimitry Andric uint64_t Address,
3971145449b1SDimitry Andric const MCDisassembler *Decoder) {
397258b69754SDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
397363faed5bSDimitry Andric true, 4, Inst, Decoder))
39745a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<21>(Val)));
397530815c53SDimitry Andric return MCDisassembler::Success;
397630815c53SDimitry Andric }
397730815c53SDimitry Andric
DecodeThumbCmpBROperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)397863faed5bSDimitry Andric static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
3979145449b1SDimitry Andric uint64_t Address,
3980145449b1SDimitry Andric const MCDisassembler *Decoder) {
39814a16efa3SDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
398263faed5bSDimitry Andric true, 2, Inst, Decoder))
39835a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Val << 1));
398430815c53SDimitry Andric return MCDisassembler::Success;
398530815c53SDimitry Andric }
398630815c53SDimitry Andric
DecodeThumbAddrModeRR(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)398763faed5bSDimitry Andric static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
3988145449b1SDimitry Andric uint64_t Address,
3989145449b1SDimitry Andric const MCDisassembler *Decoder) {
399030815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
399130815c53SDimitry Andric
3992902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 0, 3);
3993902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Val, 3, 3);
399430815c53SDimitry Andric
399530815c53SDimitry Andric if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
399630815c53SDimitry Andric return MCDisassembler::Fail;
399730815c53SDimitry Andric if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
399830815c53SDimitry Andric return MCDisassembler::Fail;
399930815c53SDimitry Andric
400030815c53SDimitry Andric return S;
400130815c53SDimitry Andric }
400230815c53SDimitry Andric
DecodeThumbAddrModeIS(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)400363faed5bSDimitry Andric static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
4004145449b1SDimitry Andric uint64_t Address,
4005145449b1SDimitry Andric const MCDisassembler *Decoder) {
400630815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
400730815c53SDimitry Andric
4008902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 0, 3);
4009902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 3, 5);
401030815c53SDimitry Andric
401130815c53SDimitry Andric if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
401230815c53SDimitry Andric return MCDisassembler::Fail;
40135a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
401430815c53SDimitry Andric
401530815c53SDimitry Andric return S;
401630815c53SDimitry Andric }
401730815c53SDimitry Andric
DecodeThumbAddrModePC(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)401863faed5bSDimitry Andric static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
4019145449b1SDimitry Andric uint64_t Address,
4020145449b1SDimitry Andric const MCDisassembler *Decoder) {
402130815c53SDimitry Andric unsigned imm = Val << 2;
402230815c53SDimitry Andric
40235a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
402430815c53SDimitry Andric tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
402530815c53SDimitry Andric
402630815c53SDimitry Andric return MCDisassembler::Success;
402730815c53SDimitry Andric }
402830815c53SDimitry Andric
DecodeThumbAddrModeSP(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)402963faed5bSDimitry Andric static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
4030145449b1SDimitry Andric uint64_t Address,
4031145449b1SDimitry Andric const MCDisassembler *Decoder) {
40325a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::SP));
40335a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
403430815c53SDimitry Andric
403530815c53SDimitry Andric return MCDisassembler::Success;
403630815c53SDimitry Andric }
403730815c53SDimitry Andric
DecodeT2AddrModeSOReg(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)403863faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
4039145449b1SDimitry Andric uint64_t Address,
4040145449b1SDimitry Andric const MCDisassembler *Decoder) {
404130815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
404230815c53SDimitry Andric
4043902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 6, 4);
4044902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Val, 2, 4);
4045902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 2);
404630815c53SDimitry Andric
4047f8af5cf6SDimitry Andric // Thumb stores cannot use PC as dest register.
4048f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4049f8af5cf6SDimitry Andric case ARM::t2STRHs:
4050f8af5cf6SDimitry Andric case ARM::t2STRBs:
4051f8af5cf6SDimitry Andric case ARM::t2STRs:
4052f8af5cf6SDimitry Andric if (Rn == 15)
4053f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4054c7dac04cSDimitry Andric break;
4055f8af5cf6SDimitry Andric default:
4056f8af5cf6SDimitry Andric break;
4057f8af5cf6SDimitry Andric }
4058f8af5cf6SDimitry Andric
405930815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
406030815c53SDimitry Andric return MCDisassembler::Fail;
406130815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
406230815c53SDimitry Andric return MCDisassembler::Fail;
40635a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
406430815c53SDimitry Andric
406530815c53SDimitry Andric return S;
406630815c53SDimitry Andric }
406730815c53SDimitry Andric
DecodeT2LoadShift(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)406863faed5bSDimitry Andric static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
4069145449b1SDimitry Andric uint64_t Address,
4070145449b1SDimitry Andric const MCDisassembler *Decoder) {
407130815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
407230815c53SDimitry Andric
4073902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4074902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4075f8af5cf6SDimitry Andric
40765a5ac124SDimitry Andric const FeatureBitset &featureBits =
40775a5ac124SDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
40785a5ac124SDimitry Andric
40795a5ac124SDimitry Andric bool hasMP = featureBits[ARM::FeatureMP];
40805a5ac124SDimitry Andric bool hasV7Ops = featureBits[ARM::HasV7Ops];
408167c32a98SDimitry Andric
4082f8af5cf6SDimitry Andric if (Rn == 15) {
408330815c53SDimitry Andric switch (Inst.getOpcode()) {
408430815c53SDimitry Andric case ARM::t2LDRBs:
408530815c53SDimitry Andric Inst.setOpcode(ARM::t2LDRBpci);
408630815c53SDimitry Andric break;
408730815c53SDimitry Andric case ARM::t2LDRHs:
408830815c53SDimitry Andric Inst.setOpcode(ARM::t2LDRHpci);
408930815c53SDimitry Andric break;
409030815c53SDimitry Andric case ARM::t2LDRSHs:
409130815c53SDimitry Andric Inst.setOpcode(ARM::t2LDRSHpci);
409230815c53SDimitry Andric break;
409330815c53SDimitry Andric case ARM::t2LDRSBs:
409430815c53SDimitry Andric Inst.setOpcode(ARM::t2LDRSBpci);
409530815c53SDimitry Andric break;
4096f8af5cf6SDimitry Andric case ARM::t2LDRs:
4097f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRpci);
4098f8af5cf6SDimitry Andric break;
409930815c53SDimitry Andric case ARM::t2PLDs:
4100f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLDpci);
4101f8af5cf6SDimitry Andric break;
4102f8af5cf6SDimitry Andric case ARM::t2PLIs:
4103f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLIpci);
410430815c53SDimitry Andric break;
410530815c53SDimitry Andric default:
410630815c53SDimitry Andric return MCDisassembler::Fail;
410730815c53SDimitry Andric }
410830815c53SDimitry Andric
4109f8af5cf6SDimitry Andric return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
4110f8af5cf6SDimitry Andric }
411130815c53SDimitry Andric
4112f8af5cf6SDimitry Andric if (Rt == 15) {
4113f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4114f8af5cf6SDimitry Andric case ARM::t2LDRSHs:
4115f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4116f8af5cf6SDimitry Andric case ARM::t2LDRHs:
4117f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLDWs);
4118f8af5cf6SDimitry Andric break;
411967c32a98SDimitry Andric case ARM::t2LDRSBs:
412067c32a98SDimitry Andric Inst.setOpcode(ARM::t2PLIs);
4121c7dac04cSDimitry Andric break;
4122f8af5cf6SDimitry Andric default:
4123f8af5cf6SDimitry Andric break;
4124f8af5cf6SDimitry Andric }
4125f8af5cf6SDimitry Andric }
4126f8af5cf6SDimitry Andric
4127f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4128f8af5cf6SDimitry Andric case ARM::t2PLDs:
412967c32a98SDimitry Andric break;
4130f8af5cf6SDimitry Andric case ARM::t2PLIs:
413167c32a98SDimitry Andric if (!hasV7Ops)
413267c32a98SDimitry Andric return MCDisassembler::Fail;
413367c32a98SDimitry Andric break;
413467c32a98SDimitry Andric case ARM::t2PLDWs:
413567c32a98SDimitry Andric if (!hasV7Ops || !hasMP)
413667c32a98SDimitry Andric return MCDisassembler::Fail;
4137f8af5cf6SDimitry Andric break;
4138f8af5cf6SDimitry Andric default:
4139f8af5cf6SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4140f8af5cf6SDimitry Andric return MCDisassembler::Fail;
414130815c53SDimitry Andric }
414230815c53SDimitry Andric
4143902a7b52SDimitry Andric unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
4144902a7b52SDimitry Andric addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
4145902a7b52SDimitry Andric addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
414630815c53SDimitry Andric if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
414730815c53SDimitry Andric return MCDisassembler::Fail;
414830815c53SDimitry Andric
414930815c53SDimitry Andric return S;
415030815c53SDimitry Andric }
415130815c53SDimitry Andric
DecodeT2LoadImm8(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)4152f8af5cf6SDimitry Andric static DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
4153145449b1SDimitry Andric uint64_t Address,
4154145449b1SDimitry Andric const MCDisassembler *Decoder) {
4155f8af5cf6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4156f8af5cf6SDimitry Andric
4157f8af5cf6SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4158f8af5cf6SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4159f8af5cf6SDimitry Andric unsigned U = fieldFromInstruction(Insn, 9, 1);
4160f8af5cf6SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 8);
4161f8af5cf6SDimitry Andric imm |= (U << 8);
4162f8af5cf6SDimitry Andric imm |= (Rn << 9);
416367c32a98SDimitry Andric unsigned add = fieldFromInstruction(Insn, 9, 1);
416467c32a98SDimitry Andric
41655a5ac124SDimitry Andric const FeatureBitset &featureBits =
41665a5ac124SDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
41675a5ac124SDimitry Andric
41685a5ac124SDimitry Andric bool hasMP = featureBits[ARM::FeatureMP];
41695a5ac124SDimitry Andric bool hasV7Ops = featureBits[ARM::HasV7Ops];
4170f8af5cf6SDimitry Andric
4171f8af5cf6SDimitry Andric if (Rn == 15) {
4172f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4173f8af5cf6SDimitry Andric case ARM::t2LDRi8:
4174f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRpci);
4175f8af5cf6SDimitry Andric break;
4176f8af5cf6SDimitry Andric case ARM::t2LDRBi8:
4177f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRBpci);
4178f8af5cf6SDimitry Andric break;
4179f8af5cf6SDimitry Andric case ARM::t2LDRSBi8:
4180f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRSBpci);
4181f8af5cf6SDimitry Andric break;
4182f8af5cf6SDimitry Andric case ARM::t2LDRHi8:
4183f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRHpci);
4184f8af5cf6SDimitry Andric break;
4185f8af5cf6SDimitry Andric case ARM::t2LDRSHi8:
4186f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRSHpci);
4187f8af5cf6SDimitry Andric break;
4188f8af5cf6SDimitry Andric case ARM::t2PLDi8:
4189f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLDpci);
4190f8af5cf6SDimitry Andric break;
4191f8af5cf6SDimitry Andric case ARM::t2PLIi8:
4192f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLIpci);
4193f8af5cf6SDimitry Andric break;
4194f8af5cf6SDimitry Andric default:
4195f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4196f8af5cf6SDimitry Andric }
4197f8af5cf6SDimitry Andric return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
4198f8af5cf6SDimitry Andric }
4199f8af5cf6SDimitry Andric
4200f8af5cf6SDimitry Andric if (Rt == 15) {
4201f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4202f8af5cf6SDimitry Andric case ARM::t2LDRSHi8:
4203f8af5cf6SDimitry Andric return MCDisassembler::Fail;
420467c32a98SDimitry Andric case ARM::t2LDRHi8:
420567c32a98SDimitry Andric if (!add)
420667c32a98SDimitry Andric Inst.setOpcode(ARM::t2PLDWi8);
420767c32a98SDimitry Andric break;
420867c32a98SDimitry Andric case ARM::t2LDRSBi8:
420967c32a98SDimitry Andric Inst.setOpcode(ARM::t2PLIi8);
421067c32a98SDimitry Andric break;
4211f8af5cf6SDimitry Andric default:
4212f8af5cf6SDimitry Andric break;
4213f8af5cf6SDimitry Andric }
4214f8af5cf6SDimitry Andric }
4215f8af5cf6SDimitry Andric
4216f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4217f8af5cf6SDimitry Andric case ARM::t2PLDi8:
421867c32a98SDimitry Andric break;
4219f8af5cf6SDimitry Andric case ARM::t2PLIi8:
422067c32a98SDimitry Andric if (!hasV7Ops)
422167c32a98SDimitry Andric return MCDisassembler::Fail;
422267c32a98SDimitry Andric break;
4223f8af5cf6SDimitry Andric case ARM::t2PLDWi8:
422467c32a98SDimitry Andric if (!hasV7Ops || !hasMP)
422567c32a98SDimitry Andric return MCDisassembler::Fail;
4226f8af5cf6SDimitry Andric break;
4227f8af5cf6SDimitry Andric default:
4228f8af5cf6SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4229f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4230f8af5cf6SDimitry Andric }
4231f8af5cf6SDimitry Andric
4232f8af5cf6SDimitry Andric if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
4233f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4234f8af5cf6SDimitry Andric return S;
4235f8af5cf6SDimitry Andric }
4236f8af5cf6SDimitry Andric
DecodeT2LoadImm12(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)4237f8af5cf6SDimitry Andric static DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
4238145449b1SDimitry Andric uint64_t Address,
4239145449b1SDimitry Andric const MCDisassembler *Decoder) {
4240f8af5cf6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4241f8af5cf6SDimitry Andric
4242f8af5cf6SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4243f8af5cf6SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4244f8af5cf6SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 12);
4245f8af5cf6SDimitry Andric imm |= (Rn << 13);
4246f8af5cf6SDimitry Andric
42475a5ac124SDimitry Andric const FeatureBitset &featureBits =
42485a5ac124SDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
42495a5ac124SDimitry Andric
42505a5ac124SDimitry Andric bool hasMP = featureBits[ARM::FeatureMP];
42515a5ac124SDimitry Andric bool hasV7Ops = featureBits[ARM::HasV7Ops];
425267c32a98SDimitry Andric
4253f8af5cf6SDimitry Andric if (Rn == 15) {
4254f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4255f8af5cf6SDimitry Andric case ARM::t2LDRi12:
4256f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRpci);
4257f8af5cf6SDimitry Andric break;
4258f8af5cf6SDimitry Andric case ARM::t2LDRHi12:
4259f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRHpci);
4260f8af5cf6SDimitry Andric break;
4261f8af5cf6SDimitry Andric case ARM::t2LDRSHi12:
4262f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRSHpci);
4263f8af5cf6SDimitry Andric break;
4264f8af5cf6SDimitry Andric case ARM::t2LDRBi12:
4265f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRBpci);
4266f8af5cf6SDimitry Andric break;
4267f8af5cf6SDimitry Andric case ARM::t2LDRSBi12:
4268f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRSBpci);
4269f8af5cf6SDimitry Andric break;
4270f8af5cf6SDimitry Andric case ARM::t2PLDi12:
4271f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLDpci);
4272f8af5cf6SDimitry Andric break;
4273f8af5cf6SDimitry Andric case ARM::t2PLIi12:
4274f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLIpci);
4275f8af5cf6SDimitry Andric break;
4276f8af5cf6SDimitry Andric default:
4277f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4278f8af5cf6SDimitry Andric }
4279f8af5cf6SDimitry Andric return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
4280f8af5cf6SDimitry Andric }
4281f8af5cf6SDimitry Andric
4282f8af5cf6SDimitry Andric if (Rt == 15) {
4283f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4284f8af5cf6SDimitry Andric case ARM::t2LDRSHi12:
4285f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4286f8af5cf6SDimitry Andric case ARM::t2LDRHi12:
428767c32a98SDimitry Andric Inst.setOpcode(ARM::t2PLDWi12);
428867c32a98SDimitry Andric break;
428967c32a98SDimitry Andric case ARM::t2LDRSBi12:
429067c32a98SDimitry Andric Inst.setOpcode(ARM::t2PLIi12);
4291f8af5cf6SDimitry Andric break;
4292f8af5cf6SDimitry Andric default:
4293f8af5cf6SDimitry Andric break;
4294f8af5cf6SDimitry Andric }
4295f8af5cf6SDimitry Andric }
4296f8af5cf6SDimitry Andric
4297f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4298f8af5cf6SDimitry Andric case ARM::t2PLDi12:
429967c32a98SDimitry Andric break;
4300f8af5cf6SDimitry Andric case ARM::t2PLIi12:
430167c32a98SDimitry Andric if (!hasV7Ops)
430267c32a98SDimitry Andric return MCDisassembler::Fail;
430367c32a98SDimitry Andric break;
430467c32a98SDimitry Andric case ARM::t2PLDWi12:
430567c32a98SDimitry Andric if (!hasV7Ops || !hasMP)
430667c32a98SDimitry Andric return MCDisassembler::Fail;
4307f8af5cf6SDimitry Andric break;
4308f8af5cf6SDimitry Andric default:
4309f8af5cf6SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4310f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4311f8af5cf6SDimitry Andric }
4312f8af5cf6SDimitry Andric
4313f8af5cf6SDimitry Andric if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
4314f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4315f8af5cf6SDimitry Andric return S;
4316f8af5cf6SDimitry Andric }
4317f8af5cf6SDimitry Andric
DecodeT2LoadT(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)4318145449b1SDimitry Andric static DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn, uint64_t Address,
4319145449b1SDimitry Andric const MCDisassembler *Decoder) {
4320f8af5cf6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4321f8af5cf6SDimitry Andric
4322f8af5cf6SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4323f8af5cf6SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4324f8af5cf6SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 8);
4325f8af5cf6SDimitry Andric imm |= (Rn << 9);
4326f8af5cf6SDimitry Andric
4327f8af5cf6SDimitry Andric if (Rn == 15) {
4328f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4329f8af5cf6SDimitry Andric case ARM::t2LDRT:
4330f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRpci);
4331f8af5cf6SDimitry Andric break;
4332f8af5cf6SDimitry Andric case ARM::t2LDRBT:
4333f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRBpci);
4334f8af5cf6SDimitry Andric break;
4335f8af5cf6SDimitry Andric case ARM::t2LDRHT:
4336f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRHpci);
4337f8af5cf6SDimitry Andric break;
4338f8af5cf6SDimitry Andric case ARM::t2LDRSBT:
4339f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRSBpci);
4340f8af5cf6SDimitry Andric break;
4341f8af5cf6SDimitry Andric case ARM::t2LDRSHT:
4342f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRSHpci);
4343f8af5cf6SDimitry Andric break;
4344f8af5cf6SDimitry Andric default:
4345f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4346f8af5cf6SDimitry Andric }
4347f8af5cf6SDimitry Andric return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
4348f8af5cf6SDimitry Andric }
4349f8af5cf6SDimitry Andric
4350f8af5cf6SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4351f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4352f8af5cf6SDimitry Andric if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
4353f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4354f8af5cf6SDimitry Andric return S;
4355f8af5cf6SDimitry Andric }
4356f8af5cf6SDimitry Andric
DecodeT2LoadLabel(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)4357f8af5cf6SDimitry Andric static DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
4358145449b1SDimitry Andric uint64_t Address,
4359145449b1SDimitry Andric const MCDisassembler *Decoder) {
4360f8af5cf6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4361f8af5cf6SDimitry Andric
4362f8af5cf6SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4363f8af5cf6SDimitry Andric unsigned U = fieldFromInstruction(Insn, 23, 1);
4364f8af5cf6SDimitry Andric int imm = fieldFromInstruction(Insn, 0, 12);
4365f8af5cf6SDimitry Andric
43665a5ac124SDimitry Andric const FeatureBitset &featureBits =
43675a5ac124SDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
43685a5ac124SDimitry Andric
43695a5ac124SDimitry Andric bool hasV7Ops = featureBits[ARM::HasV7Ops];
437067c32a98SDimitry Andric
4371f8af5cf6SDimitry Andric if (Rt == 15) {
4372f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4373f8af5cf6SDimitry Andric case ARM::t2LDRBpci:
4374f8af5cf6SDimitry Andric case ARM::t2LDRHpci:
4375f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLDpci);
4376f8af5cf6SDimitry Andric break;
4377f8af5cf6SDimitry Andric case ARM::t2LDRSBpci:
4378f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLIpci);
4379f8af5cf6SDimitry Andric break;
4380f8af5cf6SDimitry Andric case ARM::t2LDRSHpci:
4381f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4382f8af5cf6SDimitry Andric default:
4383f8af5cf6SDimitry Andric break;
4384f8af5cf6SDimitry Andric }
4385f8af5cf6SDimitry Andric }
4386f8af5cf6SDimitry Andric
4387f8af5cf6SDimitry Andric switch(Inst.getOpcode()) {
4388f8af5cf6SDimitry Andric case ARM::t2PLDpci:
438967c32a98SDimitry Andric break;
4390f8af5cf6SDimitry Andric case ARM::t2PLIpci:
439167c32a98SDimitry Andric if (!hasV7Ops)
439267c32a98SDimitry Andric return MCDisassembler::Fail;
4393f8af5cf6SDimitry Andric break;
4394f8af5cf6SDimitry Andric default:
4395f8af5cf6SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4396f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4397f8af5cf6SDimitry Andric }
4398f8af5cf6SDimitry Andric
4399f8af5cf6SDimitry Andric if (!U) {
4400f8af5cf6SDimitry Andric // Special case for #-0.
4401f8af5cf6SDimitry Andric if (imm == 0)
4402f8af5cf6SDimitry Andric imm = INT32_MIN;
4403f8af5cf6SDimitry Andric else
4404f8af5cf6SDimitry Andric imm = -imm;
4405f8af5cf6SDimitry Andric }
44065a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
4407f8af5cf6SDimitry Andric
4408f8af5cf6SDimitry Andric return S;
4409f8af5cf6SDimitry Andric }
4410f8af5cf6SDimitry Andric
DecodeT2Imm8S4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4411145449b1SDimitry Andric static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, uint64_t Address,
4412145449b1SDimitry Andric const MCDisassembler *Decoder) {
441358b69754SDimitry Andric if (Val == 0)
44145a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(INT32_MIN));
441558b69754SDimitry Andric else {
441630815c53SDimitry Andric int imm = Val & 0xFF;
441758b69754SDimitry Andric
441830815c53SDimitry Andric if (!(Val & 0x100)) imm *= -1;
44195a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm * 4));
442058b69754SDimitry Andric }
442130815c53SDimitry Andric
442230815c53SDimitry Andric return MCDisassembler::Success;
442330815c53SDimitry Andric }
442430815c53SDimitry Andric
DecodeT2Imm7S4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4425e6d15924SDimitry Andric static DecodeStatus DecodeT2Imm7S4(MCInst &Inst, unsigned Val, uint64_t Address,
4426145449b1SDimitry Andric const MCDisassembler *Decoder) {
4427e6d15924SDimitry Andric if (Val == 0)
4428e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(INT32_MIN));
4429e6d15924SDimitry Andric else {
4430e6d15924SDimitry Andric int imm = Val & 0x7F;
4431e6d15924SDimitry Andric
4432e6d15924SDimitry Andric if (!(Val & 0x80))
4433e6d15924SDimitry Andric imm *= -1;
4434e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(imm * 4));
4435e6d15924SDimitry Andric }
4436e6d15924SDimitry Andric
4437e6d15924SDimitry Andric return MCDisassembler::Success;
4438e6d15924SDimitry Andric }
4439e6d15924SDimitry Andric
DecodeT2AddrModeImm8s4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)444063faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
4441145449b1SDimitry Andric uint64_t Address,
4442145449b1SDimitry Andric const MCDisassembler *Decoder) {
444330815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
444430815c53SDimitry Andric
4445902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 9, 4);
4446902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 9);
444730815c53SDimitry Andric
444830815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
444930815c53SDimitry Andric return MCDisassembler::Fail;
445030815c53SDimitry Andric if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
445130815c53SDimitry Andric return MCDisassembler::Fail;
445230815c53SDimitry Andric
445330815c53SDimitry Andric return S;
445430815c53SDimitry Andric }
445530815c53SDimitry Andric
DecodeT2AddrModeImm7s4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4456e6d15924SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7s4(MCInst &Inst, unsigned Val,
4457e6d15924SDimitry Andric uint64_t Address,
4458145449b1SDimitry Andric const MCDisassembler *Decoder) {
4459e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4460e6d15924SDimitry Andric
4461e6d15924SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 8, 4);
4462e6d15924SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 8);
4463e6d15924SDimitry Andric
4464e6d15924SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4465e6d15924SDimitry Andric return MCDisassembler::Fail;
4466e6d15924SDimitry Andric if (!Check(S, DecodeT2Imm7S4(Inst, imm, Address, Decoder)))
4467e6d15924SDimitry Andric return MCDisassembler::Fail;
4468e6d15924SDimitry Andric
4469e6d15924SDimitry Andric return S;
4470e6d15924SDimitry Andric }
4471e6d15924SDimitry Andric
DecodeT2AddrModeImm0_1020s4(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)447263faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst, unsigned Val,
4473145449b1SDimitry Andric uint64_t Address,
4474145449b1SDimitry Andric const MCDisassembler *Decoder) {
447530815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
447630815c53SDimitry Andric
4477902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 8, 4);
4478902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 8);
447930815c53SDimitry Andric
448030815c53SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
448130815c53SDimitry Andric return MCDisassembler::Fail;
448230815c53SDimitry Andric
44835a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
448430815c53SDimitry Andric
448530815c53SDimitry Andric return S;
448630815c53SDimitry Andric }
448730815c53SDimitry Andric
DecodeT2Imm8(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4488145449b1SDimitry Andric static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, uint64_t Address,
4489145449b1SDimitry Andric const MCDisassembler *Decoder) {
449030815c53SDimitry Andric int imm = Val & 0xFF;
449130815c53SDimitry Andric if (Val == 0)
449230815c53SDimitry Andric imm = INT32_MIN;
449330815c53SDimitry Andric else if (!(Val & 0x100))
449430815c53SDimitry Andric imm *= -1;
44955a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
449630815c53SDimitry Andric
449730815c53SDimitry Andric return MCDisassembler::Success;
449830815c53SDimitry Andric }
449930815c53SDimitry Andric
4500e6d15924SDimitry Andric template <int shift>
DecodeT2Imm7(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4501145449b1SDimitry Andric static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, uint64_t Address,
4502145449b1SDimitry Andric const MCDisassembler *Decoder) {
4503e6d15924SDimitry Andric int imm = Val & 0x7F;
4504e6d15924SDimitry Andric if (Val == 0)
4505e6d15924SDimitry Andric imm = INT32_MIN;
4506e6d15924SDimitry Andric else if (!(Val & 0x80))
4507e6d15924SDimitry Andric imm *= -1;
4508e6d15924SDimitry Andric if (imm != INT32_MIN)
4509e6d15924SDimitry Andric imm *= (1U << shift);
4510e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
4511e6d15924SDimitry Andric
4512e6d15924SDimitry Andric return MCDisassembler::Success;
4513e6d15924SDimitry Andric }
4514e6d15924SDimitry Andric
DecodeT2AddrModeImm8(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)451563faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
4516145449b1SDimitry Andric uint64_t Address,
4517145449b1SDimitry Andric const MCDisassembler *Decoder) {
451830815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
451930815c53SDimitry Andric
4520902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 9, 4);
4521902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 9);
452230815c53SDimitry Andric
4523f8af5cf6SDimitry Andric // Thumb stores cannot use PC as dest register.
4524f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4525f8af5cf6SDimitry Andric case ARM::t2STRT:
4526f8af5cf6SDimitry Andric case ARM::t2STRBT:
4527f8af5cf6SDimitry Andric case ARM::t2STRHT:
4528f8af5cf6SDimitry Andric case ARM::t2STRi8:
4529f8af5cf6SDimitry Andric case ARM::t2STRHi8:
4530f8af5cf6SDimitry Andric case ARM::t2STRBi8:
4531f8af5cf6SDimitry Andric if (Rn == 15)
4532f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4533f8af5cf6SDimitry Andric break;
4534f8af5cf6SDimitry Andric default:
4535f8af5cf6SDimitry Andric break;
4536f8af5cf6SDimitry Andric }
4537f8af5cf6SDimitry Andric
453830815c53SDimitry Andric // Some instructions always use an additive offset.
453930815c53SDimitry Andric switch (Inst.getOpcode()) {
454030815c53SDimitry Andric case ARM::t2LDRT:
454130815c53SDimitry Andric case ARM::t2LDRBT:
454230815c53SDimitry Andric case ARM::t2LDRHT:
454330815c53SDimitry Andric case ARM::t2LDRSBT:
454430815c53SDimitry Andric case ARM::t2LDRSHT:
454530815c53SDimitry Andric case ARM::t2STRT:
454630815c53SDimitry Andric case ARM::t2STRBT:
454730815c53SDimitry Andric case ARM::t2STRHT:
454830815c53SDimitry Andric imm |= 0x100;
454930815c53SDimitry Andric break;
455030815c53SDimitry Andric default:
455130815c53SDimitry Andric break;
455230815c53SDimitry Andric }
455330815c53SDimitry Andric
455430815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
455530815c53SDimitry Andric return MCDisassembler::Fail;
455630815c53SDimitry Andric if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
455730815c53SDimitry Andric return MCDisassembler::Fail;
455830815c53SDimitry Andric
455930815c53SDimitry Andric return S;
456030815c53SDimitry Andric }
456130815c53SDimitry Andric
4562e6d15924SDimitry Andric template <int shift>
DecodeTAddrModeImm7(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4563e6d15924SDimitry Andric static DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val,
4564e6d15924SDimitry Andric uint64_t Address,
4565145449b1SDimitry Andric const MCDisassembler *Decoder) {
4566e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4567e6d15924SDimitry Andric
4568e6d15924SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 8, 3);
4569e6d15924SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 8);
4570e6d15924SDimitry Andric
4571e6d15924SDimitry Andric if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
4572e6d15924SDimitry Andric return MCDisassembler::Fail;
4573e6d15924SDimitry Andric if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
4574e6d15924SDimitry Andric return MCDisassembler::Fail;
4575e6d15924SDimitry Andric
4576e6d15924SDimitry Andric return S;
4577e6d15924SDimitry Andric }
4578e6d15924SDimitry Andric
4579e6d15924SDimitry Andric template <int shift, int WriteBack>
DecodeT2AddrModeImm7(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4580e6d15924SDimitry Andric static DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val,
4581e6d15924SDimitry Andric uint64_t Address,
4582145449b1SDimitry Andric const MCDisassembler *Decoder) {
4583e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4584e6d15924SDimitry Andric
4585e6d15924SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 8, 4);
4586e6d15924SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 8);
4587e6d15924SDimitry Andric if (WriteBack) {
4588e6d15924SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4589e6d15924SDimitry Andric return MCDisassembler::Fail;
4590e6d15924SDimitry Andric } else if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4591e6d15924SDimitry Andric return MCDisassembler::Fail;
4592e6d15924SDimitry Andric if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder)))
4593e6d15924SDimitry Andric return MCDisassembler::Fail;
4594e6d15924SDimitry Andric
4595e6d15924SDimitry Andric return S;
4596e6d15924SDimitry Andric }
4597e6d15924SDimitry Andric
DecodeT2LdStPre(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)459863faed5bSDimitry Andric static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
4599145449b1SDimitry Andric uint64_t Address,
4600145449b1SDimitry Andric const MCDisassembler *Decoder) {
460130815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
460230815c53SDimitry Andric
4603902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4604902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4605902a7b52SDimitry Andric unsigned addr = fieldFromInstruction(Insn, 0, 8);
4606902a7b52SDimitry Andric addr |= fieldFromInstruction(Insn, 9, 1) << 8;
460730815c53SDimitry Andric addr |= Rn << 9;
4608902a7b52SDimitry Andric unsigned load = fieldFromInstruction(Insn, 20, 1);
460930815c53SDimitry Andric
4610f8af5cf6SDimitry Andric if (Rn == 15) {
4611f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4612f8af5cf6SDimitry Andric case ARM::t2LDR_PRE:
4613f8af5cf6SDimitry Andric case ARM::t2LDR_POST:
4614f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRpci);
4615f8af5cf6SDimitry Andric break;
4616f8af5cf6SDimitry Andric case ARM::t2LDRB_PRE:
4617f8af5cf6SDimitry Andric case ARM::t2LDRB_POST:
4618f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRBpci);
4619f8af5cf6SDimitry Andric break;
4620f8af5cf6SDimitry Andric case ARM::t2LDRH_PRE:
4621f8af5cf6SDimitry Andric case ARM::t2LDRH_POST:
4622f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRHpci);
4623f8af5cf6SDimitry Andric break;
4624f8af5cf6SDimitry Andric case ARM::t2LDRSB_PRE:
4625f8af5cf6SDimitry Andric case ARM::t2LDRSB_POST:
4626f8af5cf6SDimitry Andric if (Rt == 15)
4627f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2PLIpci);
4628f8af5cf6SDimitry Andric else
4629f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRSBpci);
4630f8af5cf6SDimitry Andric break;
4631f8af5cf6SDimitry Andric case ARM::t2LDRSH_PRE:
4632f8af5cf6SDimitry Andric case ARM::t2LDRSH_POST:
4633f8af5cf6SDimitry Andric Inst.setOpcode(ARM::t2LDRSHpci);
4634f8af5cf6SDimitry Andric break;
4635f8af5cf6SDimitry Andric default:
4636f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4637f8af5cf6SDimitry Andric }
4638f8af5cf6SDimitry Andric return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
4639f8af5cf6SDimitry Andric }
4640f8af5cf6SDimitry Andric
464130815c53SDimitry Andric if (!load) {
464230815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
464330815c53SDimitry Andric return MCDisassembler::Fail;
464430815c53SDimitry Andric }
464530815c53SDimitry Andric
46464a16efa3SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
464730815c53SDimitry Andric return MCDisassembler::Fail;
464830815c53SDimitry Andric
464930815c53SDimitry Andric if (load) {
465030815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
465130815c53SDimitry Andric return MCDisassembler::Fail;
465230815c53SDimitry Andric }
465330815c53SDimitry Andric
465430815c53SDimitry Andric if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
465530815c53SDimitry Andric return MCDisassembler::Fail;
465630815c53SDimitry Andric
465730815c53SDimitry Andric return S;
465830815c53SDimitry Andric }
465930815c53SDimitry Andric
DecodeT2AddrModeImm12(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)466063faed5bSDimitry Andric static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
4661145449b1SDimitry Andric uint64_t Address,
4662145449b1SDimitry Andric const MCDisassembler *Decoder) {
466330815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
466430815c53SDimitry Andric
4665902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 13, 4);
4666902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 12);
466730815c53SDimitry Andric
4668f8af5cf6SDimitry Andric // Thumb stores cannot use PC as dest register.
4669f8af5cf6SDimitry Andric switch (Inst.getOpcode()) {
4670f8af5cf6SDimitry Andric case ARM::t2STRi12:
4671f8af5cf6SDimitry Andric case ARM::t2STRBi12:
4672f8af5cf6SDimitry Andric case ARM::t2STRHi12:
4673f8af5cf6SDimitry Andric if (Rn == 15)
4674f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4675c7dac04cSDimitry Andric break;
4676f8af5cf6SDimitry Andric default:
4677f8af5cf6SDimitry Andric break;
4678f8af5cf6SDimitry Andric }
4679f8af5cf6SDimitry Andric
468030815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
468130815c53SDimitry Andric return MCDisassembler::Fail;
46825a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
468330815c53SDimitry Andric
468430815c53SDimitry Andric return S;
468530815c53SDimitry Andric }
468630815c53SDimitry Andric
DecodeThumbAddSPImm(MCInst & Inst,uint16_t Insn,uint64_t Address,const MCDisassembler * Decoder)468763faed5bSDimitry Andric static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
4688145449b1SDimitry Andric uint64_t Address,
4689145449b1SDimitry Andric const MCDisassembler *Decoder) {
4690902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 7);
469130815c53SDimitry Andric
46925a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::SP));
46935a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::SP));
46945a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
469530815c53SDimitry Andric
469630815c53SDimitry Andric return MCDisassembler::Success;
469730815c53SDimitry Andric }
469830815c53SDimitry Andric
DecodeThumbAddSPReg(MCInst & Inst,uint16_t Insn,uint64_t Address,const MCDisassembler * Decoder)469963faed5bSDimitry Andric static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
4700145449b1SDimitry Andric uint64_t Address,
4701145449b1SDimitry Andric const MCDisassembler *Decoder) {
470230815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
470330815c53SDimitry Andric
470430815c53SDimitry Andric if (Inst.getOpcode() == ARM::tADDrSP) {
4705902a7b52SDimitry Andric unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
4706902a7b52SDimitry Andric Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
470730815c53SDimitry Andric
470830815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
470930815c53SDimitry Andric return MCDisassembler::Fail;
47105a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::SP));
471130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
471230815c53SDimitry Andric return MCDisassembler::Fail;
471330815c53SDimitry Andric } else if (Inst.getOpcode() == ARM::tADDspr) {
4714902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 3, 4);
471530815c53SDimitry Andric
47165a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::SP));
47175a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::SP));
471830815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
471930815c53SDimitry Andric return MCDisassembler::Fail;
472030815c53SDimitry Andric }
472130815c53SDimitry Andric
472230815c53SDimitry Andric return S;
472330815c53SDimitry Andric }
472430815c53SDimitry Andric
DecodeThumbCPS(MCInst & Inst,uint16_t Insn,uint64_t Address,const MCDisassembler * Decoder)472563faed5bSDimitry Andric static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
4726145449b1SDimitry Andric uint64_t Address,
4727145449b1SDimitry Andric const MCDisassembler *Decoder) {
4728902a7b52SDimitry Andric unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
4729902a7b52SDimitry Andric unsigned flags = fieldFromInstruction(Insn, 0, 3);
473030815c53SDimitry Andric
47315a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imod));
47325a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(flags));
473330815c53SDimitry Andric
473430815c53SDimitry Andric return MCDisassembler::Success;
473530815c53SDimitry Andric }
473630815c53SDimitry Andric
DecodePostIdxReg(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)473763faed5bSDimitry Andric static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
4738145449b1SDimitry Andric uint64_t Address,
4739145449b1SDimitry Andric const MCDisassembler *Decoder) {
474030815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4741902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4742902a7b52SDimitry Andric unsigned add = fieldFromInstruction(Insn, 4, 1);
474330815c53SDimitry Andric
474463faed5bSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
474530815c53SDimitry Andric return MCDisassembler::Fail;
47465a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(add));
474730815c53SDimitry Andric
474830815c53SDimitry Andric return S;
474930815c53SDimitry Andric }
475030815c53SDimitry Andric
DecodeMveAddrModeRQ(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)4751e6d15924SDimitry Andric static DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn,
4752145449b1SDimitry Andric uint64_t Address,
4753145449b1SDimitry Andric const MCDisassembler *Decoder) {
4754e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4755e6d15924SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 3, 4);
4756e6d15924SDimitry Andric unsigned Qm = fieldFromInstruction(Insn, 0, 3);
4757e6d15924SDimitry Andric
4758e6d15924SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4759e6d15924SDimitry Andric return MCDisassembler::Fail;
4760e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
4761e6d15924SDimitry Andric return MCDisassembler::Fail;
4762e6d15924SDimitry Andric
4763e6d15924SDimitry Andric return S;
4764e6d15924SDimitry Andric }
4765e6d15924SDimitry Andric
4766e6d15924SDimitry Andric template <int shift>
DecodeMveAddrModeQ(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)4767e6d15924SDimitry Andric static DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn,
4768145449b1SDimitry Andric uint64_t Address,
4769145449b1SDimitry Andric const MCDisassembler *Decoder) {
4770e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
4771e6d15924SDimitry Andric unsigned Qm = fieldFromInstruction(Insn, 8, 3);
4772e6d15924SDimitry Andric int imm = fieldFromInstruction(Insn, 0, 7);
4773e6d15924SDimitry Andric
4774e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
4775e6d15924SDimitry Andric return MCDisassembler::Fail;
4776e6d15924SDimitry Andric
4777e6d15924SDimitry Andric if(!fieldFromInstruction(Insn, 7, 1)) {
4778e6d15924SDimitry Andric if (imm == 0)
4779e6d15924SDimitry Andric imm = INT32_MIN; // indicate -0
4780e6d15924SDimitry Andric else
4781e6d15924SDimitry Andric imm *= -1;
4782e6d15924SDimitry Andric }
4783e6d15924SDimitry Andric if (imm != INT32_MIN)
4784e6d15924SDimitry Andric imm *= (1U << shift);
4785e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
4786e6d15924SDimitry Andric
4787e6d15924SDimitry Andric return S;
4788e6d15924SDimitry Andric }
4789e6d15924SDimitry Andric
DecodeThumbBLXOffset(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)479063faed5bSDimitry Andric static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
4791145449b1SDimitry Andric uint64_t Address,
4792145449b1SDimitry Andric const MCDisassembler *Decoder) {
479358b69754SDimitry Andric // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
479458b69754SDimitry Andric // Note only one trailing zero not two. Also the J1 and J2 values are from
479558b69754SDimitry Andric // the encoded instruction. So here change to I1 and I2 values via:
479658b69754SDimitry Andric // I1 = NOT(J1 EOR S);
479758b69754SDimitry Andric // I2 = NOT(J2 EOR S);
479858b69754SDimitry Andric // and build the imm32 with two trailing zeros as documented:
479958b69754SDimitry Andric // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
480058b69754SDimitry Andric unsigned S = (Val >> 23) & 1;
480158b69754SDimitry Andric unsigned J1 = (Val >> 22) & 1;
480258b69754SDimitry Andric unsigned J2 = (Val >> 21) & 1;
480358b69754SDimitry Andric unsigned I1 = !(J1 ^ S);
480458b69754SDimitry Andric unsigned I2 = !(J2 ^ S);
480558b69754SDimitry Andric unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
480658b69754SDimitry Andric int imm32 = SignExtend32<25>(tmp << 1);
480758b69754SDimitry Andric
480830815c53SDimitry Andric if (!tryAddingSymbolicOperand(Address,
480958b69754SDimitry Andric (Address & ~2u) + imm32 + 4,
481030815c53SDimitry Andric true, 4, Inst, Decoder))
48115a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm32));
481230815c53SDimitry Andric return MCDisassembler::Success;
481330815c53SDimitry Andric }
481430815c53SDimitry Andric
DecodeCoprocessor(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)481563faed5bSDimitry Andric static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
4816145449b1SDimitry Andric uint64_t Address,
4817145449b1SDimitry Andric const MCDisassembler *Decoder) {
481830815c53SDimitry Andric if (Val == 0xA || Val == 0xB)
481930815c53SDimitry Andric return MCDisassembler::Fail;
482030815c53SDimitry Andric
48215a5ac124SDimitry Andric const FeatureBitset &featureBits =
48225a5ac124SDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
48235a5ac124SDimitry Andric
4824e6d15924SDimitry Andric if (!isValidCoprocessorNumber(Val, featureBits))
4825f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4826f8af5cf6SDimitry Andric
48275a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
482830815c53SDimitry Andric return MCDisassembler::Success;
482930815c53SDimitry Andric }
483030815c53SDimitry Andric
DecodeThumbTableBranch(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)4831145449b1SDimitry Andric static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
4832145449b1SDimitry Andric uint64_t Address,
4833145449b1SDimitry Andric const MCDisassembler *Decoder) {
4834b60736ecSDimitry Andric const FeatureBitset &FeatureBits =
4835b60736ecSDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
483630815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
483730815c53SDimitry Andric
4838902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4839902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
484030815c53SDimitry Andric
4841b60736ecSDimitry Andric if (Rn == 13 && !FeatureBits[ARM::HasV8Ops]) S = MCDisassembler::SoftFail;
484230815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
484330815c53SDimitry Andric return MCDisassembler::Fail;
484430815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
484530815c53SDimitry Andric return MCDisassembler::Fail;
484630815c53SDimitry Andric return S;
484730815c53SDimitry Andric }
484830815c53SDimitry Andric
DecodeThumb2BCCInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)4849145449b1SDimitry Andric static DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
4850145449b1SDimitry Andric uint64_t Address,
4851145449b1SDimitry Andric const MCDisassembler *Decoder) {
485230815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
485330815c53SDimitry Andric
4854902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 22, 4);
485530815c53SDimitry Andric if (pred == 0xE || pred == 0xF) {
4856902a7b52SDimitry Andric unsigned opc = fieldFromInstruction(Insn, 4, 28);
485730815c53SDimitry Andric switch (opc) {
485830815c53SDimitry Andric default:
485930815c53SDimitry Andric return MCDisassembler::Fail;
486030815c53SDimitry Andric case 0xf3bf8f4:
486130815c53SDimitry Andric Inst.setOpcode(ARM::t2DSB);
486230815c53SDimitry Andric break;
486330815c53SDimitry Andric case 0xf3bf8f5:
486430815c53SDimitry Andric Inst.setOpcode(ARM::t2DMB);
486530815c53SDimitry Andric break;
486630815c53SDimitry Andric case 0xf3bf8f6:
486730815c53SDimitry Andric Inst.setOpcode(ARM::t2ISB);
486830815c53SDimitry Andric break;
486930815c53SDimitry Andric }
487030815c53SDimitry Andric
4871902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 4);
487230815c53SDimitry Andric return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
487330815c53SDimitry Andric }
487430815c53SDimitry Andric
4875902a7b52SDimitry Andric unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
4876902a7b52SDimitry Andric brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
4877902a7b52SDimitry Andric brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
4878902a7b52SDimitry Andric brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
4879902a7b52SDimitry Andric brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
488030815c53SDimitry Andric
488130815c53SDimitry Andric if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
488230815c53SDimitry Andric return MCDisassembler::Fail;
488330815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
488430815c53SDimitry Andric return MCDisassembler::Fail;
488530815c53SDimitry Andric
488630815c53SDimitry Andric return S;
488730815c53SDimitry Andric }
488830815c53SDimitry Andric
488930815c53SDimitry Andric // Decode a shifted immediate operand. These basically consist
489030815c53SDimitry Andric // of an 8-bit value, and a 4-bit directive that specifies either
489130815c53SDimitry Andric // a splat operation or a rotation.
DecodeT2SOImm(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4892145449b1SDimitry Andric static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, uint64_t Address,
4893145449b1SDimitry Andric const MCDisassembler *Decoder) {
4894902a7b52SDimitry Andric unsigned ctrl = fieldFromInstruction(Val, 10, 2);
489530815c53SDimitry Andric if (ctrl == 0) {
4896902a7b52SDimitry Andric unsigned byte = fieldFromInstruction(Val, 8, 2);
4897902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Val, 0, 8);
489830815c53SDimitry Andric switch (byte) {
489930815c53SDimitry Andric case 0:
49005a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
490130815c53SDimitry Andric break;
490230815c53SDimitry Andric case 1:
49035a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm((imm << 16) | imm));
490430815c53SDimitry Andric break;
490530815c53SDimitry Andric case 2:
49065a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 8)));
490730815c53SDimitry Andric break;
490830815c53SDimitry Andric case 3:
49095a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm((imm << 24) | (imm << 16) |
491030815c53SDimitry Andric (imm << 8) | imm));
491130815c53SDimitry Andric break;
491230815c53SDimitry Andric }
491330815c53SDimitry Andric } else {
4914902a7b52SDimitry Andric unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
4915902a7b52SDimitry Andric unsigned rot = fieldFromInstruction(Val, 7, 5);
49167fa27ce4SDimitry Andric unsigned imm = llvm::rotr<uint32_t>(unrot, rot);
49175a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm));
491830815c53SDimitry Andric }
491930815c53SDimitry Andric
492030815c53SDimitry Andric return MCDisassembler::Success;
492130815c53SDimitry Andric }
492230815c53SDimitry Andric
DecodeThumbBCCTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4923145449b1SDimitry Andric static DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
4924145449b1SDimitry Andric uint64_t Address,
4925145449b1SDimitry Andric const MCDisassembler *Decoder) {
492658b69754SDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
492763faed5bSDimitry Andric true, 2, Inst, Decoder))
49285a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend32<9>(Val << 1)));
492930815c53SDimitry Andric return MCDisassembler::Success;
493030815c53SDimitry Andric }
493130815c53SDimitry Andric
DecodeThumbBLTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)493263faed5bSDimitry Andric static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
493371d5a254SDimitry Andric uint64_t Address,
4934145449b1SDimitry Andric const MCDisassembler *Decoder) {
493558b69754SDimitry Andric // Val is passed in as S:J1:J2:imm10:imm11
493658b69754SDimitry Andric // Note no trailing zero after imm11. Also the J1 and J2 values are from
493758b69754SDimitry Andric // the encoded instruction. So here change to I1 and I2 values via:
493858b69754SDimitry Andric // I1 = NOT(J1 EOR S);
493958b69754SDimitry Andric // I2 = NOT(J2 EOR S);
494058b69754SDimitry Andric // and build the imm32 with one trailing zero as documented:
494158b69754SDimitry Andric // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
494258b69754SDimitry Andric unsigned S = (Val >> 23) & 1;
494358b69754SDimitry Andric unsigned J1 = (Val >> 22) & 1;
494458b69754SDimitry Andric unsigned J2 = (Val >> 21) & 1;
494558b69754SDimitry Andric unsigned I1 = !(J1 ^ S);
494658b69754SDimitry Andric unsigned I2 = !(J2 ^ S);
494758b69754SDimitry Andric unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
494858b69754SDimitry Andric int imm32 = SignExtend32<25>(tmp << 1);
494958b69754SDimitry Andric
495058b69754SDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
495163faed5bSDimitry Andric true, 4, Inst, Decoder))
49525a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(imm32));
495330815c53SDimitry Andric return MCDisassembler::Success;
495430815c53SDimitry Andric }
495530815c53SDimitry Andric
DecodeMemBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)495663faed5bSDimitry Andric static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
4957145449b1SDimitry Andric uint64_t Address,
4958145449b1SDimitry Andric const MCDisassembler *Decoder) {
495958b69754SDimitry Andric if (Val & ~0xf)
496030815c53SDimitry Andric return MCDisassembler::Fail;
496130815c53SDimitry Andric
49625a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
496330815c53SDimitry Andric return MCDisassembler::Success;
496430815c53SDimitry Andric }
496530815c53SDimitry Andric
DecodeInstSyncBarrierOption(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4966f8af5cf6SDimitry Andric static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
4967145449b1SDimitry Andric uint64_t Address,
4968145449b1SDimitry Andric const MCDisassembler *Decoder) {
4969f8af5cf6SDimitry Andric if (Val & ~0xf)
4970f8af5cf6SDimitry Andric return MCDisassembler::Fail;
4971f8af5cf6SDimitry Andric
49725a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
4973f8af5cf6SDimitry Andric return MCDisassembler::Success;
4974f8af5cf6SDimitry Andric }
4975f8af5cf6SDimitry Andric
DecodeMSRMask(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)4976145449b1SDimitry Andric static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val, uint64_t Address,
4977145449b1SDimitry Andric const MCDisassembler *Decoder) {
497867c32a98SDimitry Andric DecodeStatus S = MCDisassembler::Success;
49795a5ac124SDimitry Andric const FeatureBitset &FeatureBits =
49805a5ac124SDimitry Andric ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
49815a5ac124SDimitry Andric
49825a5ac124SDimitry Andric if (FeatureBits[ARM::FeatureMClass]) {
498367c32a98SDimitry Andric unsigned ValLow = Val & 0xff;
498467c32a98SDimitry Andric
498567c32a98SDimitry Andric // Validate the SYSm value first.
498667c32a98SDimitry Andric switch (ValLow) {
498767c32a98SDimitry Andric case 0: // apsr
498867c32a98SDimitry Andric case 1: // iapsr
498967c32a98SDimitry Andric case 2: // eapsr
499067c32a98SDimitry Andric case 3: // xpsr
499167c32a98SDimitry Andric case 5: // ipsr
499267c32a98SDimitry Andric case 6: // epsr
499367c32a98SDimitry Andric case 7: // iepsr
499467c32a98SDimitry Andric case 8: // msp
499567c32a98SDimitry Andric case 9: // psp
499667c32a98SDimitry Andric case 16: // primask
499767c32a98SDimitry Andric case 20: // control
499867c32a98SDimitry Andric break;
499967c32a98SDimitry Andric case 17: // basepri
500067c32a98SDimitry Andric case 18: // basepri_max
500167c32a98SDimitry Andric case 19: // faultmask
50025a5ac124SDimitry Andric if (!(FeatureBits[ARM::HasV7Ops]))
500367c32a98SDimitry Andric // Values basepri, basepri_max and faultmask are only valid for v7m.
500467c32a98SDimitry Andric return MCDisassembler::Fail;
500567c32a98SDimitry Andric break;
500601095a5dSDimitry Andric case 0x8a: // msplim_ns
500701095a5dSDimitry Andric case 0x8b: // psplim_ns
500801095a5dSDimitry Andric case 0x91: // basepri_ns
500901095a5dSDimitry Andric case 0x93: // faultmask_ns
501001095a5dSDimitry Andric if (!(FeatureBits[ARM::HasV8MMainlineOps]))
501101095a5dSDimitry Andric return MCDisassembler::Fail;
5012e3b55780SDimitry Andric [[fallthrough]];
501301095a5dSDimitry Andric case 10: // msplim
501401095a5dSDimitry Andric case 11: // psplim
501501095a5dSDimitry Andric case 0x88: // msp_ns
501601095a5dSDimitry Andric case 0x89: // psp_ns
501701095a5dSDimitry Andric case 0x90: // primask_ns
501801095a5dSDimitry Andric case 0x94: // control_ns
501901095a5dSDimitry Andric case 0x98: // sp_ns
502001095a5dSDimitry Andric if (!(FeatureBits[ARM::Feature8MSecExt]))
502101095a5dSDimitry Andric return MCDisassembler::Fail;
502201095a5dSDimitry Andric break;
5023f65dcba8SDimitry Andric case 0x20: // pac_key_p_0
5024f65dcba8SDimitry Andric case 0x21: // pac_key_p_1
5025f65dcba8SDimitry Andric case 0x22: // pac_key_p_2
5026f65dcba8SDimitry Andric case 0x23: // pac_key_p_3
5027f65dcba8SDimitry Andric case 0x24: // pac_key_u_0
5028f65dcba8SDimitry Andric case 0x25: // pac_key_u_1
5029f65dcba8SDimitry Andric case 0x26: // pac_key_u_2
5030f65dcba8SDimitry Andric case 0x27: // pac_key_u_3
5031f65dcba8SDimitry Andric case 0xa0: // pac_key_p_0_ns
5032f65dcba8SDimitry Andric case 0xa1: // pac_key_p_1_ns
5033f65dcba8SDimitry Andric case 0xa2: // pac_key_p_2_ns
5034f65dcba8SDimitry Andric case 0xa3: // pac_key_p_3_ns
5035f65dcba8SDimitry Andric case 0xa4: // pac_key_u_0_ns
5036f65dcba8SDimitry Andric case 0xa5: // pac_key_u_1_ns
5037f65dcba8SDimitry Andric case 0xa6: // pac_key_u_2_ns
5038f65dcba8SDimitry Andric case 0xa7: // pac_key_u_3_ns
5039f65dcba8SDimitry Andric if (!(FeatureBits[ARM::FeaturePACBTI]))
5040f65dcba8SDimitry Andric return MCDisassembler::Fail;
5041f65dcba8SDimitry Andric break;
504267c32a98SDimitry Andric default:
5043eb11fae6SDimitry Andric // Architecturally defined as unpredictable
5044eb11fae6SDimitry Andric S = MCDisassembler::SoftFail;
5045eb11fae6SDimitry Andric break;
504667c32a98SDimitry Andric }
504767c32a98SDimitry Andric
504867c32a98SDimitry Andric if (Inst.getOpcode() == ARM::t2MSR_M) {
504967c32a98SDimitry Andric unsigned Mask = fieldFromInstruction(Val, 10, 2);
50505a5ac124SDimitry Andric if (!(FeatureBits[ARM::HasV7Ops])) {
505167c32a98SDimitry Andric // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
505267c32a98SDimitry Andric // unpredictable.
505367c32a98SDimitry Andric if (Mask != 2)
505467c32a98SDimitry Andric S = MCDisassembler::SoftFail;
505567c32a98SDimitry Andric }
505667c32a98SDimitry Andric else {
505767c32a98SDimitry Andric // The ARMv7-M architecture stores an additional 2-bit mask value in
505867c32a98SDimitry Andric // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
505967c32a98SDimitry Andric // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
506067c32a98SDimitry Andric // the NZCVQ bits should be moved by the instruction. Bit mask{0}
506167c32a98SDimitry Andric // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
506267c32a98SDimitry Andric // only if the processor includes the DSP extension.
506367c32a98SDimitry Andric if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
5064dd58ef01SDimitry Andric (!(FeatureBits[ARM::FeatureDSP]) && (Mask & 1)))
506567c32a98SDimitry Andric S = MCDisassembler::SoftFail;
506667c32a98SDimitry Andric }
506767c32a98SDimitry Andric }
506867c32a98SDimitry Andric } else {
506967c32a98SDimitry Andric // A/R class
507067c32a98SDimitry Andric if (Val == 0)
507167c32a98SDimitry Andric return MCDisassembler::Fail;
507267c32a98SDimitry Andric }
50735a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
507467c32a98SDimitry Andric return S;
507567c32a98SDimitry Andric }
507667c32a98SDimitry Andric
DecodeBankedReg(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)507767c32a98SDimitry Andric static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
5078145449b1SDimitry Andric uint64_t Address,
5079145449b1SDimitry Andric const MCDisassembler *Decoder) {
508067c32a98SDimitry Andric unsigned R = fieldFromInstruction(Val, 5, 1);
508167c32a98SDimitry Andric unsigned SysM = fieldFromInstruction(Val, 0, 5);
508267c32a98SDimitry Andric
508367c32a98SDimitry Andric // The table of encodings for these banked registers comes from B9.2.3 of the
508467c32a98SDimitry Andric // ARM ARM. There are patterns, but nothing regular enough to make this logic
508567c32a98SDimitry Andric // neater. So by fiat, these values are UNPREDICTABLE:
5086eb11fae6SDimitry Andric if (!ARMBankedReg::lookupBankedRegByEncoding((R << 5) | SysM))
5087eb11fae6SDimitry Andric return MCDisassembler::Fail;
508867c32a98SDimitry Andric
50895a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
509030815c53SDimitry Andric return MCDisassembler::Success;
509130815c53SDimitry Andric }
509230815c53SDimitry Andric
DecodeDoubleRegLoad(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)509363faed5bSDimitry Andric static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
5094145449b1SDimitry Andric uint64_t Address,
5095145449b1SDimitry Andric const MCDisassembler *Decoder) {
509630815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
509730815c53SDimitry Andric
5098902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5099902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5100902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
510130815c53SDimitry Andric
5102f8af5cf6SDimitry Andric if (Rn == 0xF)
5103f8af5cf6SDimitry Andric S = MCDisassembler::SoftFail;
510430815c53SDimitry Andric
5105f8af5cf6SDimitry Andric if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
510630815c53SDimitry Andric return MCDisassembler::Fail;
510730815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
510830815c53SDimitry Andric return MCDisassembler::Fail;
510930815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
511030815c53SDimitry Andric return MCDisassembler::Fail;
511130815c53SDimitry Andric
511230815c53SDimitry Andric return S;
511330815c53SDimitry Andric }
511430815c53SDimitry Andric
DecodeDoubleRegStore(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)511563faed5bSDimitry Andric static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
511671d5a254SDimitry Andric uint64_t Address,
5117145449b1SDimitry Andric const MCDisassembler *Decoder) {
511830815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
511930815c53SDimitry Andric
5120902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5121902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 0, 4);
5122902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5123902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
512430815c53SDimitry Andric
512559d6cff9SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
512630815c53SDimitry Andric return MCDisassembler::Fail;
512730815c53SDimitry Andric
5128f8af5cf6SDimitry Andric if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
5129f8af5cf6SDimitry Andric S = MCDisassembler::SoftFail;
513030815c53SDimitry Andric
5131f8af5cf6SDimitry Andric if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
513230815c53SDimitry Andric return MCDisassembler::Fail;
513330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
513430815c53SDimitry Andric return MCDisassembler::Fail;
513530815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
513630815c53SDimitry Andric return MCDisassembler::Fail;
513730815c53SDimitry Andric
513830815c53SDimitry Andric return S;
513930815c53SDimitry Andric }
514030815c53SDimitry Andric
DecodeLDRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)514163faed5bSDimitry Andric static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
5142145449b1SDimitry Andric uint64_t Address,
5143145449b1SDimitry Andric const MCDisassembler *Decoder) {
514430815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
514530815c53SDimitry Andric
5146902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5147902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5148902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 12);
5149902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 16, 4) << 13;
5150902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 23, 1) << 12;
5151902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
515230815c53SDimitry Andric
515330815c53SDimitry Andric if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
515430815c53SDimitry Andric
515530815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
515630815c53SDimitry Andric return MCDisassembler::Fail;
515730815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
515830815c53SDimitry Andric return MCDisassembler::Fail;
515930815c53SDimitry Andric if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
516030815c53SDimitry Andric return MCDisassembler::Fail;
516130815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
516230815c53SDimitry Andric return MCDisassembler::Fail;
516330815c53SDimitry Andric
516430815c53SDimitry Andric return S;
516530815c53SDimitry Andric }
516630815c53SDimitry Andric
DecodeLDRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)516763faed5bSDimitry Andric static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
5168145449b1SDimitry Andric uint64_t Address,
5169145449b1SDimitry Andric const MCDisassembler *Decoder) {
517030815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
517130815c53SDimitry Andric
5172902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5173902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5174902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 12);
5175902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 16, 4) << 13;
5176902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 23, 1) << 12;
5177902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
5178902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
517930815c53SDimitry Andric
518030815c53SDimitry Andric if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
518130815c53SDimitry Andric if (Rm == 0xF) S = MCDisassembler::SoftFail;
518230815c53SDimitry Andric
518330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
518430815c53SDimitry Andric return MCDisassembler::Fail;
518530815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
518630815c53SDimitry Andric return MCDisassembler::Fail;
518730815c53SDimitry Andric if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
518830815c53SDimitry Andric return MCDisassembler::Fail;
518930815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
519030815c53SDimitry Andric return MCDisassembler::Fail;
519130815c53SDimitry Andric
519230815c53SDimitry Andric return S;
519330815c53SDimitry Andric }
519430815c53SDimitry Andric
DecodeSTRPreImm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)519563faed5bSDimitry Andric static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
5196145449b1SDimitry Andric uint64_t Address,
5197145449b1SDimitry Andric const MCDisassembler *Decoder) {
519830815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
519930815c53SDimitry Andric
5200902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5201902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5202902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 12);
5203902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 16, 4) << 13;
5204902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 23, 1) << 12;
5205902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
520630815c53SDimitry Andric
520730815c53SDimitry Andric if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
520830815c53SDimitry Andric
520930815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
521030815c53SDimitry Andric return MCDisassembler::Fail;
521130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
521230815c53SDimitry Andric return MCDisassembler::Fail;
521330815c53SDimitry Andric if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
521430815c53SDimitry Andric return MCDisassembler::Fail;
521530815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
521630815c53SDimitry Andric return MCDisassembler::Fail;
521730815c53SDimitry Andric
521830815c53SDimitry Andric return S;
521930815c53SDimitry Andric }
522030815c53SDimitry Andric
DecodeSTRPreReg(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)522163faed5bSDimitry Andric static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
5222145449b1SDimitry Andric uint64_t Address,
5223145449b1SDimitry Andric const MCDisassembler *Decoder) {
522430815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
522530815c53SDimitry Andric
5226902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5227902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5228902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 0, 12);
5229902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 16, 4) << 13;
5230902a7b52SDimitry Andric imm |= fieldFromInstruction(Insn, 23, 1) << 12;
5231902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
523230815c53SDimitry Andric
523330815c53SDimitry Andric if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
523430815c53SDimitry Andric
523530815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
523630815c53SDimitry Andric return MCDisassembler::Fail;
523730815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
523830815c53SDimitry Andric return MCDisassembler::Fail;
523930815c53SDimitry Andric if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
524030815c53SDimitry Andric return MCDisassembler::Fail;
524130815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
524230815c53SDimitry Andric return MCDisassembler::Fail;
524330815c53SDimitry Andric
524430815c53SDimitry Andric return S;
524530815c53SDimitry Andric }
524630815c53SDimitry Andric
DecodeVLD1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5247145449b1SDimitry Andric static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
5248145449b1SDimitry Andric const MCDisassembler *Decoder) {
524930815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
525030815c53SDimitry Andric
5251902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5252902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5253902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5254902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5255902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 10, 2);
525630815c53SDimitry Andric
525730815c53SDimitry Andric unsigned align = 0;
525830815c53SDimitry Andric unsigned index = 0;
525930815c53SDimitry Andric switch (size) {
526030815c53SDimitry Andric default:
526130815c53SDimitry Andric return MCDisassembler::Fail;
526230815c53SDimitry Andric case 0:
5263902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
526430815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5265902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 5, 3);
526630815c53SDimitry Andric break;
526730815c53SDimitry Andric case 1:
5268902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
526930815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5270902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 6, 2);
5271902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
527230815c53SDimitry Andric align = 2;
527330815c53SDimitry Andric break;
527430815c53SDimitry Andric case 2:
5275902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 6, 1))
527630815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5277902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 7, 1);
5278522600a2SDimitry Andric
5279522600a2SDimitry Andric switch (fieldFromInstruction(Insn, 4, 2)) {
5280522600a2SDimitry Andric case 0 :
5281522600a2SDimitry Andric align = 0; break;
5282522600a2SDimitry Andric case 3:
5283522600a2SDimitry Andric align = 4; break;
5284522600a2SDimitry Andric default:
5285522600a2SDimitry Andric return MCDisassembler::Fail;
5286522600a2SDimitry Andric }
5287522600a2SDimitry Andric break;
528830815c53SDimitry Andric }
528930815c53SDimitry Andric
529030815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
529130815c53SDimitry Andric return MCDisassembler::Fail;
529230815c53SDimitry Andric if (Rm != 0xF) { // Writeback
529330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
529430815c53SDimitry Andric return MCDisassembler::Fail;
529530815c53SDimitry Andric }
529630815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
529730815c53SDimitry Andric return MCDisassembler::Fail;
52985a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
529930815c53SDimitry Andric if (Rm != 0xF) {
530030815c53SDimitry Andric if (Rm != 0xD) {
530130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
530230815c53SDimitry Andric return MCDisassembler::Fail;
530330815c53SDimitry Andric } else
53045a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
530530815c53SDimitry Andric }
530630815c53SDimitry Andric
530730815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
530830815c53SDimitry Andric return MCDisassembler::Fail;
53095a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(index));
531030815c53SDimitry Andric
531130815c53SDimitry Andric return S;
531230815c53SDimitry Andric }
531330815c53SDimitry Andric
DecodeVST1LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5314145449b1SDimitry Andric static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, uint64_t Address,
5315145449b1SDimitry Andric const MCDisassembler *Decoder) {
531630815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
531730815c53SDimitry Andric
5318902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5319902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5320902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5321902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5322902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 10, 2);
532330815c53SDimitry Andric
532430815c53SDimitry Andric unsigned align = 0;
532530815c53SDimitry Andric unsigned index = 0;
532630815c53SDimitry Andric switch (size) {
532730815c53SDimitry Andric default:
532830815c53SDimitry Andric return MCDisassembler::Fail;
532930815c53SDimitry Andric case 0:
5330902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
533130815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5332902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 5, 3);
533330815c53SDimitry Andric break;
533430815c53SDimitry Andric case 1:
5335902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
533630815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5337902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 6, 2);
5338902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
533930815c53SDimitry Andric align = 2;
534030815c53SDimitry Andric break;
534130815c53SDimitry Andric case 2:
5342902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 6, 1))
534330815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5344902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 7, 1);
5345522600a2SDimitry Andric
5346522600a2SDimitry Andric switch (fieldFromInstruction(Insn, 4, 2)) {
5347522600a2SDimitry Andric case 0:
5348522600a2SDimitry Andric align = 0; break;
5349522600a2SDimitry Andric case 3:
5350522600a2SDimitry Andric align = 4; break;
5351522600a2SDimitry Andric default:
5352522600a2SDimitry Andric return MCDisassembler::Fail;
5353522600a2SDimitry Andric }
5354522600a2SDimitry Andric break;
535530815c53SDimitry Andric }
535630815c53SDimitry Andric
535730815c53SDimitry Andric if (Rm != 0xF) { // Writeback
535830815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
535930815c53SDimitry Andric return MCDisassembler::Fail;
536030815c53SDimitry Andric }
536130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
536230815c53SDimitry Andric return MCDisassembler::Fail;
53635a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
536430815c53SDimitry Andric if (Rm != 0xF) {
536530815c53SDimitry Andric if (Rm != 0xD) {
536630815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
536730815c53SDimitry Andric return MCDisassembler::Fail;
536830815c53SDimitry Andric } else
53695a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
537030815c53SDimitry Andric }
537130815c53SDimitry Andric
537230815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
537330815c53SDimitry Andric return MCDisassembler::Fail;
53745a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(index));
537530815c53SDimitry Andric
537630815c53SDimitry Andric return S;
537730815c53SDimitry Andric }
537830815c53SDimitry Andric
DecodeVLD2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5379145449b1SDimitry Andric static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
5380145449b1SDimitry Andric const MCDisassembler *Decoder) {
538130815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
538230815c53SDimitry Andric
5383902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5384902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5385902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5386902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5387902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 10, 2);
538830815c53SDimitry Andric
538930815c53SDimitry Andric unsigned align = 0;
539030815c53SDimitry Andric unsigned index = 0;
539130815c53SDimitry Andric unsigned inc = 1;
539230815c53SDimitry Andric switch (size) {
539330815c53SDimitry Andric default:
539430815c53SDimitry Andric return MCDisassembler::Fail;
539530815c53SDimitry Andric case 0:
5396902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 5, 3);
5397902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
539830815c53SDimitry Andric align = 2;
539930815c53SDimitry Andric break;
540030815c53SDimitry Andric case 1:
5401902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 6, 2);
5402902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
540330815c53SDimitry Andric align = 4;
5404902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
540530815c53SDimitry Andric inc = 2;
540630815c53SDimitry Andric break;
540730815c53SDimitry Andric case 2:
5408902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
540930815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5410902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 7, 1);
5411902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1) != 0)
541230815c53SDimitry Andric align = 8;
5413902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 6, 1))
541430815c53SDimitry Andric inc = 2;
541530815c53SDimitry Andric break;
541630815c53SDimitry Andric }
541730815c53SDimitry Andric
541830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
541930815c53SDimitry Andric return MCDisassembler::Fail;
542030815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
542130815c53SDimitry Andric return MCDisassembler::Fail;
542230815c53SDimitry Andric if (Rm != 0xF) { // Writeback
542330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
542430815c53SDimitry Andric return MCDisassembler::Fail;
542530815c53SDimitry Andric }
542630815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
542730815c53SDimitry Andric return MCDisassembler::Fail;
54285a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
542930815c53SDimitry Andric if (Rm != 0xF) {
543030815c53SDimitry Andric if (Rm != 0xD) {
543130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
543230815c53SDimitry Andric return MCDisassembler::Fail;
543330815c53SDimitry Andric } else
54345a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
543530815c53SDimitry Andric }
543630815c53SDimitry Andric
543730815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
543830815c53SDimitry Andric return MCDisassembler::Fail;
543930815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
544030815c53SDimitry Andric return MCDisassembler::Fail;
54415a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(index));
544230815c53SDimitry Andric
544330815c53SDimitry Andric return S;
544430815c53SDimitry Andric }
544530815c53SDimitry Andric
DecodeVST2LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5446145449b1SDimitry Andric static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, uint64_t Address,
5447145449b1SDimitry Andric const MCDisassembler *Decoder) {
544830815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
544930815c53SDimitry Andric
5450902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5451902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5452902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5453902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5454902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 10, 2);
545530815c53SDimitry Andric
545630815c53SDimitry Andric unsigned align = 0;
545730815c53SDimitry Andric unsigned index = 0;
545830815c53SDimitry Andric unsigned inc = 1;
545930815c53SDimitry Andric switch (size) {
546030815c53SDimitry Andric default:
546130815c53SDimitry Andric return MCDisassembler::Fail;
546230815c53SDimitry Andric case 0:
5463902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 5, 3);
5464902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
546530815c53SDimitry Andric align = 2;
546630815c53SDimitry Andric break;
546730815c53SDimitry Andric case 1:
5468902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 6, 2);
5469902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
547030815c53SDimitry Andric align = 4;
5471902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
547230815c53SDimitry Andric inc = 2;
547330815c53SDimitry Andric break;
547430815c53SDimitry Andric case 2:
5475902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
547630815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5477902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 7, 1);
5478902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1) != 0)
547930815c53SDimitry Andric align = 8;
5480902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 6, 1))
548130815c53SDimitry Andric inc = 2;
548230815c53SDimitry Andric break;
548330815c53SDimitry Andric }
548430815c53SDimitry Andric
548530815c53SDimitry Andric if (Rm != 0xF) { // Writeback
548630815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
548730815c53SDimitry Andric return MCDisassembler::Fail;
548830815c53SDimitry Andric }
548930815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
549030815c53SDimitry Andric return MCDisassembler::Fail;
54915a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
549230815c53SDimitry Andric if (Rm != 0xF) {
549330815c53SDimitry Andric if (Rm != 0xD) {
549430815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
549530815c53SDimitry Andric return MCDisassembler::Fail;
549630815c53SDimitry Andric } else
54975a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
549830815c53SDimitry Andric }
549930815c53SDimitry Andric
550030815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
550130815c53SDimitry Andric return MCDisassembler::Fail;
550230815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
550330815c53SDimitry Andric return MCDisassembler::Fail;
55045a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(index));
550530815c53SDimitry Andric
550630815c53SDimitry Andric return S;
550730815c53SDimitry Andric }
550830815c53SDimitry Andric
DecodeVLD3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5509145449b1SDimitry Andric static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
5510145449b1SDimitry Andric const MCDisassembler *Decoder) {
551130815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
551230815c53SDimitry Andric
5513902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5514902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5515902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5516902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5517902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 10, 2);
551830815c53SDimitry Andric
551930815c53SDimitry Andric unsigned align = 0;
552030815c53SDimitry Andric unsigned index = 0;
552130815c53SDimitry Andric unsigned inc = 1;
552230815c53SDimitry Andric switch (size) {
552330815c53SDimitry Andric default:
552430815c53SDimitry Andric return MCDisassembler::Fail;
552530815c53SDimitry Andric case 0:
5526902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
552730815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5528902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 5, 3);
552930815c53SDimitry Andric break;
553030815c53SDimitry Andric case 1:
5531902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
553230815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5533902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 6, 2);
5534902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
553530815c53SDimitry Andric inc = 2;
553630815c53SDimitry Andric break;
553730815c53SDimitry Andric case 2:
5538902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 2))
553930815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5540902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 7, 1);
5541902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 6, 1))
554230815c53SDimitry Andric inc = 2;
554330815c53SDimitry Andric break;
554430815c53SDimitry Andric }
554530815c53SDimitry Andric
554630815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
554730815c53SDimitry Andric return MCDisassembler::Fail;
554830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
554930815c53SDimitry Andric return MCDisassembler::Fail;
555030815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
555130815c53SDimitry Andric return MCDisassembler::Fail;
555230815c53SDimitry Andric
555330815c53SDimitry Andric if (Rm != 0xF) { // Writeback
555430815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
555530815c53SDimitry Andric return MCDisassembler::Fail;
555630815c53SDimitry Andric }
555730815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
555830815c53SDimitry Andric return MCDisassembler::Fail;
55595a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
556030815c53SDimitry Andric if (Rm != 0xF) {
556130815c53SDimitry Andric if (Rm != 0xD) {
556230815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
556330815c53SDimitry Andric return MCDisassembler::Fail;
556430815c53SDimitry Andric } else
55655a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
556630815c53SDimitry Andric }
556730815c53SDimitry Andric
556830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
556930815c53SDimitry Andric return MCDisassembler::Fail;
557030815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
557130815c53SDimitry Andric return MCDisassembler::Fail;
557230815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
557330815c53SDimitry Andric return MCDisassembler::Fail;
55745a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(index));
557530815c53SDimitry Andric
557630815c53SDimitry Andric return S;
557730815c53SDimitry Andric }
557830815c53SDimitry Andric
DecodeVST3LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5579145449b1SDimitry Andric static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, uint64_t Address,
5580145449b1SDimitry Andric const MCDisassembler *Decoder) {
558130815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
558230815c53SDimitry Andric
5583902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5584902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5585902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5586902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5587902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 10, 2);
558830815c53SDimitry Andric
558930815c53SDimitry Andric unsigned align = 0;
559030815c53SDimitry Andric unsigned index = 0;
559130815c53SDimitry Andric unsigned inc = 1;
559230815c53SDimitry Andric switch (size) {
559330815c53SDimitry Andric default:
559430815c53SDimitry Andric return MCDisassembler::Fail;
559530815c53SDimitry Andric case 0:
5596902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
559730815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5598902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 5, 3);
559930815c53SDimitry Andric break;
560030815c53SDimitry Andric case 1:
5601902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
560230815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5603902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 6, 2);
5604902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
560530815c53SDimitry Andric inc = 2;
560630815c53SDimitry Andric break;
560730815c53SDimitry Andric case 2:
5608902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 2))
560930815c53SDimitry Andric return MCDisassembler::Fail; // UNDEFINED
5610902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 7, 1);
5611902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 6, 1))
561230815c53SDimitry Andric inc = 2;
561330815c53SDimitry Andric break;
561430815c53SDimitry Andric }
561530815c53SDimitry Andric
561630815c53SDimitry Andric if (Rm != 0xF) { // Writeback
561730815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
561830815c53SDimitry Andric return MCDisassembler::Fail;
561930815c53SDimitry Andric }
562030815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
562130815c53SDimitry Andric return MCDisassembler::Fail;
56225a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
562330815c53SDimitry Andric if (Rm != 0xF) {
562430815c53SDimitry Andric if (Rm != 0xD) {
562530815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
562630815c53SDimitry Andric return MCDisassembler::Fail;
562730815c53SDimitry Andric } else
56285a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
562930815c53SDimitry Andric }
563030815c53SDimitry Andric
563130815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
563230815c53SDimitry Andric return MCDisassembler::Fail;
563330815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
563430815c53SDimitry Andric return MCDisassembler::Fail;
563530815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
563630815c53SDimitry Andric return MCDisassembler::Fail;
56375a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(index));
563830815c53SDimitry Andric
563930815c53SDimitry Andric return S;
564030815c53SDimitry Andric }
564130815c53SDimitry Andric
DecodeVLD4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5642145449b1SDimitry Andric static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
5643145449b1SDimitry Andric const MCDisassembler *Decoder) {
564430815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
564530815c53SDimitry Andric
5646902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5647902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5648902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5649902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5650902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 10, 2);
565130815c53SDimitry Andric
565230815c53SDimitry Andric unsigned align = 0;
565330815c53SDimitry Andric unsigned index = 0;
565430815c53SDimitry Andric unsigned inc = 1;
565530815c53SDimitry Andric switch (size) {
565630815c53SDimitry Andric default:
565730815c53SDimitry Andric return MCDisassembler::Fail;
565830815c53SDimitry Andric case 0:
5659902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
566030815c53SDimitry Andric align = 4;
5661902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 5, 3);
566230815c53SDimitry Andric break;
566330815c53SDimitry Andric case 1:
5664902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
566530815c53SDimitry Andric align = 8;
5666902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 6, 2);
5667902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
566830815c53SDimitry Andric inc = 2;
566930815c53SDimitry Andric break;
567030815c53SDimitry Andric case 2:
5671522600a2SDimitry Andric switch (fieldFromInstruction(Insn, 4, 2)) {
5672522600a2SDimitry Andric case 0:
5673522600a2SDimitry Andric align = 0; break;
5674522600a2SDimitry Andric case 3:
5675522600a2SDimitry Andric return MCDisassembler::Fail;
5676522600a2SDimitry Andric default:
5677522600a2SDimitry Andric align = 4 << fieldFromInstruction(Insn, 4, 2); break;
5678522600a2SDimitry Andric }
5679522600a2SDimitry Andric
5680902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 7, 1);
5681902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 6, 1))
568230815c53SDimitry Andric inc = 2;
568330815c53SDimitry Andric break;
568430815c53SDimitry Andric }
568530815c53SDimitry Andric
568630815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
568730815c53SDimitry Andric return MCDisassembler::Fail;
568830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
568930815c53SDimitry Andric return MCDisassembler::Fail;
569030815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
569130815c53SDimitry Andric return MCDisassembler::Fail;
569230815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
569330815c53SDimitry Andric return MCDisassembler::Fail;
569430815c53SDimitry Andric
569530815c53SDimitry Andric if (Rm != 0xF) { // Writeback
569630815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
569730815c53SDimitry Andric return MCDisassembler::Fail;
569830815c53SDimitry Andric }
569930815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
570030815c53SDimitry Andric return MCDisassembler::Fail;
57015a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
570230815c53SDimitry Andric if (Rm != 0xF) {
570330815c53SDimitry Andric if (Rm != 0xD) {
570430815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
570530815c53SDimitry Andric return MCDisassembler::Fail;
570630815c53SDimitry Andric } else
57075a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
570830815c53SDimitry Andric }
570930815c53SDimitry Andric
571030815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
571130815c53SDimitry Andric return MCDisassembler::Fail;
571230815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
571330815c53SDimitry Andric return MCDisassembler::Fail;
571430815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
571530815c53SDimitry Andric return MCDisassembler::Fail;
571630815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
571730815c53SDimitry Andric return MCDisassembler::Fail;
57185a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(index));
571930815c53SDimitry Andric
572030815c53SDimitry Andric return S;
572130815c53SDimitry Andric }
572230815c53SDimitry Andric
DecodeVST4LN(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5723145449b1SDimitry Andric static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, uint64_t Address,
5724145449b1SDimitry Andric const MCDisassembler *Decoder) {
572530815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
572630815c53SDimitry Andric
5727902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5728902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
5729902a7b52SDimitry Andric unsigned Rd = fieldFromInstruction(Insn, 12, 4);
5730902a7b52SDimitry Andric Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
5731902a7b52SDimitry Andric unsigned size = fieldFromInstruction(Insn, 10, 2);
573230815c53SDimitry Andric
573330815c53SDimitry Andric unsigned align = 0;
573430815c53SDimitry Andric unsigned index = 0;
573530815c53SDimitry Andric unsigned inc = 1;
573630815c53SDimitry Andric switch (size) {
573730815c53SDimitry Andric default:
573830815c53SDimitry Andric return MCDisassembler::Fail;
573930815c53SDimitry Andric case 0:
5740902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
574130815c53SDimitry Andric align = 4;
5742902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 5, 3);
574330815c53SDimitry Andric break;
574430815c53SDimitry Andric case 1:
5745902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 4, 1))
574630815c53SDimitry Andric align = 8;
5747902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 6, 2);
5748902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 5, 1))
574930815c53SDimitry Andric inc = 2;
575030815c53SDimitry Andric break;
575130815c53SDimitry Andric case 2:
5752522600a2SDimitry Andric switch (fieldFromInstruction(Insn, 4, 2)) {
5753522600a2SDimitry Andric case 0:
5754522600a2SDimitry Andric align = 0; break;
5755522600a2SDimitry Andric case 3:
5756522600a2SDimitry Andric return MCDisassembler::Fail;
5757522600a2SDimitry Andric default:
5758522600a2SDimitry Andric align = 4 << fieldFromInstruction(Insn, 4, 2); break;
5759522600a2SDimitry Andric }
5760522600a2SDimitry Andric
5761902a7b52SDimitry Andric index = fieldFromInstruction(Insn, 7, 1);
5762902a7b52SDimitry Andric if (fieldFromInstruction(Insn, 6, 1))
576330815c53SDimitry Andric inc = 2;
576430815c53SDimitry Andric break;
576530815c53SDimitry Andric }
576630815c53SDimitry Andric
576730815c53SDimitry Andric if (Rm != 0xF) { // Writeback
576830815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
576930815c53SDimitry Andric return MCDisassembler::Fail;
577030815c53SDimitry Andric }
577130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
577230815c53SDimitry Andric return MCDisassembler::Fail;
57735a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(align));
577430815c53SDimitry Andric if (Rm != 0xF) {
577530815c53SDimitry Andric if (Rm != 0xD) {
577630815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
577730815c53SDimitry Andric return MCDisassembler::Fail;
577830815c53SDimitry Andric } else
57795a5ac124SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
578030815c53SDimitry Andric }
578130815c53SDimitry Andric
578230815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
578330815c53SDimitry Andric return MCDisassembler::Fail;
578430815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
578530815c53SDimitry Andric return MCDisassembler::Fail;
578630815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
578730815c53SDimitry Andric return MCDisassembler::Fail;
578830815c53SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
578930815c53SDimitry Andric return MCDisassembler::Fail;
57905a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(index));
579130815c53SDimitry Andric
579230815c53SDimitry Andric return S;
579330815c53SDimitry Andric }
579430815c53SDimitry Andric
DecodeVMOVSRR(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5795145449b1SDimitry Andric static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, uint64_t Address,
5796145449b1SDimitry Andric const MCDisassembler *Decoder) {
579730815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
5798902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5799902a7b52SDimitry Andric unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
5800902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 5, 1);
5801902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
5802902a7b52SDimitry Andric Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
580330815c53SDimitry Andric
580430815c53SDimitry Andric if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
580530815c53SDimitry Andric S = MCDisassembler::SoftFail;
580630815c53SDimitry Andric
580730815c53SDimitry Andric if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)))
580830815c53SDimitry Andric return MCDisassembler::Fail;
580930815c53SDimitry Andric if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
581030815c53SDimitry Andric return MCDisassembler::Fail;
581130815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)))
581230815c53SDimitry Andric return MCDisassembler::Fail;
581330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
581430815c53SDimitry Andric return MCDisassembler::Fail;
581530815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
581630815c53SDimitry Andric return MCDisassembler::Fail;
581730815c53SDimitry Andric
581830815c53SDimitry Andric return S;
581930815c53SDimitry Andric }
582030815c53SDimitry Andric
DecodeVMOVRRS(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5821145449b1SDimitry Andric static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, uint64_t Address,
5822145449b1SDimitry Andric const MCDisassembler *Decoder) {
582330815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
5824902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5825902a7b52SDimitry Andric unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
5826902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 5, 1);
5827902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
5828902a7b52SDimitry Andric Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
582930815c53SDimitry Andric
583030815c53SDimitry Andric if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
583130815c53SDimitry Andric S = MCDisassembler::SoftFail;
583230815c53SDimitry Andric
583330815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)))
583430815c53SDimitry Andric return MCDisassembler::Fail;
583530815c53SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
583630815c53SDimitry Andric return MCDisassembler::Fail;
583730815c53SDimitry Andric if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)))
583830815c53SDimitry Andric return MCDisassembler::Fail;
583930815c53SDimitry Andric if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
584030815c53SDimitry Andric return MCDisassembler::Fail;
584130815c53SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
584230815c53SDimitry Andric return MCDisassembler::Fail;
584330815c53SDimitry Andric
584430815c53SDimitry Andric return S;
584530815c53SDimitry Andric }
584630815c53SDimitry Andric
DecodeIT(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5847145449b1SDimitry Andric static DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn, uint64_t Address,
5848145449b1SDimitry Andric const MCDisassembler *Decoder) {
584930815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
5850902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 4, 4);
5851902a7b52SDimitry Andric unsigned mask = fieldFromInstruction(Insn, 0, 4);
585230815c53SDimitry Andric
585330815c53SDimitry Andric if (pred == 0xF) {
585430815c53SDimitry Andric pred = 0xE;
585530815c53SDimitry Andric S = MCDisassembler::SoftFail;
585630815c53SDimitry Andric }
585730815c53SDimitry Andric
5858f8af5cf6SDimitry Andric if (mask == 0x0)
5859f8af5cf6SDimitry Andric return MCDisassembler::Fail;
586030815c53SDimitry Andric
5861e6d15924SDimitry Andric // IT masks are encoded as a sequence of replacement low-order bits
5862e6d15924SDimitry Andric // for the condition code. So if the low bit of the starting
5863e6d15924SDimitry Andric // condition code is 1, then we have to flip all the bits above the
5864e6d15924SDimitry Andric // terminating bit (which is the lowest 1 bit).
5865e6d15924SDimitry Andric if (pred & 1) {
5866e6d15924SDimitry Andric unsigned LowBit = mask & -mask;
5867e6d15924SDimitry Andric unsigned BitsAboveLowBit = 0xF & (-LowBit << 1);
5868e6d15924SDimitry Andric mask ^= BitsAboveLowBit;
5869e6d15924SDimitry Andric }
5870e6d15924SDimitry Andric
58715a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(pred));
58725a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(mask));
587330815c53SDimitry Andric return S;
587430815c53SDimitry Andric }
587530815c53SDimitry Andric
DecodeT2LDRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5876145449b1SDimitry Andric static DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
5877145449b1SDimitry Andric uint64_t Address,
5878145449b1SDimitry Andric const MCDisassembler *Decoder) {
587930815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
588030815c53SDimitry Andric
5881902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5882902a7b52SDimitry Andric unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
5883902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5884902a7b52SDimitry Andric unsigned addr = fieldFromInstruction(Insn, 0, 8);
5885902a7b52SDimitry Andric unsigned W = fieldFromInstruction(Insn, 21, 1);
5886902a7b52SDimitry Andric unsigned U = fieldFromInstruction(Insn, 23, 1);
5887902a7b52SDimitry Andric unsigned P = fieldFromInstruction(Insn, 24, 1);
588830815c53SDimitry Andric bool writeback = (W == 1) | (P == 0);
588930815c53SDimitry Andric
589030815c53SDimitry Andric addr |= (U << 8) | (Rn << 9);
589130815c53SDimitry Andric
589230815c53SDimitry Andric if (writeback && (Rn == Rt || Rn == Rt2))
589330815c53SDimitry Andric Check(S, MCDisassembler::SoftFail);
589430815c53SDimitry Andric if (Rt == Rt2)
589530815c53SDimitry Andric Check(S, MCDisassembler::SoftFail);
589630815c53SDimitry Andric
589730815c53SDimitry Andric // Rt
589830815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
589930815c53SDimitry Andric return MCDisassembler::Fail;
590030815c53SDimitry Andric // Rt2
590130815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
590230815c53SDimitry Andric return MCDisassembler::Fail;
590330815c53SDimitry Andric // Writeback operand
590430815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
590530815c53SDimitry Andric return MCDisassembler::Fail;
590630815c53SDimitry Andric // addr
590730815c53SDimitry Andric if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
590830815c53SDimitry Andric return MCDisassembler::Fail;
590930815c53SDimitry Andric
591030815c53SDimitry Andric return S;
591130815c53SDimitry Andric }
591230815c53SDimitry Andric
DecodeT2STRDPreInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5913145449b1SDimitry Andric static DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
5914145449b1SDimitry Andric uint64_t Address,
5915145449b1SDimitry Andric const MCDisassembler *Decoder) {
591630815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
591730815c53SDimitry Andric
5918902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5919902a7b52SDimitry Andric unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
5920902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5921902a7b52SDimitry Andric unsigned addr = fieldFromInstruction(Insn, 0, 8);
5922902a7b52SDimitry Andric unsigned W = fieldFromInstruction(Insn, 21, 1);
5923902a7b52SDimitry Andric unsigned U = fieldFromInstruction(Insn, 23, 1);
5924902a7b52SDimitry Andric unsigned P = fieldFromInstruction(Insn, 24, 1);
592530815c53SDimitry Andric bool writeback = (W == 1) | (P == 0);
592630815c53SDimitry Andric
592730815c53SDimitry Andric addr |= (U << 8) | (Rn << 9);
592830815c53SDimitry Andric
592930815c53SDimitry Andric if (writeback && (Rn == Rt || Rn == Rt2))
593030815c53SDimitry Andric Check(S, MCDisassembler::SoftFail);
593130815c53SDimitry Andric
593230815c53SDimitry Andric // Writeback operand
593330815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
593430815c53SDimitry Andric return MCDisassembler::Fail;
593530815c53SDimitry Andric // Rt
593630815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
593730815c53SDimitry Andric return MCDisassembler::Fail;
593830815c53SDimitry Andric // Rt2
593930815c53SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
594030815c53SDimitry Andric return MCDisassembler::Fail;
594130815c53SDimitry Andric // addr
594230815c53SDimitry Andric if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
594330815c53SDimitry Andric return MCDisassembler::Fail;
594430815c53SDimitry Andric
594530815c53SDimitry Andric return S;
594630815c53SDimitry Andric }
594730815c53SDimitry Andric
DecodeT2Adr(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)5948145449b1SDimitry Andric static DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn, uint64_t Address,
5949145449b1SDimitry Andric const MCDisassembler *Decoder) {
5950902a7b52SDimitry Andric unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
5951902a7b52SDimitry Andric unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
595230815c53SDimitry Andric if (sign1 != sign2) return MCDisassembler::Fail;
5953706b4fc4SDimitry Andric const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
5954706b4fc4SDimitry Andric assert(Inst.getNumOperands() == 0 && "We should receive an empty Inst");
5955706b4fc4SDimitry Andric DecodeStatus S = DecoderGPRRegisterClass(Inst, Rd, Address, Decoder);
595630815c53SDimitry Andric
5957902a7b52SDimitry Andric unsigned Val = fieldFromInstruction(Insn, 0, 8);
5958902a7b52SDimitry Andric Val |= fieldFromInstruction(Insn, 12, 3) << 8;
5959902a7b52SDimitry Andric Val |= fieldFromInstruction(Insn, 26, 1) << 11;
5960706b4fc4SDimitry Andric // If sign, then it is decreasing the address.
5961706b4fc4SDimitry Andric if (sign1) {
5962706b4fc4SDimitry Andric // Following ARMv7 Architecture Manual, when the offset
5963706b4fc4SDimitry Andric // is zero, it is decoded as a subw, not as a adr.w
5964706b4fc4SDimitry Andric if (!Val) {
5965706b4fc4SDimitry Andric Inst.setOpcode(ARM::t2SUBri12);
5966706b4fc4SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::PC));
5967706b4fc4SDimitry Andric } else
5968706b4fc4SDimitry Andric Val = -Val;
5969706b4fc4SDimitry Andric }
5970706b4fc4SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
5971706b4fc4SDimitry Andric return S;
597230815c53SDimitry Andric }
597330815c53SDimitry Andric
DecodeT2ShifterImmOperand(MCInst & Inst,uint32_t Val,uint64_t Address,const MCDisassembler * Decoder)597463faed5bSDimitry Andric static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
597530815c53SDimitry Andric uint64_t Address,
5976145449b1SDimitry Andric const MCDisassembler *Decoder) {
597730815c53SDimitry Andric DecodeStatus S = MCDisassembler::Success;
597830815c53SDimitry Andric
597930815c53SDimitry Andric // Shift of "asr #32" is not allowed in Thumb2 mode.
59805a5ac124SDimitry Andric if (Val == 0x20) S = MCDisassembler::Fail;
59815a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
598230815c53SDimitry Andric return S;
598330815c53SDimitry Andric }
598430815c53SDimitry Andric
DecodeSwap(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)5985145449b1SDimitry Andric static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, uint64_t Address,
5986145449b1SDimitry Andric const MCDisassembler *Decoder) {
5987902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 12, 4);
5988902a7b52SDimitry Andric unsigned Rt2 = fieldFromInstruction(Insn, 0, 4);
5989902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
5990902a7b52SDimitry Andric unsigned pred = fieldFromInstruction(Insn, 28, 4);
599163faed5bSDimitry Andric
599263faed5bSDimitry Andric if (pred == 0xF)
599363faed5bSDimitry Andric return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
599463faed5bSDimitry Andric
599563faed5bSDimitry Andric DecodeStatus S = MCDisassembler::Success;
5996b61ab53cSDimitry Andric
5997b61ab53cSDimitry Andric if (Rt == Rn || Rn == Rt2)
5998b61ab53cSDimitry Andric S = MCDisassembler::SoftFail;
5999b61ab53cSDimitry Andric
600063faed5bSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
600163faed5bSDimitry Andric return MCDisassembler::Fail;
600263faed5bSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
600363faed5bSDimitry Andric return MCDisassembler::Fail;
600463faed5bSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
600563faed5bSDimitry Andric return MCDisassembler::Fail;
600663faed5bSDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
600763faed5bSDimitry Andric return MCDisassembler::Fail;
600863faed5bSDimitry Andric
600963faed5bSDimitry Andric return S;
601063faed5bSDimitry Andric }
601163faed5bSDimitry Andric
DecodeVCVTD(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6012145449b1SDimitry Andric static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, uint64_t Address,
6013145449b1SDimitry Andric const MCDisassembler *Decoder) {
6014dd58ef01SDimitry Andric const FeatureBitset &featureBits =
6015dd58ef01SDimitry Andric ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
6016dd58ef01SDimitry Andric bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
6017dd58ef01SDimitry Andric
6018902a7b52SDimitry Andric unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
6019902a7b52SDimitry Andric Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
6020902a7b52SDimitry Andric unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
6021902a7b52SDimitry Andric Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
6022902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 16, 6);
6023902a7b52SDimitry Andric unsigned cmode = fieldFromInstruction(Insn, 8, 4);
6024f8af5cf6SDimitry Andric unsigned op = fieldFromInstruction(Insn, 5, 1);
602563faed5bSDimitry Andric
602663faed5bSDimitry Andric DecodeStatus S = MCDisassembler::Success;
602763faed5bSDimitry Andric
6028dd58ef01SDimitry Andric // If the top 3 bits of imm are clear, this is a VMOV (immediate)
6029dd58ef01SDimitry Andric if (!(imm & 0x38)) {
6030dd58ef01SDimitry Andric if (cmode == 0xF) {
6031f8af5cf6SDimitry Andric if (op == 1) return MCDisassembler::Fail;
603263faed5bSDimitry Andric Inst.setOpcode(ARM::VMOVv2f32);
6033dd58ef01SDimitry Andric }
6034dd58ef01SDimitry Andric if (hasFullFP16) {
6035dd58ef01SDimitry Andric if (cmode == 0xE) {
6036dd58ef01SDimitry Andric if (op == 1) {
6037dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMOVv1i64);
6038dd58ef01SDimitry Andric } else {
6039dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMOVv8i8);
6040dd58ef01SDimitry Andric }
6041dd58ef01SDimitry Andric }
6042dd58ef01SDimitry Andric if (cmode == 0xD) {
6043dd58ef01SDimitry Andric if (op == 1) {
6044dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMVNv2i32);
6045dd58ef01SDimitry Andric } else {
6046dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMOVv2i32);
6047dd58ef01SDimitry Andric }
6048dd58ef01SDimitry Andric }
6049dd58ef01SDimitry Andric if (cmode == 0xC) {
6050dd58ef01SDimitry Andric if (op == 1) {
6051dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMVNv2i32);
6052dd58ef01SDimitry Andric } else {
6053dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMOVv2i32);
6054dd58ef01SDimitry Andric }
6055dd58ef01SDimitry Andric }
6056dd58ef01SDimitry Andric }
60571d5ae102SDimitry Andric return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
605863faed5bSDimitry Andric }
605963faed5bSDimitry Andric
6060f8af5cf6SDimitry Andric if (!(imm & 0x20)) return MCDisassembler::Fail;
606163faed5bSDimitry Andric
606263faed5bSDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
606363faed5bSDimitry Andric return MCDisassembler::Fail;
606463faed5bSDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
606563faed5bSDimitry Andric return MCDisassembler::Fail;
60665a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(64 - imm));
606763faed5bSDimitry Andric
606863faed5bSDimitry Andric return S;
606963faed5bSDimitry Andric }
607063faed5bSDimitry Andric
DecodeVCVTQ(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6071145449b1SDimitry Andric static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, uint64_t Address,
6072145449b1SDimitry Andric const MCDisassembler *Decoder) {
6073dd58ef01SDimitry Andric const FeatureBitset &featureBits =
6074dd58ef01SDimitry Andric ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
6075dd58ef01SDimitry Andric bool hasFullFP16 = featureBits[ARM::FeatureFullFP16];
6076dd58ef01SDimitry Andric
6077902a7b52SDimitry Andric unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
6078902a7b52SDimitry Andric Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
6079902a7b52SDimitry Andric unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
6080902a7b52SDimitry Andric Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
6081902a7b52SDimitry Andric unsigned imm = fieldFromInstruction(Insn, 16, 6);
6082902a7b52SDimitry Andric unsigned cmode = fieldFromInstruction(Insn, 8, 4);
6083f8af5cf6SDimitry Andric unsigned op = fieldFromInstruction(Insn, 5, 1);
608463faed5bSDimitry Andric
608563faed5bSDimitry Andric DecodeStatus S = MCDisassembler::Success;
608663faed5bSDimitry Andric
6087dd58ef01SDimitry Andric // If the top 3 bits of imm are clear, this is a VMOV (immediate)
6088dd58ef01SDimitry Andric if (!(imm & 0x38)) {
6089dd58ef01SDimitry Andric if (cmode == 0xF) {
6090f8af5cf6SDimitry Andric if (op == 1) return MCDisassembler::Fail;
609163faed5bSDimitry Andric Inst.setOpcode(ARM::VMOVv4f32);
6092dd58ef01SDimitry Andric }
6093dd58ef01SDimitry Andric if (hasFullFP16) {
6094dd58ef01SDimitry Andric if (cmode == 0xE) {
6095dd58ef01SDimitry Andric if (op == 1) {
6096dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMOVv2i64);
6097dd58ef01SDimitry Andric } else {
6098dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMOVv16i8);
6099dd58ef01SDimitry Andric }
6100dd58ef01SDimitry Andric }
6101dd58ef01SDimitry Andric if (cmode == 0xD) {
6102dd58ef01SDimitry Andric if (op == 1) {
6103dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMVNv4i32);
6104dd58ef01SDimitry Andric } else {
6105dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMOVv4i32);
6106dd58ef01SDimitry Andric }
6107dd58ef01SDimitry Andric }
6108dd58ef01SDimitry Andric if (cmode == 0xC) {
6109dd58ef01SDimitry Andric if (op == 1) {
6110dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMVNv4i32);
6111dd58ef01SDimitry Andric } else {
6112dd58ef01SDimitry Andric Inst.setOpcode(ARM::VMOVv4i32);
6113dd58ef01SDimitry Andric }
6114dd58ef01SDimitry Andric }
6115dd58ef01SDimitry Andric }
61161d5ae102SDimitry Andric return DecodeVMOVModImmInstruction(Inst, Insn, Address, Decoder);
611763faed5bSDimitry Andric }
611863faed5bSDimitry Andric
6119f8af5cf6SDimitry Andric if (!(imm & 0x20)) return MCDisassembler::Fail;
612063faed5bSDimitry Andric
612163faed5bSDimitry Andric if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
612263faed5bSDimitry Andric return MCDisassembler::Fail;
612363faed5bSDimitry Andric if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
612463faed5bSDimitry Andric return MCDisassembler::Fail;
61255a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(64 - imm));
612663faed5bSDimitry Andric
612763faed5bSDimitry Andric return S;
612863faed5bSDimitry Andric }
612963faed5bSDimitry Andric
6130145449b1SDimitry Andric static DecodeStatus
DecodeNEONComplexLane64Instruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6131145449b1SDimitry Andric DecodeNEONComplexLane64Instruction(MCInst &Inst, unsigned Insn,
6132044eb2f6SDimitry Andric uint64_t Address,
6133145449b1SDimitry Andric const MCDisassembler *Decoder) {
6134044eb2f6SDimitry Andric unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
6135044eb2f6SDimitry Andric Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
6136044eb2f6SDimitry Andric unsigned Vn = (fieldFromInstruction(Insn, 16, 4) << 0);
6137044eb2f6SDimitry Andric Vn |= (fieldFromInstruction(Insn, 7, 1) << 4);
6138044eb2f6SDimitry Andric unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
6139044eb2f6SDimitry Andric Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
6140044eb2f6SDimitry Andric unsigned q = (fieldFromInstruction(Insn, 6, 1) << 0);
6141044eb2f6SDimitry Andric unsigned rotate = (fieldFromInstruction(Insn, 20, 2) << 0);
6142044eb2f6SDimitry Andric
6143044eb2f6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6144044eb2f6SDimitry Andric
6145044eb2f6SDimitry Andric auto DestRegDecoder = q ? DecodeQPRRegisterClass : DecodeDPRRegisterClass;
6146044eb2f6SDimitry Andric
6147044eb2f6SDimitry Andric if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
6148044eb2f6SDimitry Andric return MCDisassembler::Fail;
6149044eb2f6SDimitry Andric if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
6150044eb2f6SDimitry Andric return MCDisassembler::Fail;
6151044eb2f6SDimitry Andric if (!Check(S, DestRegDecoder(Inst, Vn, Address, Decoder)))
6152044eb2f6SDimitry Andric return MCDisassembler::Fail;
6153044eb2f6SDimitry Andric if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
6154044eb2f6SDimitry Andric return MCDisassembler::Fail;
6155044eb2f6SDimitry Andric // The lane index does not have any bits in the encoding, because it can only
6156044eb2f6SDimitry Andric // be 0.
6157044eb2f6SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
6158044eb2f6SDimitry Andric Inst.addOperand(MCOperand::createImm(rotate));
6159044eb2f6SDimitry Andric
6160044eb2f6SDimitry Andric return S;
6161044eb2f6SDimitry Andric }
6162044eb2f6SDimitry Andric
DecodeLDR(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6163145449b1SDimitry Andric static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, uint64_t Address,
6164145449b1SDimitry Andric const MCDisassembler *Decoder) {
616563faed5bSDimitry Andric DecodeStatus S = MCDisassembler::Success;
616663faed5bSDimitry Andric
6167902a7b52SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 16, 4);
6168902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Val, 12, 4);
6169902a7b52SDimitry Andric unsigned Rm = fieldFromInstruction(Val, 0, 4);
6170902a7b52SDimitry Andric Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
6171902a7b52SDimitry Andric unsigned Cond = fieldFromInstruction(Val, 28, 4);
617263faed5bSDimitry Andric
6173902a7b52SDimitry Andric if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
617463faed5bSDimitry Andric S = MCDisassembler::SoftFail;
617563faed5bSDimitry Andric
617663faed5bSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
617763faed5bSDimitry Andric return MCDisassembler::Fail;
617863faed5bSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
617963faed5bSDimitry Andric return MCDisassembler::Fail;
618063faed5bSDimitry Andric if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
618163faed5bSDimitry Andric return MCDisassembler::Fail;
618263faed5bSDimitry Andric if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
618363faed5bSDimitry Andric return MCDisassembler::Fail;
618463faed5bSDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
618563faed5bSDimitry Andric return MCDisassembler::Fail;
618663faed5bSDimitry Andric
618763faed5bSDimitry Andric return S;
618863faed5bSDimitry Andric }
618963faed5bSDimitry Andric
DecoderForMRRC2AndMCRR2(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)619071d5a254SDimitry Andric static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
6191145449b1SDimitry Andric uint64_t Address,
6192145449b1SDimitry Andric const MCDisassembler *Decoder) {
6193b61ab53cSDimitry Andric DecodeStatus S = MCDisassembler::Success;
6194b61ab53cSDimitry Andric
6195902a7b52SDimitry Andric unsigned CRm = fieldFromInstruction(Val, 0, 4);
6196902a7b52SDimitry Andric unsigned opc1 = fieldFromInstruction(Val, 4, 4);
6197902a7b52SDimitry Andric unsigned cop = fieldFromInstruction(Val, 8, 4);
6198902a7b52SDimitry Andric unsigned Rt = fieldFromInstruction(Val, 12, 4);
6199902a7b52SDimitry Andric unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
6200b61ab53cSDimitry Andric
6201b61ab53cSDimitry Andric if ((cop & ~0x1) == 0xa)
6202b61ab53cSDimitry Andric return MCDisassembler::Fail;
6203b61ab53cSDimitry Andric
6204b61ab53cSDimitry Andric if (Rt == Rt2)
6205b61ab53cSDimitry Andric S = MCDisassembler::SoftFail;
6206b61ab53cSDimitry Andric
620701095a5dSDimitry Andric // We have to check if the instruction is MRRC2
620801095a5dSDimitry Andric // or MCRR2 when constructing the operands for
620901095a5dSDimitry Andric // Inst. Reason is because MRRC2 stores to two
6210b1c73532SDimitry Andric // registers so it's tablegen desc has two
621101095a5dSDimitry Andric // outputs whereas MCRR doesn't store to any
621201095a5dSDimitry Andric // registers so all of it's operands are listed
621301095a5dSDimitry Andric // as inputs, therefore the operand order for
621401095a5dSDimitry Andric // MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm]
621501095a5dSDimitry Andric // and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm]
621601095a5dSDimitry Andric
621701095a5dSDimitry Andric if (Inst.getOpcode() == ARM::MRRC2) {
6218b61ab53cSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
6219b61ab53cSDimitry Andric return MCDisassembler::Fail;
6220b61ab53cSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
6221b61ab53cSDimitry Andric return MCDisassembler::Fail;
622201095a5dSDimitry Andric }
622301095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(cop));
622401095a5dSDimitry Andric Inst.addOperand(MCOperand::createImm(opc1));
622501095a5dSDimitry Andric if (Inst.getOpcode() == ARM::MCRR2) {
622601095a5dSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
622701095a5dSDimitry Andric return MCDisassembler::Fail;
622801095a5dSDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
622901095a5dSDimitry Andric return MCDisassembler::Fail;
623001095a5dSDimitry Andric }
62315a5ac124SDimitry Andric Inst.addOperand(MCOperand::createImm(CRm));
6232b61ab53cSDimitry Andric
6233b61ab53cSDimitry Andric return S;
6234b61ab53cSDimitry Andric }
6235044eb2f6SDimitry Andric
DecodeForVMRSandVMSR(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6236044eb2f6SDimitry Andric static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
6237044eb2f6SDimitry Andric uint64_t Address,
6238145449b1SDimitry Andric const MCDisassembler *Decoder) {
6239044eb2f6SDimitry Andric const FeatureBitset &featureBits =
6240044eb2f6SDimitry Andric ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
6241044eb2f6SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6242044eb2f6SDimitry Andric
6243e6d15924SDimitry Andric // Add explicit operand for the destination sysreg, for cases where
6244e6d15924SDimitry Andric // we have to model it for code generation purposes.
6245e6d15924SDimitry Andric switch (Inst.getOpcode()) {
6246e6d15924SDimitry Andric case ARM::VMSR_FPSCR_NZCVQC:
6247e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
6248e6d15924SDimitry Andric break;
6249e6d15924SDimitry Andric case ARM::VMSR_P0:
6250e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::VPR));
6251e6d15924SDimitry Andric break;
6252e6d15924SDimitry Andric }
6253e6d15924SDimitry Andric
6254e6d15924SDimitry Andric if (Inst.getOpcode() != ARM::FMSTAT) {
6255044eb2f6SDimitry Andric unsigned Rt = fieldFromInstruction(Val, 12, 4);
6256044eb2f6SDimitry Andric
6257044eb2f6SDimitry Andric if (featureBits[ARM::ModeThumb] && !featureBits[ARM::HasV8Ops]) {
6258044eb2f6SDimitry Andric if (Rt == 13 || Rt == 15)
6259044eb2f6SDimitry Andric S = MCDisassembler::SoftFail;
6260044eb2f6SDimitry Andric Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder));
6261044eb2f6SDimitry Andric } else
6262044eb2f6SDimitry Andric Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder));
6263e6d15924SDimitry Andric }
6264e6d15924SDimitry Andric
6265e6d15924SDimitry Andric // Add explicit operand for the source sysreg, similarly to above.
6266e6d15924SDimitry Andric switch (Inst.getOpcode()) {
6267e6d15924SDimitry Andric case ARM::VMRS_FPSCR_NZCVQC:
6268e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::FPSCR_NZCV));
6269e6d15924SDimitry Andric break;
6270e6d15924SDimitry Andric case ARM::VMRS_P0:
6271e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::VPR));
6272e6d15924SDimitry Andric break;
6273e6d15924SDimitry Andric }
6274044eb2f6SDimitry Andric
6275044eb2f6SDimitry Andric if (featureBits[ARM::ModeThumb]) {
6276044eb2f6SDimitry Andric Inst.addOperand(MCOperand::createImm(ARMCC::AL));
6277044eb2f6SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
6278044eb2f6SDimitry Andric } else {
6279044eb2f6SDimitry Andric unsigned pred = fieldFromInstruction(Val, 28, 4);
6280044eb2f6SDimitry Andric if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
6281044eb2f6SDimitry Andric return MCDisassembler::Fail;
6282044eb2f6SDimitry Andric }
6283044eb2f6SDimitry Andric
6284044eb2f6SDimitry Andric return S;
6285044eb2f6SDimitry Andric }
6286e6d15924SDimitry Andric
6287e6d15924SDimitry Andric template <bool isSigned, bool isNeg, bool zeroPermitted, int size>
DecodeBFLabelOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6288e6d15924SDimitry Andric static DecodeStatus DecodeBFLabelOperand(MCInst &Inst, unsigned Val,
6289e6d15924SDimitry Andric uint64_t Address,
6290145449b1SDimitry Andric const MCDisassembler *Decoder) {
6291e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6292e6d15924SDimitry Andric if (Val == 0 && !zeroPermitted)
6293e6d15924SDimitry Andric S = MCDisassembler::Fail;
6294e6d15924SDimitry Andric
6295e6d15924SDimitry Andric uint64_t DecVal;
6296e6d15924SDimitry Andric if (isSigned)
6297e6d15924SDimitry Andric DecVal = SignExtend32<size + 1>(Val << 1);
6298e6d15924SDimitry Andric else
6299e6d15924SDimitry Andric DecVal = (Val << 1);
6300e6d15924SDimitry Andric
6301e6d15924SDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + DecVal + 4, true, 4, Inst,
6302e6d15924SDimitry Andric Decoder))
6303e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(isNeg ? -DecVal : DecVal));
6304e6d15924SDimitry Andric return S;
6305e6d15924SDimitry Andric }
6306e6d15924SDimitry Andric
DecodeBFAfterTargetOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6307e6d15924SDimitry Andric static DecodeStatus DecodeBFAfterTargetOperand(MCInst &Inst, unsigned Val,
6308e6d15924SDimitry Andric uint64_t Address,
6309145449b1SDimitry Andric const MCDisassembler *Decoder) {
6310e6d15924SDimitry Andric
6311e6d15924SDimitry Andric uint64_t LocImm = Inst.getOperand(0).getImm();
6312e6d15924SDimitry Andric Val = LocImm + (2 << Val);
6313e6d15924SDimitry Andric if (!tryAddingSymbolicOperand(Address, Address + Val + 4, true, 4, Inst,
6314e6d15924SDimitry Andric Decoder))
6315e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
6316e6d15924SDimitry Andric return MCDisassembler::Success;
6317e6d15924SDimitry Andric }
6318e6d15924SDimitry Andric
DecodePredNoALOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6319e6d15924SDimitry Andric static DecodeStatus DecodePredNoALOperand(MCInst &Inst, unsigned Val,
6320e6d15924SDimitry Andric uint64_t Address,
6321145449b1SDimitry Andric const MCDisassembler *Decoder) {
6322e6d15924SDimitry Andric if (Val >= ARMCC::AL) // also exclude the non-condition NV
6323e6d15924SDimitry Andric return MCDisassembler::Fail;
6324e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
6325e6d15924SDimitry Andric return MCDisassembler::Success;
6326e6d15924SDimitry Andric }
6327e6d15924SDimitry Andric
DecodeLOLoop(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6328e6d15924SDimitry Andric static DecodeStatus DecodeLOLoop(MCInst &Inst, unsigned Insn, uint64_t Address,
6329145449b1SDimitry Andric const MCDisassembler *Decoder) {
6330e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6331e6d15924SDimitry Andric
6332e6d15924SDimitry Andric if (Inst.getOpcode() == ARM::MVE_LCTP)
6333e6d15924SDimitry Andric return S;
6334e6d15924SDimitry Andric
6335e6d15924SDimitry Andric unsigned Imm = fieldFromInstruction(Insn, 11, 1) |
6336e6d15924SDimitry Andric fieldFromInstruction(Insn, 1, 10) << 1;
6337e6d15924SDimitry Andric switch (Inst.getOpcode()) {
6338e6d15924SDimitry Andric case ARM::t2LEUpdate:
6339e6d15924SDimitry Andric case ARM::MVE_LETP:
6340e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::LR));
6341e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::LR));
6342e3b55780SDimitry Andric [[fallthrough]];
6343e6d15924SDimitry Andric case ARM::t2LE:
6344e6d15924SDimitry Andric if (!Check(S, DecodeBFLabelOperand<false, true, true, 11>(
6345e6d15924SDimitry Andric Inst, Imm, Address, Decoder)))
6346e6d15924SDimitry Andric return MCDisassembler::Fail;
6347e6d15924SDimitry Andric break;
6348e6d15924SDimitry Andric case ARM::t2WLS:
6349e6d15924SDimitry Andric case ARM::MVE_WLSTP_8:
6350e6d15924SDimitry Andric case ARM::MVE_WLSTP_16:
6351e6d15924SDimitry Andric case ARM::MVE_WLSTP_32:
6352e6d15924SDimitry Andric case ARM::MVE_WLSTP_64:
6353e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::LR));
6354e6d15924SDimitry Andric if (!Check(S,
6355e6d15924SDimitry Andric DecoderGPRRegisterClass(Inst, fieldFromInstruction(Insn, 16, 4),
6356e6d15924SDimitry Andric Address, Decoder)) ||
6357e6d15924SDimitry Andric !Check(S, DecodeBFLabelOperand<false, false, true, 11>(
6358e6d15924SDimitry Andric Inst, Imm, Address, Decoder)))
6359e6d15924SDimitry Andric return MCDisassembler::Fail;
6360e6d15924SDimitry Andric break;
6361e6d15924SDimitry Andric case ARM::t2DLS:
6362e6d15924SDimitry Andric case ARM::MVE_DLSTP_8:
6363e6d15924SDimitry Andric case ARM::MVE_DLSTP_16:
6364e6d15924SDimitry Andric case ARM::MVE_DLSTP_32:
6365e6d15924SDimitry Andric case ARM::MVE_DLSTP_64:
6366e6d15924SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
6367e6d15924SDimitry Andric if (Rn == 0xF) {
6368e6d15924SDimitry Andric // Enforce all the rest of the instruction bits in LCTP, which
6369e6d15924SDimitry Andric // won't have been reliably checked based on LCTP's own tablegen
6370e6d15924SDimitry Andric // record, because we came to this decode by a roundabout route.
6371e6d15924SDimitry Andric uint32_t CanonicalLCTP = 0xF00FE001, SBZMask = 0x00300FFE;
6372e6d15924SDimitry Andric if ((Insn & ~SBZMask) != CanonicalLCTP)
6373e6d15924SDimitry Andric return MCDisassembler::Fail; // a mandatory bit is wrong: hard fail
6374e6d15924SDimitry Andric if (Insn != CanonicalLCTP)
6375e6d15924SDimitry Andric Check(S, MCDisassembler::SoftFail); // an SBZ bit is wrong: soft fail
6376e6d15924SDimitry Andric
6377e6d15924SDimitry Andric Inst.setOpcode(ARM::MVE_LCTP);
6378e6d15924SDimitry Andric } else {
6379e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::LR));
6380e6d15924SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst,
6381e6d15924SDimitry Andric fieldFromInstruction(Insn, 16, 4),
6382e6d15924SDimitry Andric Address, Decoder)))
6383e6d15924SDimitry Andric return MCDisassembler::Fail;
6384e6d15924SDimitry Andric }
6385e6d15924SDimitry Andric break;
6386e6d15924SDimitry Andric }
6387e6d15924SDimitry Andric return S;
6388e6d15924SDimitry Andric }
6389e6d15924SDimitry Andric
DecodeLongShiftOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6390e6d15924SDimitry Andric static DecodeStatus DecodeLongShiftOperand(MCInst &Inst, unsigned Val,
6391e6d15924SDimitry Andric uint64_t Address,
6392145449b1SDimitry Andric const MCDisassembler *Decoder) {
6393e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6394e6d15924SDimitry Andric
6395e6d15924SDimitry Andric if (Val == 0)
6396e6d15924SDimitry Andric Val = 32;
6397e6d15924SDimitry Andric
6398e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(Val));
6399e6d15924SDimitry Andric
6400e6d15924SDimitry Andric return S;
6401e6d15924SDimitry Andric }
6402e6d15924SDimitry Andric
DecodetGPROddRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6403e6d15924SDimitry Andric static DecodeStatus DecodetGPROddRegisterClass(MCInst &Inst, unsigned RegNo,
6404145449b1SDimitry Andric uint64_t Address,
6405145449b1SDimitry Andric const MCDisassembler *Decoder) {
6406e6d15924SDimitry Andric if ((RegNo) + 1 > 11)
6407e6d15924SDimitry Andric return MCDisassembler::Fail;
6408e6d15924SDimitry Andric
6409e6d15924SDimitry Andric unsigned Register = GPRDecoderTable[(RegNo) + 1];
6410e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
6411e6d15924SDimitry Andric return MCDisassembler::Success;
6412e6d15924SDimitry Andric }
6413e6d15924SDimitry Andric
DecodetGPREvenRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6414e6d15924SDimitry Andric static DecodeStatus DecodetGPREvenRegisterClass(MCInst &Inst, unsigned RegNo,
6415145449b1SDimitry Andric uint64_t Address,
6416145449b1SDimitry Andric const MCDisassembler *Decoder) {
6417e6d15924SDimitry Andric if ((RegNo) > 14)
6418e6d15924SDimitry Andric return MCDisassembler::Fail;
6419e6d15924SDimitry Andric
6420e6d15924SDimitry Andric unsigned Register = GPRDecoderTable[(RegNo)];
6421e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
6422e6d15924SDimitry Andric return MCDisassembler::Success;
6423e6d15924SDimitry Andric }
6424e6d15924SDimitry Andric
6425cfca06d7SDimitry Andric static DecodeStatus
DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6426cfca06d7SDimitry Andric DecodeGPRwithAPSR_NZCVnospRegisterClass(MCInst &Inst, unsigned RegNo,
6427145449b1SDimitry Andric uint64_t Address,
6428145449b1SDimitry Andric const MCDisassembler *Decoder) {
6429cfca06d7SDimitry Andric if (RegNo == 15) {
6430cfca06d7SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::APSR_NZCV));
6431cfca06d7SDimitry Andric return MCDisassembler::Success;
6432cfca06d7SDimitry Andric }
6433cfca06d7SDimitry Andric
6434cfca06d7SDimitry Andric unsigned Register = GPRDecoderTable[RegNo];
6435cfca06d7SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
6436cfca06d7SDimitry Andric
6437cfca06d7SDimitry Andric if (RegNo == 13)
6438cfca06d7SDimitry Andric return MCDisassembler::SoftFail;
6439cfca06d7SDimitry Andric
6440cfca06d7SDimitry Andric return MCDisassembler::Success;
6441cfca06d7SDimitry Andric }
6442cfca06d7SDimitry Andric
DecodeVSCCLRM(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6443e6d15924SDimitry Andric static DecodeStatus DecodeVSCCLRM(MCInst &Inst, unsigned Insn, uint64_t Address,
6444145449b1SDimitry Andric const MCDisassembler *Decoder) {
6445e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6446e6d15924SDimitry Andric
6447e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(ARMCC::AL));
6448e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
6449e6d15924SDimitry Andric if (Inst.getOpcode() == ARM::VSCCLRMD) {
6450e6d15924SDimitry Andric unsigned reglist = (fieldFromInstruction(Insn, 1, 7) << 1) |
6451e6d15924SDimitry Andric (fieldFromInstruction(Insn, 12, 4) << 8) |
6452e6d15924SDimitry Andric (fieldFromInstruction(Insn, 22, 1) << 12);
6453e6d15924SDimitry Andric if (!Check(S, DecodeDPRRegListOperand(Inst, reglist, Address, Decoder))) {
6454e6d15924SDimitry Andric return MCDisassembler::Fail;
6455e6d15924SDimitry Andric }
6456e6d15924SDimitry Andric } else {
6457e6d15924SDimitry Andric unsigned reglist = fieldFromInstruction(Insn, 0, 8) |
6458e6d15924SDimitry Andric (fieldFromInstruction(Insn, 22, 1) << 8) |
6459e6d15924SDimitry Andric (fieldFromInstruction(Insn, 12, 4) << 9);
6460e6d15924SDimitry Andric if (!Check(S, DecodeSPRRegListOperand(Inst, reglist, Address, Decoder))) {
6461e6d15924SDimitry Andric return MCDisassembler::Fail;
6462e6d15924SDimitry Andric }
6463e6d15924SDimitry Andric }
6464e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::VPR));
6465e6d15924SDimitry Andric
6466e6d15924SDimitry Andric return S;
6467e6d15924SDimitry Andric }
6468e6d15924SDimitry Andric
DecodeMQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6469e6d15924SDimitry Andric static DecodeStatus DecodeMQPRRegisterClass(MCInst &Inst, unsigned RegNo,
6470e6d15924SDimitry Andric uint64_t Address,
6471145449b1SDimitry Andric const MCDisassembler *Decoder) {
6472e6d15924SDimitry Andric if (RegNo > 7)
6473e6d15924SDimitry Andric return MCDisassembler::Fail;
6474e6d15924SDimitry Andric
6475e6d15924SDimitry Andric unsigned Register = QPRDecoderTable[RegNo];
6476e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
6477e6d15924SDimitry Andric return MCDisassembler::Success;
6478e6d15924SDimitry Andric }
6479e6d15924SDimitry Andric
6480e6d15924SDimitry Andric static const uint16_t QQPRDecoderTable[] = {
6481e6d15924SDimitry Andric ARM::Q0_Q1, ARM::Q1_Q2, ARM::Q2_Q3, ARM::Q3_Q4,
6482e6d15924SDimitry Andric ARM::Q4_Q5, ARM::Q5_Q6, ARM::Q6_Q7
6483e6d15924SDimitry Andric };
6484e6d15924SDimitry Andric
DecodeMQQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6485c0981da4SDimitry Andric static DecodeStatus DecodeMQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
6486e6d15924SDimitry Andric uint64_t Address,
6487145449b1SDimitry Andric const MCDisassembler *Decoder) {
6488e6d15924SDimitry Andric if (RegNo > 6)
6489e6d15924SDimitry Andric return MCDisassembler::Fail;
6490e6d15924SDimitry Andric
6491e6d15924SDimitry Andric unsigned Register = QQPRDecoderTable[RegNo];
6492e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
6493e6d15924SDimitry Andric return MCDisassembler::Success;
6494e6d15924SDimitry Andric }
6495e6d15924SDimitry Andric
6496e6d15924SDimitry Andric static const uint16_t QQQQPRDecoderTable[] = {
6497e6d15924SDimitry Andric ARM::Q0_Q1_Q2_Q3, ARM::Q1_Q2_Q3_Q4, ARM::Q2_Q3_Q4_Q5,
6498e6d15924SDimitry Andric ARM::Q3_Q4_Q5_Q6, ARM::Q4_Q5_Q6_Q7
6499e6d15924SDimitry Andric };
6500e6d15924SDimitry Andric
DecodeMQQQQPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6501c0981da4SDimitry Andric static DecodeStatus DecodeMQQQQPRRegisterClass(MCInst &Inst, unsigned RegNo,
6502e6d15924SDimitry Andric uint64_t Address,
6503145449b1SDimitry Andric const MCDisassembler *Decoder) {
6504e6d15924SDimitry Andric if (RegNo > 4)
6505e6d15924SDimitry Andric return MCDisassembler::Fail;
6506e6d15924SDimitry Andric
6507e6d15924SDimitry Andric unsigned Register = QQQQPRDecoderTable[RegNo];
6508e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(Register));
6509e6d15924SDimitry Andric return MCDisassembler::Success;
6510e6d15924SDimitry Andric }
6511e6d15924SDimitry Andric
DecodeVPTMaskOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6512e6d15924SDimitry Andric static DecodeStatus DecodeVPTMaskOperand(MCInst &Inst, unsigned Val,
6513e6d15924SDimitry Andric uint64_t Address,
6514145449b1SDimitry Andric const MCDisassembler *Decoder) {
6515e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6516e6d15924SDimitry Andric
6517e6d15924SDimitry Andric // Parse VPT mask and encode it in the MCInst as an immediate with the same
6518e6d15924SDimitry Andric // format as the it_mask. That is, from the second 'e|t' encode 'e' as 1 and
6519e6d15924SDimitry Andric // 't' as 0 and finish with a 1.
6520e6d15924SDimitry Andric unsigned Imm = 0;
6521e6d15924SDimitry Andric // We always start with a 't'.
6522e6d15924SDimitry Andric unsigned CurBit = 0;
6523e6d15924SDimitry Andric for (int i = 3; i >= 0; --i) {
6524e6d15924SDimitry Andric // If the bit we are looking at is not the same as last one, invert the
6525e6d15924SDimitry Andric // CurBit, if it is the same leave it as is.
6526e6d15924SDimitry Andric CurBit ^= (Val >> i) & 1U;
6527e6d15924SDimitry Andric
6528e6d15924SDimitry Andric // Encode the CurBit at the right place in the immediate.
6529e6d15924SDimitry Andric Imm |= (CurBit << i);
6530e6d15924SDimitry Andric
6531e6d15924SDimitry Andric // If we are done, finish the encoding with a 1.
6532e6d15924SDimitry Andric if ((Val & ~(~0U << i)) == 0) {
6533e6d15924SDimitry Andric Imm |= 1U << i;
6534e6d15924SDimitry Andric break;
6535e6d15924SDimitry Andric }
6536e6d15924SDimitry Andric }
6537e6d15924SDimitry Andric
6538e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm));
6539e6d15924SDimitry Andric
6540e6d15924SDimitry Andric return S;
6541e6d15924SDimitry Andric }
6542e6d15924SDimitry Andric
DecodeVpredROperand(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6543e6d15924SDimitry Andric static DecodeStatus DecodeVpredROperand(MCInst &Inst, unsigned RegNo,
6544145449b1SDimitry Andric uint64_t Address,
6545145449b1SDimitry Andric const MCDisassembler *Decoder) {
6546e6d15924SDimitry Andric // The vpred_r operand type includes an MQPR register field derived
6547e6d15924SDimitry Andric // from the encoding. But we don't actually want to add an operand
6548e6d15924SDimitry Andric // to the MCInst at this stage, because AddThumbPredicate will do it
6549e6d15924SDimitry Andric // later, and will infer the register number from the TIED_TO
6550e6d15924SDimitry Andric // constraint. So this is a deliberately empty decoder method that
6551e6d15924SDimitry Andric // will inhibit the auto-generated disassembly code from adding an
6552e6d15924SDimitry Andric // operand at all.
6553e6d15924SDimitry Andric return MCDisassembler::Success;
6554e6d15924SDimitry Andric }
6555e6d15924SDimitry Andric
6556e3b55780SDimitry Andric [[maybe_unused]] static DecodeStatus
DecodeVpredNOperand(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6557e3b55780SDimitry Andric DecodeVpredNOperand(MCInst &Inst, unsigned RegNo, uint64_t Address,
6558e3b55780SDimitry Andric const MCDisassembler *Decoder) {
6559e3b55780SDimitry Andric // Similar to above, we want to ensure that no operands are added for the
6560e3b55780SDimitry Andric // vpred operands. (This is marked "maybe_unused" for the moment; because
6561e3b55780SDimitry Andric // DecoderEmitter currently (wrongly) omits operands with no instruction bits,
6562e3b55780SDimitry Andric // the decoder doesn't actually call it yet. That will be addressed in a
6563e3b55780SDimitry Andric // future change.)
6564e3b55780SDimitry Andric return MCDisassembler::Success;
6565e3b55780SDimitry Andric }
6566e3b55780SDimitry Andric
6567145449b1SDimitry Andric static DecodeStatus
DecodeRestrictedIPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6568145449b1SDimitry Andric DecodeRestrictedIPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
6569145449b1SDimitry Andric const MCDisassembler *Decoder) {
6570e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::EQ : ARMCC::NE));
6571e6d15924SDimitry Andric return MCDisassembler::Success;
6572e6d15924SDimitry Andric }
6573e6d15924SDimitry Andric
6574145449b1SDimitry Andric static DecodeStatus
DecodeRestrictedSPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6575145449b1SDimitry Andric DecodeRestrictedSPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
6576145449b1SDimitry Andric const MCDisassembler *Decoder) {
6577e6d15924SDimitry Andric unsigned Code;
6578e6d15924SDimitry Andric switch (Val & 0x3) {
6579e6d15924SDimitry Andric case 0:
6580e6d15924SDimitry Andric Code = ARMCC::GE;
6581e6d15924SDimitry Andric break;
6582e6d15924SDimitry Andric case 1:
6583e6d15924SDimitry Andric Code = ARMCC::LT;
6584e6d15924SDimitry Andric break;
6585e6d15924SDimitry Andric case 2:
6586e6d15924SDimitry Andric Code = ARMCC::GT;
6587e6d15924SDimitry Andric break;
6588e6d15924SDimitry Andric case 3:
6589e6d15924SDimitry Andric Code = ARMCC::LE;
6590e6d15924SDimitry Andric break;
6591e6d15924SDimitry Andric }
6592e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(Code));
6593e6d15924SDimitry Andric return MCDisassembler::Success;
6594e6d15924SDimitry Andric }
6595e6d15924SDimitry Andric
6596145449b1SDimitry Andric static DecodeStatus
DecodeRestrictedUPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6597145449b1SDimitry Andric DecodeRestrictedUPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
6598145449b1SDimitry Andric const MCDisassembler *Decoder) {
6599e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm((Val & 0x1) == 0 ? ARMCC::HS : ARMCC::HI));
6600e6d15924SDimitry Andric return MCDisassembler::Success;
6601e6d15924SDimitry Andric }
6602e6d15924SDimitry Andric
6603145449b1SDimitry Andric static DecodeStatus
DecodeRestrictedFPPredicateOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6604145449b1SDimitry Andric DecodeRestrictedFPPredicateOperand(MCInst &Inst, unsigned Val, uint64_t Address,
6605145449b1SDimitry Andric const MCDisassembler *Decoder) {
6606e6d15924SDimitry Andric unsigned Code;
6607e6d15924SDimitry Andric switch (Val) {
6608e6d15924SDimitry Andric default:
6609e6d15924SDimitry Andric return MCDisassembler::Fail;
6610e6d15924SDimitry Andric case 0:
6611e6d15924SDimitry Andric Code = ARMCC::EQ;
6612e6d15924SDimitry Andric break;
6613e6d15924SDimitry Andric case 1:
6614e6d15924SDimitry Andric Code = ARMCC::NE;
6615e6d15924SDimitry Andric break;
6616e6d15924SDimitry Andric case 4:
6617e6d15924SDimitry Andric Code = ARMCC::GE;
6618e6d15924SDimitry Andric break;
6619e6d15924SDimitry Andric case 5:
6620e6d15924SDimitry Andric Code = ARMCC::LT;
6621e6d15924SDimitry Andric break;
6622e6d15924SDimitry Andric case 6:
6623e6d15924SDimitry Andric Code = ARMCC::GT;
6624e6d15924SDimitry Andric break;
6625e6d15924SDimitry Andric case 7:
6626e6d15924SDimitry Andric Code = ARMCC::LE;
6627e6d15924SDimitry Andric break;
6628e6d15924SDimitry Andric }
6629e6d15924SDimitry Andric
6630e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(Code));
6631e6d15924SDimitry Andric return MCDisassembler::Success;
6632e6d15924SDimitry Andric }
6633e6d15924SDimitry Andric
DecodeVCVTImmOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6634e6d15924SDimitry Andric static DecodeStatus DecodeVCVTImmOperand(MCInst &Inst, unsigned Val,
6635145449b1SDimitry Andric uint64_t Address,
6636145449b1SDimitry Andric const MCDisassembler *Decoder) {
6637e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6638e6d15924SDimitry Andric
6639e6d15924SDimitry Andric unsigned DecodedVal = 64 - Val;
6640e6d15924SDimitry Andric
6641e6d15924SDimitry Andric switch (Inst.getOpcode()) {
6642e6d15924SDimitry Andric case ARM::MVE_VCVTf16s16_fix:
6643e6d15924SDimitry Andric case ARM::MVE_VCVTs16f16_fix:
6644e6d15924SDimitry Andric case ARM::MVE_VCVTf16u16_fix:
6645e6d15924SDimitry Andric case ARM::MVE_VCVTu16f16_fix:
6646e6d15924SDimitry Andric if (DecodedVal > 16)
6647e6d15924SDimitry Andric return MCDisassembler::Fail;
6648e6d15924SDimitry Andric break;
6649e6d15924SDimitry Andric case ARM::MVE_VCVTf32s32_fix:
6650e6d15924SDimitry Andric case ARM::MVE_VCVTs32f32_fix:
6651e6d15924SDimitry Andric case ARM::MVE_VCVTf32u32_fix:
6652e6d15924SDimitry Andric case ARM::MVE_VCVTu32f32_fix:
6653e6d15924SDimitry Andric if (DecodedVal > 32)
6654e6d15924SDimitry Andric return MCDisassembler::Fail;
6655e6d15924SDimitry Andric break;
6656e6d15924SDimitry Andric }
6657e6d15924SDimitry Andric
6658e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(64 - Val));
6659e6d15924SDimitry Andric
6660e6d15924SDimitry Andric return S;
6661e6d15924SDimitry Andric }
6662e6d15924SDimitry Andric
FixedRegForVSTRVLDR_SYSREG(unsigned Opcode)6663e6d15924SDimitry Andric static unsigned FixedRegForVSTRVLDR_SYSREG(unsigned Opcode) {
6664e6d15924SDimitry Andric switch (Opcode) {
6665e6d15924SDimitry Andric case ARM::VSTR_P0_off:
6666e6d15924SDimitry Andric case ARM::VSTR_P0_pre:
6667e6d15924SDimitry Andric case ARM::VSTR_P0_post:
6668e6d15924SDimitry Andric case ARM::VLDR_P0_off:
6669e6d15924SDimitry Andric case ARM::VLDR_P0_pre:
6670e6d15924SDimitry Andric case ARM::VLDR_P0_post:
6671e6d15924SDimitry Andric return ARM::P0;
6672e6d15924SDimitry Andric default:
6673e6d15924SDimitry Andric return 0;
6674e6d15924SDimitry Andric }
6675e6d15924SDimitry Andric }
6676e6d15924SDimitry Andric
6677e6d15924SDimitry Andric template <bool Writeback>
DecodeVSTRVLDR_SYSREG(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6678e6d15924SDimitry Andric static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Val,
6679e6d15924SDimitry Andric uint64_t Address,
6680145449b1SDimitry Andric const MCDisassembler *Decoder) {
6681e6d15924SDimitry Andric switch (Inst.getOpcode()) {
6682e6d15924SDimitry Andric case ARM::VSTR_FPSCR_pre:
6683e6d15924SDimitry Andric case ARM::VSTR_FPSCR_NZCVQC_pre:
6684e6d15924SDimitry Andric case ARM::VLDR_FPSCR_pre:
6685e6d15924SDimitry Andric case ARM::VLDR_FPSCR_NZCVQC_pre:
6686e6d15924SDimitry Andric case ARM::VSTR_FPSCR_off:
6687e6d15924SDimitry Andric case ARM::VSTR_FPSCR_NZCVQC_off:
6688e6d15924SDimitry Andric case ARM::VLDR_FPSCR_off:
6689e6d15924SDimitry Andric case ARM::VLDR_FPSCR_NZCVQC_off:
6690e6d15924SDimitry Andric case ARM::VSTR_FPSCR_post:
6691e6d15924SDimitry Andric case ARM::VSTR_FPSCR_NZCVQC_post:
6692e6d15924SDimitry Andric case ARM::VLDR_FPSCR_post:
6693e6d15924SDimitry Andric case ARM::VLDR_FPSCR_NZCVQC_post:
6694e6d15924SDimitry Andric const FeatureBitset &featureBits =
6695e6d15924SDimitry Andric ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
6696e6d15924SDimitry Andric
6697e6d15924SDimitry Andric if (!featureBits[ARM::HasMVEIntegerOps] && !featureBits[ARM::FeatureVFP2])
6698e6d15924SDimitry Andric return MCDisassembler::Fail;
6699e6d15924SDimitry Andric }
6700e6d15924SDimitry Andric
6701e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6702e6d15924SDimitry Andric if (unsigned Sysreg = FixedRegForVSTRVLDR_SYSREG(Inst.getOpcode()))
6703e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(Sysreg));
6704e6d15924SDimitry Andric unsigned Rn = fieldFromInstruction(Val, 16, 4);
6705e6d15924SDimitry Andric unsigned addr = fieldFromInstruction(Val, 0, 7) |
6706e6d15924SDimitry Andric (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
6707e6d15924SDimitry Andric
6708e6d15924SDimitry Andric if (Writeback) {
6709e6d15924SDimitry Andric if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
6710e6d15924SDimitry Andric return MCDisassembler::Fail;
6711e6d15924SDimitry Andric }
6712e6d15924SDimitry Andric if (!Check(S, DecodeT2AddrModeImm7s4(Inst, addr, Address, Decoder)))
6713e6d15924SDimitry Andric return MCDisassembler::Fail;
6714e6d15924SDimitry Andric
6715e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(ARMCC::AL));
6716e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
6717e6d15924SDimitry Andric
6718e6d15924SDimitry Andric return S;
6719e6d15924SDimitry Andric }
6720e6d15924SDimitry Andric
6721145449b1SDimitry Andric static inline DecodeStatus
DecodeMVE_MEM_pre(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder,unsigned Rn,OperandDecoder RnDecoder,OperandDecoder AddrDecoder)6722145449b1SDimitry Andric DecodeMVE_MEM_pre(MCInst &Inst, unsigned Val, uint64_t Address,
6723145449b1SDimitry Andric const MCDisassembler *Decoder, unsigned Rn,
6724145449b1SDimitry Andric OperandDecoder RnDecoder, OperandDecoder AddrDecoder) {
6725e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6726e6d15924SDimitry Andric
6727e6d15924SDimitry Andric unsigned Qd = fieldFromInstruction(Val, 13, 3);
6728e6d15924SDimitry Andric unsigned addr = fieldFromInstruction(Val, 0, 7) |
6729e6d15924SDimitry Andric (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8);
6730e6d15924SDimitry Andric
6731e6d15924SDimitry Andric if (!Check(S, RnDecoder(Inst, Rn, Address, Decoder)))
6732e6d15924SDimitry Andric return MCDisassembler::Fail;
6733e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6734e6d15924SDimitry Andric return MCDisassembler::Fail;
6735e6d15924SDimitry Andric if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder)))
6736e6d15924SDimitry Andric return MCDisassembler::Fail;
6737e6d15924SDimitry Andric
6738e6d15924SDimitry Andric return S;
6739e6d15924SDimitry Andric }
6740e6d15924SDimitry Andric
6741e6d15924SDimitry Andric template <int shift>
DecodeMVE_MEM_1_pre(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6742e6d15924SDimitry Andric static DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val,
6743145449b1SDimitry Andric uint64_t Address,
6744145449b1SDimitry Andric const MCDisassembler *Decoder) {
6745e6d15924SDimitry Andric return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
6746e6d15924SDimitry Andric fieldFromInstruction(Val, 16, 3),
6747e6d15924SDimitry Andric DecodetGPRRegisterClass,
6748e6d15924SDimitry Andric DecodeTAddrModeImm7<shift>);
6749e6d15924SDimitry Andric }
6750e6d15924SDimitry Andric
6751e6d15924SDimitry Andric template <int shift>
DecodeMVE_MEM_2_pre(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6752e6d15924SDimitry Andric static DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val,
6753145449b1SDimitry Andric uint64_t Address,
6754145449b1SDimitry Andric const MCDisassembler *Decoder) {
6755e6d15924SDimitry Andric return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
6756e6d15924SDimitry Andric fieldFromInstruction(Val, 16, 4),
6757e6d15924SDimitry Andric DecoderGPRRegisterClass,
6758e6d15924SDimitry Andric DecodeT2AddrModeImm7<shift,1>);
6759e6d15924SDimitry Andric }
6760e6d15924SDimitry Andric
6761e6d15924SDimitry Andric template <int shift>
DecodeMVE_MEM_3_pre(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6762e6d15924SDimitry Andric static DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val,
6763145449b1SDimitry Andric uint64_t Address,
6764145449b1SDimitry Andric const MCDisassembler *Decoder) {
6765e6d15924SDimitry Andric return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder,
6766e6d15924SDimitry Andric fieldFromInstruction(Val, 17, 3),
6767e6d15924SDimitry Andric DecodeMQPRRegisterClass,
6768e6d15924SDimitry Andric DecodeMveAddrModeQ<shift>);
6769e6d15924SDimitry Andric }
6770e6d15924SDimitry Andric
6771e6d15924SDimitry Andric template <unsigned MinLog, unsigned MaxLog>
DecodePowerTwoOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6772e6d15924SDimitry Andric static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val,
6773e6d15924SDimitry Andric uint64_t Address,
6774145449b1SDimitry Andric const MCDisassembler *Decoder) {
6775e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6776e6d15924SDimitry Andric
6777e6d15924SDimitry Andric if (Val < MinLog || Val > MaxLog)
6778e6d15924SDimitry Andric return MCDisassembler::Fail;
6779e6d15924SDimitry Andric
6780e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(1LL << Val));
6781e6d15924SDimitry Andric return S;
6782e6d15924SDimitry Andric }
6783e6d15924SDimitry Andric
6784e6d15924SDimitry Andric template <unsigned start>
6785145449b1SDimitry Andric static DecodeStatus
DecodeMVEPairVectorIndexOperand(MCInst & Inst,unsigned Val,uint64_t Address,const MCDisassembler * Decoder)6786145449b1SDimitry Andric DecodeMVEPairVectorIndexOperand(MCInst &Inst, unsigned Val, uint64_t Address,
6787145449b1SDimitry Andric const MCDisassembler *Decoder) {
6788e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6789e6d15924SDimitry Andric
6790e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(start + Val));
6791e6d15924SDimitry Andric
6792e6d15924SDimitry Andric return S;
6793e6d15924SDimitry Andric }
6794e6d15924SDimitry Andric
DecodeMVEVMOVQtoDReg(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6795e6d15924SDimitry Andric static DecodeStatus DecodeMVEVMOVQtoDReg(MCInst &Inst, unsigned Insn,
6796145449b1SDimitry Andric uint64_t Address,
6797145449b1SDimitry Andric const MCDisassembler *Decoder) {
6798e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6799e6d15924SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 0, 4);
6800e6d15924SDimitry Andric unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
6801e6d15924SDimitry Andric unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
6802e6d15924SDimitry Andric fieldFromInstruction(Insn, 13, 3));
6803e6d15924SDimitry Andric unsigned index = fieldFromInstruction(Insn, 4, 1);
6804e6d15924SDimitry Andric
6805e6d15924SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
6806e6d15924SDimitry Andric return MCDisassembler::Fail;
6807e6d15924SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
6808e6d15924SDimitry Andric return MCDisassembler::Fail;
6809e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6810e6d15924SDimitry Andric return MCDisassembler::Fail;
6811e6d15924SDimitry Andric if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
6812e6d15924SDimitry Andric return MCDisassembler::Fail;
6813e6d15924SDimitry Andric if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
6814e6d15924SDimitry Andric return MCDisassembler::Fail;
6815e6d15924SDimitry Andric
6816e6d15924SDimitry Andric return S;
6817e6d15924SDimitry Andric }
6818e6d15924SDimitry Andric
DecodeMVEVMOVDRegtoQ(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6819e6d15924SDimitry Andric static DecodeStatus DecodeMVEVMOVDRegtoQ(MCInst &Inst, unsigned Insn,
6820145449b1SDimitry Andric uint64_t Address,
6821145449b1SDimitry Andric const MCDisassembler *Decoder) {
6822e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6823e6d15924SDimitry Andric unsigned Rt = fieldFromInstruction(Insn, 0, 4);
6824e6d15924SDimitry Andric unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
6825e6d15924SDimitry Andric unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
6826e6d15924SDimitry Andric fieldFromInstruction(Insn, 13, 3));
6827e6d15924SDimitry Andric unsigned index = fieldFromInstruction(Insn, 4, 1);
6828e6d15924SDimitry Andric
6829e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6830e6d15924SDimitry Andric return MCDisassembler::Fail;
6831e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6832e6d15924SDimitry Andric return MCDisassembler::Fail;
6833e6d15924SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
6834e6d15924SDimitry Andric return MCDisassembler::Fail;
6835e6d15924SDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2, Address, Decoder)))
6836e6d15924SDimitry Andric return MCDisassembler::Fail;
6837e6d15924SDimitry Andric if (!Check(S, DecodeMVEPairVectorIndexOperand<2>(Inst, index, Address, Decoder)))
6838e6d15924SDimitry Andric return MCDisassembler::Fail;
6839e6d15924SDimitry Andric if (!Check(S, DecodeMVEPairVectorIndexOperand<0>(Inst, index, Address, Decoder)))
6840e6d15924SDimitry Andric return MCDisassembler::Fail;
6841e6d15924SDimitry Andric
6842e6d15924SDimitry Andric return S;
6843e6d15924SDimitry Andric }
6844e6d15924SDimitry Andric
6845145449b1SDimitry Andric static DecodeStatus
DecodeMVEOverlappingLongShift(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6846145449b1SDimitry Andric DecodeMVEOverlappingLongShift(MCInst &Inst, unsigned Insn, uint64_t Address,
6847145449b1SDimitry Andric const MCDisassembler *Decoder) {
6848e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6849e6d15924SDimitry Andric
6850e6d15924SDimitry Andric unsigned RdaLo = fieldFromInstruction(Insn, 17, 3) << 1;
6851e6d15924SDimitry Andric unsigned RdaHi = fieldFromInstruction(Insn, 9, 3) << 1;
6852e6d15924SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 12, 4);
6853e6d15924SDimitry Andric
6854e6d15924SDimitry Andric if (RdaHi == 14) {
6855e6d15924SDimitry Andric // This value of RdaHi (really indicating pc, because RdaHi has to
6856e6d15924SDimitry Andric // be an odd-numbered register, so the low bit will be set by the
6857e6d15924SDimitry Andric // decode function below) indicates that we must decode as SQRSHR
6858e6d15924SDimitry Andric // or UQRSHL, which both have a single Rda register field with all
6859e6d15924SDimitry Andric // four bits.
6860e6d15924SDimitry Andric unsigned Rda = fieldFromInstruction(Insn, 16, 4);
6861e6d15924SDimitry Andric
6862e6d15924SDimitry Andric switch (Inst.getOpcode()) {
6863e6d15924SDimitry Andric case ARM::MVE_ASRLr:
6864e6d15924SDimitry Andric case ARM::MVE_SQRSHRL:
6865e6d15924SDimitry Andric Inst.setOpcode(ARM::MVE_SQRSHR);
6866e6d15924SDimitry Andric break;
6867e6d15924SDimitry Andric case ARM::MVE_LSLLr:
6868e6d15924SDimitry Andric case ARM::MVE_UQRSHLL:
6869e6d15924SDimitry Andric Inst.setOpcode(ARM::MVE_UQRSHL);
6870e6d15924SDimitry Andric break;
6871e6d15924SDimitry Andric default:
6872e6d15924SDimitry Andric llvm_unreachable("Unexpected starting opcode!");
6873e6d15924SDimitry Andric }
6874e6d15924SDimitry Andric
6875e6d15924SDimitry Andric // Rda as output parameter
6876e6d15924SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
6877e6d15924SDimitry Andric return MCDisassembler::Fail;
6878e6d15924SDimitry Andric
6879e6d15924SDimitry Andric // Rda again as input parameter
6880e6d15924SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rda, Address, Decoder)))
6881e6d15924SDimitry Andric return MCDisassembler::Fail;
6882e6d15924SDimitry Andric
6883e6d15924SDimitry Andric // Rm, the amount to shift by
6884e6d15924SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
6885e6d15924SDimitry Andric return MCDisassembler::Fail;
6886e6d15924SDimitry Andric
68871d5ae102SDimitry Andric if (fieldFromInstruction (Insn, 6, 3) != 4)
68881d5ae102SDimitry Andric return MCDisassembler::SoftFail;
68891d5ae102SDimitry Andric
68901d5ae102SDimitry Andric if (Rda == Rm)
68911d5ae102SDimitry Andric return MCDisassembler::SoftFail;
68921d5ae102SDimitry Andric
6893e6d15924SDimitry Andric return S;
6894e6d15924SDimitry Andric }
6895e6d15924SDimitry Andric
6896e6d15924SDimitry Andric // Otherwise, we decode as whichever opcode our caller has already
6897e6d15924SDimitry Andric // put into Inst. Those all look the same:
6898e6d15924SDimitry Andric
6899e6d15924SDimitry Andric // RdaLo,RdaHi as output parameters
6900e6d15924SDimitry Andric if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
6901e6d15924SDimitry Andric return MCDisassembler::Fail;
6902e6d15924SDimitry Andric if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
6903e6d15924SDimitry Andric return MCDisassembler::Fail;
6904e6d15924SDimitry Andric
6905e6d15924SDimitry Andric // RdaLo,RdaHi again as input parameters
6906e6d15924SDimitry Andric if (!Check(S, DecodetGPREvenRegisterClass(Inst, RdaLo, Address, Decoder)))
6907e6d15924SDimitry Andric return MCDisassembler::Fail;
6908e6d15924SDimitry Andric if (!Check(S, DecodetGPROddRegisterClass(Inst, RdaHi, Address, Decoder)))
6909e6d15924SDimitry Andric return MCDisassembler::Fail;
6910e6d15924SDimitry Andric
6911e6d15924SDimitry Andric // Rm, the amount to shift by
6912e6d15924SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
6913e6d15924SDimitry Andric return MCDisassembler::Fail;
6914e6d15924SDimitry Andric
69151d5ae102SDimitry Andric if (Inst.getOpcode() == ARM::MVE_SQRSHRL ||
69161d5ae102SDimitry Andric Inst.getOpcode() == ARM::MVE_UQRSHLL) {
69171d5ae102SDimitry Andric unsigned Saturate = fieldFromInstruction(Insn, 7, 1);
69181d5ae102SDimitry Andric // Saturate, the bit position for saturation
69191d5ae102SDimitry Andric Inst.addOperand(MCOperand::createImm(Saturate));
69201d5ae102SDimitry Andric }
69211d5ae102SDimitry Andric
6922e6d15924SDimitry Andric return S;
6923e6d15924SDimitry Andric }
6924e6d15924SDimitry Andric
DecodeMVEVCVTt1fp(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6925145449b1SDimitry Andric static DecodeStatus DecodeMVEVCVTt1fp(MCInst &Inst, unsigned Insn,
6926145449b1SDimitry Andric uint64_t Address,
6927145449b1SDimitry Andric const MCDisassembler *Decoder) {
6928e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6929e6d15924SDimitry Andric unsigned Qd = ((fieldFromInstruction(Insn, 22, 1) << 3) |
6930e6d15924SDimitry Andric fieldFromInstruction(Insn, 13, 3));
6931e6d15924SDimitry Andric unsigned Qm = ((fieldFromInstruction(Insn, 5, 1) << 3) |
6932e6d15924SDimitry Andric fieldFromInstruction(Insn, 1, 3));
6933e6d15924SDimitry Andric unsigned imm6 = fieldFromInstruction(Insn, 16, 6);
6934e6d15924SDimitry Andric
6935e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder)))
6936e6d15924SDimitry Andric return MCDisassembler::Fail;
6937e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
6938e6d15924SDimitry Andric return MCDisassembler::Fail;
6939e6d15924SDimitry Andric if (!Check(S, DecodeVCVTImmOperand(Inst, imm6, Address, Decoder)))
6940e6d15924SDimitry Andric return MCDisassembler::Fail;
6941e6d15924SDimitry Andric
6942e6d15924SDimitry Andric return S;
6943e6d15924SDimitry Andric }
6944e6d15924SDimitry Andric
6945e6d15924SDimitry Andric template <bool scalar, OperandDecoder predicate_decoder>
DecodeMVEVCMP(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6946e6d15924SDimitry Andric static DecodeStatus DecodeMVEVCMP(MCInst &Inst, unsigned Insn, uint64_t Address,
6947145449b1SDimitry Andric const MCDisassembler *Decoder) {
6948e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6949e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::VPR));
6950e6d15924SDimitry Andric unsigned Qn = fieldFromInstruction(Insn, 17, 3);
6951e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qn, Address, Decoder)))
6952e6d15924SDimitry Andric return MCDisassembler::Fail;
6953e6d15924SDimitry Andric
6954e6d15924SDimitry Andric unsigned fc;
6955e6d15924SDimitry Andric
6956e6d15924SDimitry Andric if (scalar) {
6957e6d15924SDimitry Andric fc = fieldFromInstruction(Insn, 12, 1) << 2 |
6958e6d15924SDimitry Andric fieldFromInstruction(Insn, 7, 1) |
6959e6d15924SDimitry Andric fieldFromInstruction(Insn, 5, 1) << 1;
6960e6d15924SDimitry Andric unsigned Rm = fieldFromInstruction(Insn, 0, 4);
6961e6d15924SDimitry Andric if (!Check(S, DecodeGPRwithZRRegisterClass(Inst, Rm, Address, Decoder)))
6962e6d15924SDimitry Andric return MCDisassembler::Fail;
6963e6d15924SDimitry Andric } else {
6964e6d15924SDimitry Andric fc = fieldFromInstruction(Insn, 12, 1) << 2 |
6965e6d15924SDimitry Andric fieldFromInstruction(Insn, 7, 1) |
6966e6d15924SDimitry Andric fieldFromInstruction(Insn, 0, 1) << 1;
6967e6d15924SDimitry Andric unsigned Qm = fieldFromInstruction(Insn, 5, 1) << 4 |
6968e6d15924SDimitry Andric fieldFromInstruction(Insn, 1, 3);
6969e6d15924SDimitry Andric if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder)))
6970e6d15924SDimitry Andric return MCDisassembler::Fail;
6971e6d15924SDimitry Andric }
6972e6d15924SDimitry Andric
6973e6d15924SDimitry Andric if (!Check(S, predicate_decoder(Inst, fc, Address, Decoder)))
6974e6d15924SDimitry Andric return MCDisassembler::Fail;
6975e6d15924SDimitry Andric
6976e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(ARMVCC::None));
6977e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(0));
6978e6d15924SDimitry Andric Inst.addOperand(MCOperand::createImm(0));
6979e6d15924SDimitry Andric
6980e6d15924SDimitry Andric return S;
6981e6d15924SDimitry Andric }
6982e6d15924SDimitry Andric
DecodeMveVCTP(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6983e6d15924SDimitry Andric static DecodeStatus DecodeMveVCTP(MCInst &Inst, unsigned Insn, uint64_t Address,
6984145449b1SDimitry Andric const MCDisassembler *Decoder) {
6985e6d15924SDimitry Andric DecodeStatus S = MCDisassembler::Success;
6986e6d15924SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::VPR));
6987e6d15924SDimitry Andric unsigned Rn = fieldFromInstruction(Insn, 16, 4);
6988e6d15924SDimitry Andric if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
6989e6d15924SDimitry Andric return MCDisassembler::Fail;
6990e6d15924SDimitry Andric return S;
6991e6d15924SDimitry Andric }
69921d5ae102SDimitry Andric
DecodeMVEVPNOT(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)6993145449b1SDimitry Andric static DecodeStatus DecodeMVEVPNOT(MCInst &Inst, unsigned Insn,
6994145449b1SDimitry Andric uint64_t Address,
6995145449b1SDimitry Andric const MCDisassembler *Decoder) {
69961d5ae102SDimitry Andric DecodeStatus S = MCDisassembler::Success;
69971d5ae102SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::VPR));
69981d5ae102SDimitry Andric Inst.addOperand(MCOperand::createReg(ARM::VPR));
69991d5ae102SDimitry Andric return S;
70001d5ae102SDimitry Andric }
7001706b4fc4SDimitry Andric
DecodeT2AddSubSPImm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)7002706b4fc4SDimitry Andric static DecodeStatus DecodeT2AddSubSPImm(MCInst &Inst, unsigned Insn,
7003145449b1SDimitry Andric uint64_t Address,
7004145449b1SDimitry Andric const MCDisassembler *Decoder) {
7005706b4fc4SDimitry Andric const unsigned Rd = fieldFromInstruction(Insn, 8, 4);
7006706b4fc4SDimitry Andric const unsigned Rn = fieldFromInstruction(Insn, 16, 4);
7007706b4fc4SDimitry Andric const unsigned Imm12 = fieldFromInstruction(Insn, 26, 1) << 11 |
7008706b4fc4SDimitry Andric fieldFromInstruction(Insn, 12, 3) << 8 |
7009706b4fc4SDimitry Andric fieldFromInstruction(Insn, 0, 8);
7010706b4fc4SDimitry Andric const unsigned TypeT3 = fieldFromInstruction(Insn, 25, 1);
7011706b4fc4SDimitry Andric unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
7012706b4fc4SDimitry Andric unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
7013706b4fc4SDimitry Andric unsigned S = fieldFromInstruction(Insn, 20, 1);
7014706b4fc4SDimitry Andric if (sign1 != sign2)
7015706b4fc4SDimitry Andric return MCDisassembler::Fail;
7016706b4fc4SDimitry Andric
7017706b4fc4SDimitry Andric // T3 does a zext of imm12, where T2 does a ThumbExpandImm (T2SOImm)
7018706b4fc4SDimitry Andric DecodeStatus DS = MCDisassembler::Success;
7019706b4fc4SDimitry Andric if ((!Check(DS,
7020706b4fc4SDimitry Andric DecodeGPRspRegisterClass(Inst, Rd, Address, Decoder))) || // dst
7021706b4fc4SDimitry Andric (!Check(DS, DecodeGPRspRegisterClass(Inst, Rn, Address, Decoder))))
7022706b4fc4SDimitry Andric return MCDisassembler::Fail;
7023706b4fc4SDimitry Andric if (TypeT3) {
7024706b4fc4SDimitry Andric Inst.setOpcode(sign1 ? ARM::t2SUBspImm12 : ARM::t2ADDspImm12);
7025706b4fc4SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm12)); // zext imm12
7026706b4fc4SDimitry Andric } else {
7027706b4fc4SDimitry Andric Inst.setOpcode(sign1 ? ARM::t2SUBspImm : ARM::t2ADDspImm);
7028706b4fc4SDimitry Andric if (!Check(DS, DecodeT2SOImm(Inst, Imm12, Address, Decoder))) // imm12
7029706b4fc4SDimitry Andric return MCDisassembler::Fail;
7030706b4fc4SDimitry Andric if (!Check(DS, DecodeCCOutOperand(Inst, S, Address, Decoder))) // cc_out
7031706b4fc4SDimitry Andric return MCDisassembler::Fail;
7032344a3780SDimitry Andric }
7033706b4fc4SDimitry Andric
7034706b4fc4SDimitry Andric return DS;
7035706b4fc4SDimitry Andric }
7036ac9a064cSDimitry Andric
DecodeLazyLoadStoreMul(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)7037ac9a064cSDimitry Andric static DecodeStatus DecodeLazyLoadStoreMul(MCInst &Inst, unsigned Insn,
7038ac9a064cSDimitry Andric uint64_t Address,
7039ac9a064cSDimitry Andric const MCDisassembler *Decoder) {
7040ac9a064cSDimitry Andric DecodeStatus S = MCDisassembler::Success;
7041ac9a064cSDimitry Andric
7042ac9a064cSDimitry Andric const unsigned Rn = fieldFromInstruction(Insn, 16, 4);
7043ac9a064cSDimitry Andric // Adding Rn, holding memory location to save/load to/from, the only argument
7044ac9a064cSDimitry Andric // that is being encoded.
7045ac9a064cSDimitry Andric // '$Rn' in the assembly.
7046ac9a064cSDimitry Andric if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
7047ac9a064cSDimitry Andric return MCDisassembler::Fail;
7048ac9a064cSDimitry Andric // An optional predicate, '$p' in the assembly.
7049ac9a064cSDimitry Andric DecodePredicateOperand(Inst, ARMCC::AL, Address, Decoder);
7050ac9a064cSDimitry Andric // An immediate that represents a floating point registers list. '$regs' in
7051ac9a064cSDimitry Andric // the assembly.
7052ac9a064cSDimitry Andric Inst.addOperand(MCOperand::createImm(0)); // Arbitrary value, has no effect.
7053ac9a064cSDimitry Andric
7054ac9a064cSDimitry Andric return S;
7055ac9a064cSDimitry Andric }
7056