blob: 15e1c71eb5862a6565c9e3975e59c35aabca42d1 [file] [log] [blame]
Jia Liu31d157a2012-02-18 12:03:15 +00001//===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===//
Johnny Chenb68a3ee2010-04-02 22:27:38 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Johnny Chenb68a3ee2010-04-02 22:27:38 +00009
10#define DEBUG_TYPE "arm-disassembler"
11
Owen Anderson8d7d2e12011-08-09 20:55:18 +000012#include "ARM.h"
James Molloyb9505852011-09-07 17:24:38 +000013#include "ARMSubtarget.h"
Owen Anderson8d7d2e12011-08-09 20:55:18 +000014#include "MCTargetDesc/ARMAddressingModes.h"
Kevin Enderby9e5887b2011-10-04 22:44:48 +000015#include "MCTargetDesc/ARMMCExpr.h"
Owen Anderson8d7d2e12011-08-09 20:55:18 +000016#include "MCTargetDesc/ARMBaseInfo.h"
Sean Callanan9899f702010-04-13 21:21:57 +000017#include "llvm/MC/EDInstInfo.h"
Johnny Chenb68a3ee2010-04-02 22:27:38 +000018#include "llvm/MC/MCInst.h"
Benjamin Kramereea66f62011-11-11 12:39:41 +000019#include "llvm/MC/MCInstrDesc.h"
Owen Anderson8d7d2e12011-08-09 20:55:18 +000020#include "llvm/MC/MCExpr.h"
21#include "llvm/MC/MCContext.h"
Owen Andersona1c11002011-09-01 23:35:51 +000022#include "llvm/MC/MCDisassembler.h"
Johnny Chenb68a3ee2010-04-02 22:27:38 +000023#include "llvm/Support/Debug.h"
24#include "llvm/Support/MemoryObject.h"
25#include "llvm/Support/ErrorHandling.h"
Evan Cheng3e74d6f2011-08-24 18:08:43 +000026#include "llvm/Support/TargetRegistry.h"
Johnny Chenb68a3ee2010-04-02 22:27:38 +000027#include "llvm/Support/raw_ostream.h"
28
James Molloyc047dca2011-09-01 18:02:14 +000029using namespace llvm;
Owen Anderson83e3f672011-08-17 17:44:15 +000030
Owen Andersona6804442011-09-01 23:23:50 +000031typedef MCDisassembler::DecodeStatus DecodeStatus;
32
Owen Andersona1c11002011-09-01 23:35:51 +000033namespace {
34/// ARMDisassembler - ARM disassembler for all ARM platforms.
35class ARMDisassembler : public MCDisassembler {
36public:
37 /// Constructor - Initializes the disassembler.
38 ///
James Molloyb9505852011-09-07 17:24:38 +000039 ARMDisassembler(const MCSubtargetInfo &STI) :
40 MCDisassembler(STI) {
Owen Andersona1c11002011-09-01 23:35:51 +000041 }
42
43 ~ARMDisassembler() {
44 }
45
46 /// getInstruction - See MCDisassembler.
47 DecodeStatus getInstruction(MCInst &instr,
48 uint64_t &size,
Derek Schuffadef06a2012-02-29 01:09:06 +000049 const MemoryObject &region,
Owen Andersona1c11002011-09-01 23:35:51 +000050 uint64_t address,
Owen Anderson98c5dda2011-09-15 23:38:46 +000051 raw_ostream &vStream,
52 raw_ostream &cStream) const;
Owen Andersona1c11002011-09-01 23:35:51 +000053
54 /// getEDInfo - See MCDisassembler.
Benjamin Kramer88b6fc02012-02-11 14:51:07 +000055 const EDInstInfo *getEDInfo() const;
Owen Andersona1c11002011-09-01 23:35:51 +000056private:
57};
58
59/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.
60class ThumbDisassembler : public MCDisassembler {
61public:
62 /// Constructor - Initializes the disassembler.
63 ///
James Molloyb9505852011-09-07 17:24:38 +000064 ThumbDisassembler(const MCSubtargetInfo &STI) :
65 MCDisassembler(STI) {
Owen Andersona1c11002011-09-01 23:35:51 +000066 }
67
68 ~ThumbDisassembler() {
69 }
70
71 /// getInstruction - See MCDisassembler.
72 DecodeStatus getInstruction(MCInst &instr,
73 uint64_t &size,
Derek Schuffadef06a2012-02-29 01:09:06 +000074 const MemoryObject &region,
Owen Andersona1c11002011-09-01 23:35:51 +000075 uint64_t address,
Owen Anderson98c5dda2011-09-15 23:38:46 +000076 raw_ostream &vStream,
77 raw_ostream &cStream) const;
Owen Andersona1c11002011-09-01 23:35:51 +000078
79 /// getEDInfo - See MCDisassembler.
Benjamin Kramer88b6fc02012-02-11 14:51:07 +000080 const EDInstInfo *getEDInfo() const;
Owen Andersona1c11002011-09-01 23:35:51 +000081private:
82 mutable std::vector<unsigned> ITBlock;
Owen Andersond2fc31b2011-09-08 22:42:49 +000083 DecodeStatus AddThumbPredicate(MCInst&) const;
Owen Andersona1c11002011-09-01 23:35:51 +000084 void UpdateThumbVFPPredicate(MCInst&) const;
85};
86}
87
Owen Andersona6804442011-09-01 23:23:50 +000088static bool Check(DecodeStatus &Out, DecodeStatus In) {
James Molloyc047dca2011-09-01 18:02:14 +000089 switch (In) {
90 case MCDisassembler::Success:
91 // Out stays the same.
92 return true;
93 case MCDisassembler::SoftFail:
94 Out = In;
95 return true;
96 case MCDisassembler::Fail:
97 Out = In;
98 return false;
99 }
David Blaikie4d6ccb52012-01-20 21:51:11 +0000100 llvm_unreachable("Invalid DecodeStatus!");
James Molloyc047dca2011-09-01 18:02:14 +0000101}
Owen Anderson83e3f672011-08-17 17:44:15 +0000102
James Molloya5d58562011-09-07 19:42:28 +0000103
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000104// Forward declare these because the autogenerated code will reference them.
105// Definitions are further down.
Owen Andersona6804442011-09-01 23:23:50 +0000106static DecodeStatus DecodeGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000107 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000108static DecodeStatus DecodeGPRnopcRegisterClass(llvm::MCInst &Inst,
Jim Grosbachc4057822011-08-17 21:58:18 +0000109 unsigned RegNo, uint64_t Address,
110 const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000111static DecodeStatus DecodetGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000112 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000113static DecodeStatus DecodetcGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000114 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000115static DecodeStatus DecoderGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000116 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000117static DecodeStatus DecodeSPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000118 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000119static DecodeStatus DecodeDPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000120 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000121static DecodeStatus DecodeDPR_8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000122 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000123static DecodeStatus DecodeDPR_VFP2RegisterClass(llvm::MCInst &Inst,
Jim Grosbachc4057822011-08-17 21:58:18 +0000124 unsigned RegNo,
125 uint64_t Address,
126 const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000127static DecodeStatus DecodeQPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000128 uint64_t Address, const void *Decoder);
Jim Grosbach28f08c92012-03-05 19:33:30 +0000129static DecodeStatus DecodeDPairRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
130 uint64_t Address, const void *Decoder);
Johnny Chen270159f2010-08-12 01:40:54 +0000131
Owen Andersona6804442011-09-01 23:23:50 +0000132static DecodeStatus DecodePredicateOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000133 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000134static DecodeStatus DecodeCCOutOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000135 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000136static DecodeStatus DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000137 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000138static DecodeStatus DecodeRegListOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000139 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000140static DecodeStatus DecodeSPRRegListOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000141 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000142static DecodeStatus DecodeDPRRegListOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000143 uint64_t Address, const void *Decoder);
Johnny Chenb68a3ee2010-04-02 22:27:38 +0000144
Owen Andersona6804442011-09-01 23:23:50 +0000145static DecodeStatus DecodeBitfieldMaskOperand(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000146 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000147static DecodeStatus DecodeCopMemInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000148 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000149static DecodeStatus DecodeAddrMode2IdxInstruction(llvm::MCInst &Inst,
Jim Grosbachc4057822011-08-17 21:58:18 +0000150 unsigned Insn,
151 uint64_t Address,
152 const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000153static DecodeStatus DecodeSORegMemOperand(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000154 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000155static DecodeStatus DecodeAddrMode3Instruction(llvm::MCInst &Inst,unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000156 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000157static DecodeStatus DecodeSORegImmOperand(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000158 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000159static DecodeStatus DecodeSORegRegOperand(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000160 uint64_t Address, const void *Decoder);
161
Owen Andersona6804442011-09-01 23:23:50 +0000162static DecodeStatus DecodeMemMultipleWritebackInstruction(llvm::MCInst & Inst,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000163 unsigned Insn,
164 uint64_t Adddress,
165 const void *Decoder);
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000166static DecodeStatus DecodeT2MOVTWInstruction(llvm::MCInst &Inst, unsigned Insn,
167 uint64_t Address, const void *Decoder);
168static DecodeStatus DecodeArmMOVTWInstruction(llvm::MCInst &Inst, unsigned Insn,
169 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000170static DecodeStatus DecodeSMLAInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000171 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000172static DecodeStatus DecodeCPSInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson35008c22011-08-09 23:05:39 +0000173 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000174static DecodeStatus DecodeT2CPSInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson6153a032011-08-23 17:45:18 +0000175 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000176static DecodeStatus DecodeAddrModeImm12Operand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000177 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000178static DecodeStatus DecodeAddrMode5Operand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000179 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000180static DecodeStatus DecodeAddrMode7Operand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000181 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000182static DecodeStatus DecodeBranchImmInstruction(llvm::MCInst &Inst,unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000183 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000184static DecodeStatus DecodeAddrMode6Operand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000185 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000186static DecodeStatus DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000187 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000188static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000189 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000190static DecodeStatus DecodeVLD1DupInstruction(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000191 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000192static DecodeStatus DecodeVLD2DupInstruction(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000193 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000194static DecodeStatus DecodeVLD3DupInstruction(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000195 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000196static DecodeStatus DecodeVLD4DupInstruction(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000197 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000198static DecodeStatus DecodeNEONModImmInstruction(llvm::MCInst &Inst,unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000199 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000200static DecodeStatus DecodeVSHLMaxInstruction(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000201 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000202static DecodeStatus DecodeShiftRight8Imm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000203 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000204static DecodeStatus DecodeShiftRight16Imm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000205 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000206static DecodeStatus DecodeShiftRight32Imm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000207 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000208static DecodeStatus DecodeShiftRight64Imm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000209 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000210static DecodeStatus DecodeTBLInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000211 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000212static DecodeStatus DecodePostIdxReg(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000213 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000214static DecodeStatus DecodeCoprocessor(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000215 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000216static DecodeStatus DecodeMemBarrierOption(llvm::MCInst &Inst, unsigned Insn,
Owen Andersonc36481c2011-08-09 23:25:42 +0000217 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000218static DecodeStatus DecodeMSRMask(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson26d2f0a2011-08-11 20:21:46 +0000219 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000220static DecodeStatus DecodeDoubleRegLoad(llvm::MCInst &Inst, unsigned Insn,
Owen Andersoncbfc0442011-08-11 21:34:58 +0000221 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000222static DecodeStatus DecodeDoubleRegStore(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson3f3570a2011-08-12 17:58:32 +0000223 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000224static DecodeStatus DecodeLDRPreImm(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson9ab0f252011-08-26 20:43:14 +0000225 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000226static DecodeStatus DecodeLDRPreReg(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson9ab0f252011-08-26 20:43:14 +0000227 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000228static DecodeStatus DecodeSTRPreImm(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7cdbf082011-08-12 18:12:39 +0000229 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000230static DecodeStatus DecodeSTRPreReg(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7cdbf082011-08-12 18:12:39 +0000231 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000232static DecodeStatus DecodeVLD1LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +0000233 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000234static DecodeStatus DecodeVLD2LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +0000235 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000236static DecodeStatus DecodeVLD3LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +0000237 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000238static DecodeStatus DecodeVLD4LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +0000239 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000240static DecodeStatus DecodeVST1LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +0000241 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000242static DecodeStatus DecodeVST2LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +0000243 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000244static DecodeStatus DecodeVST3LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +0000245 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000246static DecodeStatus DecodeVST4LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +0000247 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000248static DecodeStatus DecodeVMOVSRR(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson357ec682011-08-22 20:27:12 +0000249 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000250static DecodeStatus DecodeVMOVRRS(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson357ec682011-08-22 20:27:12 +0000251 uint64_t Address, const void *Decoder);
Owen Andersoncb9fed62011-10-28 18:02:13 +0000252static DecodeStatus DecodeSwap(llvm::MCInst &Inst, unsigned Insn,
253 uint64_t Address, const void *Decoder);
Owen Andersonb589be92011-11-15 19:55:00 +0000254static DecodeStatus DecodeVCVTD(llvm::MCInst &Inst, unsigned Insn,
255 uint64_t Address, const void *Decoder);
256static DecodeStatus DecodeVCVTQ(llvm::MCInst &Inst, unsigned Insn,
257 uint64_t Address, const void *Decoder);
258
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000259
Owen Andersona6804442011-09-01 23:23:50 +0000260static DecodeStatus DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000261 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000262static DecodeStatus DecodeThumbBROperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000263 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000264static DecodeStatus DecodeT2BROperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000265 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000266static DecodeStatus DecodeThumbCmpBROperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000267 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000268static DecodeStatus DecodeThumbAddrModeRR(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000269 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000270static DecodeStatus DecodeThumbAddrModeIS(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000271 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000272static DecodeStatus DecodeThumbAddrModePC(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000273 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000274static DecodeStatus DecodeThumbAddrModeSP(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000275 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000276static DecodeStatus DecodeT2AddrModeSOReg(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000277 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000278static DecodeStatus DecodeT2LoadShift(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000279 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000280static DecodeStatus DecodeT2Imm8S4(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000281 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000282static DecodeStatus DecodeT2AddrModeImm8s4(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000283 uint64_t Address, const void *Decoder);
Jim Grosbachb6aed502011-09-09 18:37:27 +0000284static DecodeStatus DecodeT2AddrModeImm0_1020s4(llvm::MCInst &Inst,unsigned Val,
285 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000286static DecodeStatus DecodeT2Imm8(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000287 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000288static DecodeStatus DecodeT2AddrModeImm8(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000289 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000290static DecodeStatus DecodeThumbAddSPImm(llvm::MCInst &Inst, uint16_t Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000291 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000292static DecodeStatus DecodeThumbAddSPReg(llvm::MCInst &Inst, uint16_t Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000293 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000294static DecodeStatus DecodeThumbCPS(llvm::MCInst &Inst, uint16_t Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000295 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000296static DecodeStatus DecodeThumbBLXOffset(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000297 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000298static DecodeStatus DecodeT2AddrModeImm12(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000299 uint64_t Address, const void *Decoder);
Jim Grosbach7f739be2011-09-19 22:21:13 +0000300static DecodeStatus DecodeThumbTableBranch(llvm::MCInst &Inst, unsigned Val,
301 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000302static DecodeStatus DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000303 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000304static DecodeStatus DecodeT2SOImm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000305 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000306static DecodeStatus DecodeThumbBCCTargetOperand(llvm::MCInst &Inst,unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000307 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000308static DecodeStatus DecodeThumbBLTargetOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000309 uint64_t Address, const void *Decoder);
Owen Andersona6804442011-09-01 23:23:50 +0000310static DecodeStatus DecodeIT(llvm::MCInst &Inst, unsigned Val,
Owen Andersonf4408202011-08-24 22:40:22 +0000311 uint64_t Address, const void *Decoder);
Jim Grosbacha77295d2011-09-08 22:07:06 +0000312static DecodeStatus DecodeT2LDRDPreInstruction(llvm::MCInst &Inst,unsigned Insn,
313 uint64_t Address, const void *Decoder);
314static DecodeStatus DecodeT2STRDPreInstruction(llvm::MCInst &Inst,unsigned Insn,
315 uint64_t Address, const void *Decoder);
Owen Anderson08fef882011-09-09 22:24:36 +0000316static DecodeStatus DecodeT2Adr(llvm::MCInst &Inst, unsigned Val,
317 uint64_t Address, const void *Decoder);
Owen Andersona3157b42011-09-12 18:56:30 +0000318static DecodeStatus DecodeT2LdStPre(llvm::MCInst &Inst, unsigned Val,
319 uint64_t Address, const void *Decoder);
Owen Anderson0afa0092011-09-26 21:06:22 +0000320static DecodeStatus DecodeT2ShifterImmOperand(llvm::MCInst &Inst, unsigned Val,
321 uint64_t Address, const void *Decoder);
322
Owen Andersona3157b42011-09-12 18:56:30 +0000323
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000324
325#include "ARMGenDisassemblerTables.inc"
326#include "ARMGenInstrInfo.inc"
Oscar Fuentes38e13902010-09-28 11:48:19 +0000327#include "ARMGenEDInfo.inc"
Sean Callanan9899f702010-04-13 21:21:57 +0000328
James Molloyb9505852011-09-07 17:24:38 +0000329static MCDisassembler *createARMDisassembler(const Target &T, const MCSubtargetInfo &STI) {
330 return new ARMDisassembler(STI);
Johnny Chenb68a3ee2010-04-02 22:27:38 +0000331}
332
James Molloyb9505852011-09-07 17:24:38 +0000333static MCDisassembler *createThumbDisassembler(const Target &T, const MCSubtargetInfo &STI) {
334 return new ThumbDisassembler(STI);
Johnny Chenb68a3ee2010-04-02 22:27:38 +0000335}
336
Benjamin Kramer88b6fc02012-02-11 14:51:07 +0000337const EDInstInfo *ARMDisassembler::getEDInfo() const {
Sean Callanan9899f702010-04-13 21:21:57 +0000338 return instInfoARM;
339}
340
Benjamin Kramer88b6fc02012-02-11 14:51:07 +0000341const EDInstInfo *ThumbDisassembler::getEDInfo() const {
Sean Callanan9899f702010-04-13 21:21:57 +0000342 return instInfoARM;
343}
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000344
Owen Andersona6804442011-09-01 23:23:50 +0000345DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
Derek Schuffadef06a2012-02-29 01:09:06 +0000346 const MemoryObject &Region,
Jim Grosbachc4057822011-08-17 21:58:18 +0000347 uint64_t Address,
Owen Anderson98c5dda2011-09-15 23:38:46 +0000348 raw_ostream &os,
349 raw_ostream &cs) const {
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000350 CommentStream = &cs;
351
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000352 uint8_t bytes[4];
353
James Molloya5d58562011-09-07 19:42:28 +0000354 assert(!(STI.getFeatureBits() & ARM::ModeThumb) &&
355 "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!");
356
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000357 // We want to read exactly 4 bytes of data.
Benjamin Kramer86ce8522011-08-26 18:21:36 +0000358 if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
359 Size = 0;
James Molloyc047dca2011-09-01 18:02:14 +0000360 return MCDisassembler::Fail;
Benjamin Kramer86ce8522011-08-26 18:21:36 +0000361 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000362
363 // Encoded as a small-endian 32-bit word in the stream.
364 uint32_t insn = (bytes[3] << 24) |
365 (bytes[2] << 16) |
366 (bytes[1] << 8) |
367 (bytes[0] << 0);
368
369 // Calling the auto-generated decoder function.
James Molloya5d58562011-09-07 19:42:28 +0000370 DecodeStatus result = decodeARMInstruction32(MI, insn, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000371 if (result != MCDisassembler::Fail) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000372 Size = 4;
Owen Anderson83e3f672011-08-17 17:44:15 +0000373 return result;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000374 }
375
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000376 // VFP and NEON instructions, similarly, are shared between ARM
377 // and Thumb modes.
378 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000379 result = decodeVFPInstruction32(MI, insn, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000380 if (result != MCDisassembler::Fail) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000381 Size = 4;
Owen Anderson83e3f672011-08-17 17:44:15 +0000382 return result;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000383 }
384
385 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000386 result = decodeNEONDataInstruction32(MI, insn, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000387 if (result != MCDisassembler::Fail) {
Owen Anderson8533eba2011-08-10 19:01:10 +0000388 Size = 4;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000389 // Add a fake predicate operand, because we share these instruction
390 // definitions with Thumb2 where these instructions are predicable.
Owen Andersona6804442011-09-01 23:23:50 +0000391 if (!DecodePredicateOperand(MI, 0xE, Address, this))
392 return MCDisassembler::Fail;
Owen Anderson83e3f672011-08-17 17:44:15 +0000393 return result;
Owen Anderson8533eba2011-08-10 19:01:10 +0000394 }
395
396 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000397 result = decodeNEONLoadStoreInstruction32(MI, insn, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000398 if (result != MCDisassembler::Fail) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000399 Size = 4;
Owen Anderson8533eba2011-08-10 19:01:10 +0000400 // Add a fake predicate operand, because we share these instruction
401 // definitions with Thumb2 where these instructions are predicable.
Owen Andersona6804442011-09-01 23:23:50 +0000402 if (!DecodePredicateOperand(MI, 0xE, Address, this))
403 return MCDisassembler::Fail;
Owen Anderson83e3f672011-08-17 17:44:15 +0000404 return result;
Owen Anderson8533eba2011-08-10 19:01:10 +0000405 }
406
407 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000408 result = decodeNEONDupInstruction32(MI, insn, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000409 if (result != MCDisassembler::Fail) {
Owen Anderson8533eba2011-08-10 19:01:10 +0000410 Size = 4;
411 // Add a fake predicate operand, because we share these instruction
412 // definitions with Thumb2 where these instructions are predicable.
Owen Andersona6804442011-09-01 23:23:50 +0000413 if (!DecodePredicateOperand(MI, 0xE, Address, this))
414 return MCDisassembler::Fail;
Owen Anderson83e3f672011-08-17 17:44:15 +0000415 return result;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000416 }
417
418 MI.clear();
419
Benjamin Kramer86ce8522011-08-26 18:21:36 +0000420 Size = 0;
James Molloyc047dca2011-09-01 18:02:14 +0000421 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000422}
423
424namespace llvm {
Benjamin Kramer1a2f9882011-10-22 16:50:00 +0000425extern const MCInstrDesc ARMInsts[];
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000426}
427
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000428/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
429/// immediate Value in the MCInst. The immediate Value has had any PC
430/// adjustment made by the caller. If the instruction is a branch instruction
431/// then isBranch is true, else false. If the getOpInfo() function was set as
432/// part of the setupForSymbolicDisassembly() call then that function is called
433/// to get any symbolic information at the Address for this instruction. If
434/// that returns non-zero then the symbolic information it returns is used to
435/// create an MCExpr and that is added as an operand to the MCInst. If
436/// getOpInfo() returns zero and isBranch is true then a symbol look up for
437/// Value is done and if a symbol is found an MCExpr is created with that, else
438/// an MCExpr with Value is created. This function returns true if it adds an
439/// operand to the MCInst and false otherwise.
440static bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
441 bool isBranch, uint64_t InstSize,
442 MCInst &MI, const void *Decoder) {
443 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
444 LLVMOpInfoCallback getOpInfo = Dis->getLLVMOpInfoCallback();
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000445 struct LLVMOpInfo1 SymbolicOp;
Kevin Enderbyb80d5712012-02-23 18:18:17 +0000446 memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1));
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000447 SymbolicOp.Value = Value;
448 void *DisInfo = Dis->getDisInfoBlock();
Kevin Enderbyb80d5712012-02-23 18:18:17 +0000449
450 if (!getOpInfo ||
451 !getOpInfo(DisInfo, Address, 0 /* Offset */, InstSize, 1, &SymbolicOp)) {
452 // Clear SymbolicOp.Value from above and also all other fields.
453 memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1));
454 LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback();
455 if (!SymbolLookUp)
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000456 return false;
Kevin Enderbyb80d5712012-02-23 18:18:17 +0000457 uint64_t ReferenceType;
458 if (isBranch)
459 ReferenceType = LLVMDisassembler_ReferenceType_In_Branch;
460 else
461 ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
462 const char *ReferenceName;
463 const char *Name = SymbolLookUp(DisInfo, Value, &ReferenceType, Address,
464 &ReferenceName);
465 if (Name) {
466 SymbolicOp.AddSymbol.Name = Name;
467 SymbolicOp.AddSymbol.Present = true;
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000468 }
Kevin Enderbyb80d5712012-02-23 18:18:17 +0000469 // For branches always create an MCExpr so it gets printed as hex address.
470 else if (isBranch) {
471 SymbolicOp.Value = Value;
472 }
473 if(ReferenceType == LLVMDisassembler_ReferenceType_Out_SymbolStub)
474 (*Dis->CommentStream) << "symbol stub for: " << ReferenceName;
475 if (!Name && !isBranch)
476 return false;
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000477 }
478
479 MCContext *Ctx = Dis->getMCContext();
480 const MCExpr *Add = NULL;
481 if (SymbolicOp.AddSymbol.Present) {
482 if (SymbolicOp.AddSymbol.Name) {
483 StringRef Name(SymbolicOp.AddSymbol.Name);
484 MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name);
485 Add = MCSymbolRefExpr::Create(Sym, *Ctx);
486 } else {
487 Add = MCConstantExpr::Create(SymbolicOp.AddSymbol.Value, *Ctx);
488 }
489 }
490
491 const MCExpr *Sub = NULL;
492 if (SymbolicOp.SubtractSymbol.Present) {
493 if (SymbolicOp.SubtractSymbol.Name) {
494 StringRef Name(SymbolicOp.SubtractSymbol.Name);
495 MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name);
496 Sub = MCSymbolRefExpr::Create(Sym, *Ctx);
497 } else {
498 Sub = MCConstantExpr::Create(SymbolicOp.SubtractSymbol.Value, *Ctx);
499 }
500 }
501
502 const MCExpr *Off = NULL;
503 if (SymbolicOp.Value != 0)
504 Off = MCConstantExpr::Create(SymbolicOp.Value, *Ctx);
505
506 const MCExpr *Expr;
507 if (Sub) {
508 const MCExpr *LHS;
509 if (Add)
510 LHS = MCBinaryExpr::CreateSub(Add, Sub, *Ctx);
511 else
512 LHS = MCUnaryExpr::CreateMinus(Sub, *Ctx);
513 if (Off != 0)
514 Expr = MCBinaryExpr::CreateAdd(LHS, Off, *Ctx);
515 else
516 Expr = LHS;
517 } else if (Add) {
518 if (Off != 0)
519 Expr = MCBinaryExpr::CreateAdd(Add, Off, *Ctx);
520 else
521 Expr = Add;
522 } else {
523 if (Off != 0)
524 Expr = Off;
525 else
526 Expr = MCConstantExpr::Create(0, *Ctx);
527 }
528
529 if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_HI16)
530 MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateUpper16(Expr, *Ctx)));
531 else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_LO16)
532 MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateLower16(Expr, *Ctx)));
533 else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_None)
534 MI.addOperand(MCOperand::CreateExpr(Expr));
Jim Grosbach01817c32011-10-20 17:28:20 +0000535 else
Craig Topperbc219812012-02-07 02:50:20 +0000536 llvm_unreachable("bad SymbolicOp.VariantKind");
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000537
538 return true;
539}
540
541/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
542/// referenced by a load instruction with the base register that is the Pc.
543/// These can often be values in a literal pool near the Address of the
544/// instruction. The Address of the instruction and its immediate Value are
545/// used as a possible literal pool entry. The SymbolLookUp call back will
546/// return the name of a symbol referenced by the the literal pool's entry if
547/// the referenced address is that of a symbol. Or it will return a pointer to
548/// a literal 'C' string if the referenced address of the literal pool's entry
549/// is an address into a section with 'C' string literals.
550static void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
Kevin Enderbyb80d5712012-02-23 18:18:17 +0000551 const void *Decoder) {
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000552 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
553 LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback();
554 if (SymbolLookUp) {
555 void *DisInfo = Dis->getDisInfoBlock();
556 uint64_t ReferenceType;
557 ReferenceType = LLVMDisassembler_ReferenceType_In_PCrel_Load;
558 const char *ReferenceName;
559 (void)SymbolLookUp(DisInfo, Value, &ReferenceType, Address, &ReferenceName);
560 if(ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr ||
561 ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr)
562 (*Dis->CommentStream) << "literal pool for: " << ReferenceName;
563 }
564}
565
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000566// Thumb1 instructions don't have explicit S bits. Rather, they
567// implicitly set CPSR. Since it's not represented in the encoding, the
568// auto-generated decoder won't inject the CPSR operand. We need to fix
569// that as a post-pass.
570static void AddThumb1SBit(MCInst &MI, bool InITBlock) {
571 const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
Owen Anderson0aa38ab2011-08-17 18:14:48 +0000572 unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000573 MCInst::iterator I = MI.begin();
Owen Anderson0aa38ab2011-08-17 18:14:48 +0000574 for (unsigned i = 0; i < NumOps; ++i, ++I) {
575 if (I == MI.end()) break;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000576 if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
Owen Anderson0aa38ab2011-08-17 18:14:48 +0000577 if (i > 0 && OpInfo[i-1].isPredicate()) continue;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000578 MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
579 return;
580 }
581 }
582
Owen Anderson0aa38ab2011-08-17 18:14:48 +0000583 MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000584}
585
586// Most Thumb instructions don't have explicit predicates in the
587// encoding, but rather get their predicates from IT context. We need
588// to fix up the predicate operands using this context information as a
589// post-pass.
Owen Andersond2fc31b2011-09-08 22:42:49 +0000590MCDisassembler::DecodeStatus
591ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
Owen Anderson51f6a7a2011-09-09 21:48:23 +0000592 MCDisassembler::DecodeStatus S = Success;
593
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000594 // A few instructions actually have predicates encoded in them. Don't
595 // try to overwrite it if we're seeing one of those.
596 switch (MI.getOpcode()) {
597 case ARM::tBcc:
598 case ARM::t2Bcc:
Owen Andersond2fc31b2011-09-08 22:42:49 +0000599 case ARM::tCBZ:
600 case ARM::tCBNZ:
Owen Anderson9f666b52011-09-19 23:47:10 +0000601 case ARM::tCPS:
602 case ARM::t2CPS3p:
603 case ARM::t2CPS2p:
604 case ARM::t2CPS1p:
Owen Andersond9346fb2011-09-19 23:57:20 +0000605 case ARM::tMOVSr:
Owen Andersonc18e9402011-10-13 17:58:39 +0000606 case ARM::tSETEND:
Owen Anderson441462f2011-09-08 22:48:37 +0000607 // Some instructions (mostly conditional branches) are not
608 // allowed in IT blocks.
Owen Andersond2fc31b2011-09-08 22:42:49 +0000609 if (!ITBlock.empty())
Owen Anderson51f6a7a2011-09-09 21:48:23 +0000610 S = SoftFail;
611 else
612 return Success;
613 break;
614 case ARM::tB:
615 case ARM::t2B:
Owen Anderson04c78772011-09-19 22:34:23 +0000616 case ARM::t2TBB:
617 case ARM::t2TBH:
Owen Anderson51f6a7a2011-09-09 21:48:23 +0000618 // Some instructions (mostly unconditional branches) can
619 // only appears at the end of, or outside of, an IT.
620 if (ITBlock.size() > 1)
621 S = SoftFail;
Owen Andersond2fc31b2011-09-08 22:42:49 +0000622 break;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000623 default:
624 break;
625 }
626
627 // If we're in an IT block, base the predicate on that. Otherwise,
628 // assume a predicate of AL.
629 unsigned CC;
Owen Anderson10cbaab2011-08-10 17:36:48 +0000630 if (!ITBlock.empty()) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000631 CC = ITBlock.back();
Owen Anderson9bd655d2011-08-26 06:19:51 +0000632 if (CC == 0xF)
633 CC = ARMCC::AL;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000634 ITBlock.pop_back();
635 } else
636 CC = ARMCC::AL;
637
638 const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
Owen Anderson0aa38ab2011-08-17 18:14:48 +0000639 unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000640 MCInst::iterator I = MI.begin();
Owen Anderson0aa38ab2011-08-17 18:14:48 +0000641 for (unsigned i = 0; i < NumOps; ++i, ++I) {
642 if (I == MI.end()) break;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000643 if (OpInfo[i].isPredicate()) {
644 I = MI.insert(I, MCOperand::CreateImm(CC));
645 ++I;
646 if (CC == ARMCC::AL)
647 MI.insert(I, MCOperand::CreateReg(0));
648 else
649 MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
Owen Anderson51f6a7a2011-09-09 21:48:23 +0000650 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000651 }
652 }
653
Owen Anderson0aa38ab2011-08-17 18:14:48 +0000654 I = MI.insert(I, MCOperand::CreateImm(CC));
655 ++I;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000656 if (CC == ARMCC::AL)
Owen Anderson0aa38ab2011-08-17 18:14:48 +0000657 MI.insert(I, MCOperand::CreateReg(0));
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000658 else
Owen Anderson0aa38ab2011-08-17 18:14:48 +0000659 MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
Owen Andersond2fc31b2011-09-08 22:42:49 +0000660
Owen Anderson51f6a7a2011-09-09 21:48:23 +0000661 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000662}
663
664// Thumb VFP instructions are a special case. Because we share their
665// encodings between ARM and Thumb modes, and they are predicable in ARM
666// mode, the auto-generated decoder will give them an (incorrect)
667// predicate operand. We need to rewrite these operands based on the IT
668// context as a post-pass.
669void ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const {
670 unsigned CC;
Owen Anderson10cbaab2011-08-10 17:36:48 +0000671 if (!ITBlock.empty()) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000672 CC = ITBlock.back();
673 ITBlock.pop_back();
674 } else
675 CC = ARMCC::AL;
676
677 const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
678 MCInst::iterator I = MI.begin();
Owen Anderson12a1e3b2011-08-24 21:35:46 +0000679 unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
680 for (unsigned i = 0; i < NumOps; ++i, ++I) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000681 if (OpInfo[i].isPredicate() ) {
682 I->setImm(CC);
683 ++I;
684 if (CC == ARMCC::AL)
685 I->setReg(0);
686 else
687 I->setReg(ARM::CPSR);
688 return;
689 }
690 }
691}
692
Owen Andersona6804442011-09-01 23:23:50 +0000693DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
Derek Schuffadef06a2012-02-29 01:09:06 +0000694 const MemoryObject &Region,
Jim Grosbachc4057822011-08-17 21:58:18 +0000695 uint64_t Address,
Owen Anderson98c5dda2011-09-15 23:38:46 +0000696 raw_ostream &os,
697 raw_ostream &cs) const {
Kevin Enderby9e5887b2011-10-04 22:44:48 +0000698 CommentStream = &cs;
699
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000700 uint8_t bytes[4];
701
James Molloya5d58562011-09-07 19:42:28 +0000702 assert((STI.getFeatureBits() & ARM::ModeThumb) &&
703 "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
704
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000705 // We want to read exactly 2 bytes of data.
Benjamin Kramer86ce8522011-08-26 18:21:36 +0000706 if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1) {
707 Size = 0;
James Molloyc047dca2011-09-01 18:02:14 +0000708 return MCDisassembler::Fail;
Benjamin Kramer86ce8522011-08-26 18:21:36 +0000709 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000710
711 uint16_t insn16 = (bytes[1] << 8) | bytes[0];
James Molloya5d58562011-09-07 19:42:28 +0000712 DecodeStatus result = decodeThumbInstruction16(MI, insn16, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000713 if (result != MCDisassembler::Fail) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000714 Size = 2;
Owen Andersond2fc31b2011-09-08 22:42:49 +0000715 Check(result, AddThumbPredicate(MI));
Owen Anderson83e3f672011-08-17 17:44:15 +0000716 return result;
Owen Anderson16280302011-08-16 23:45:44 +0000717 }
718
719 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000720 result = decodeThumbSBitInstruction16(MI, insn16, Address, this, STI);
Owen Anderson16280302011-08-16 23:45:44 +0000721 if (result) {
722 Size = 2;
Owen Anderson10cbaab2011-08-10 17:36:48 +0000723 bool InITBlock = !ITBlock.empty();
Owen Andersond2fc31b2011-09-08 22:42:49 +0000724 Check(result, AddThumbPredicate(MI));
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000725 AddThumb1SBit(MI, InITBlock);
Owen Anderson83e3f672011-08-17 17:44:15 +0000726 return result;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000727 }
728
729 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000730 result = decodeThumb2Instruction16(MI, insn16, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000731 if (result != MCDisassembler::Fail) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000732 Size = 2;
Owen Anderson7011eee2011-10-06 23:33:11 +0000733
734 // Nested IT blocks are UNPREDICTABLE. Must be checked before we add
735 // the Thumb predicate.
736 if (MI.getOpcode() == ARM::t2IT && !ITBlock.empty())
737 result = MCDisassembler::SoftFail;
738
Owen Andersond2fc31b2011-09-08 22:42:49 +0000739 Check(result, AddThumbPredicate(MI));
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000740
741 // If we find an IT instruction, we need to parse its condition
742 // code and mask operands so that we can apply them correctly
743 // to the subsequent instructions.
744 if (MI.getOpcode() == ARM::t2IT) {
Owen Anderson34626ac2011-09-14 21:06:21 +0000745
Owen Andersoneaca9282011-08-30 22:58:27 +0000746 // (3 - the number of trailing zeros) is the number of then / else.
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000747 unsigned firstcond = MI.getOperand(0).getImm();
Owen Andersoneaca9282011-08-30 22:58:27 +0000748 unsigned Mask = MI.getOperand(1).getImm();
749 unsigned CondBit0 = Mask >> 4 & 1;
750 unsigned NumTZ = CountTrailingZeros_32(Mask);
751 assert(NumTZ <= 3 && "Invalid IT mask!");
752 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
753 bool T = ((Mask >> Pos) & 1) == CondBit0;
754 if (T)
755 ITBlock.insert(ITBlock.begin(), firstcond);
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000756 else
Owen Andersoneaca9282011-08-30 22:58:27 +0000757 ITBlock.insert(ITBlock.begin(), firstcond ^ 1);
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000758 }
Owen Andersoneaca9282011-08-30 22:58:27 +0000759
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000760 ITBlock.push_back(firstcond);
761 }
762
Owen Anderson83e3f672011-08-17 17:44:15 +0000763 return result;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000764 }
765
766 // We want to read exactly 4 bytes of data.
Benjamin Kramer86ce8522011-08-26 18:21:36 +0000767 if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) {
768 Size = 0;
James Molloyc047dca2011-09-01 18:02:14 +0000769 return MCDisassembler::Fail;
Benjamin Kramer86ce8522011-08-26 18:21:36 +0000770 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000771
772 uint32_t insn32 = (bytes[3] << 8) |
773 (bytes[2] << 0) |
774 (bytes[1] << 24) |
775 (bytes[0] << 16);
776 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000777 result = decodeThumbInstruction32(MI, insn32, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000778 if (result != MCDisassembler::Fail) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000779 Size = 4;
780 bool InITBlock = ITBlock.size();
Owen Andersond2fc31b2011-09-08 22:42:49 +0000781 Check(result, AddThumbPredicate(MI));
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000782 AddThumb1SBit(MI, InITBlock);
Owen Anderson83e3f672011-08-17 17:44:15 +0000783 return result;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000784 }
785
786 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000787 result = decodeThumb2Instruction32(MI, insn32, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000788 if (result != MCDisassembler::Fail) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000789 Size = 4;
Owen Andersond2fc31b2011-09-08 22:42:49 +0000790 Check(result, AddThumbPredicate(MI));
Owen Anderson83e3f672011-08-17 17:44:15 +0000791 return result;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000792 }
793
794 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000795 result = decodeVFPInstruction32(MI, insn32, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000796 if (result != MCDisassembler::Fail) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000797 Size = 4;
798 UpdateThumbVFPPredicate(MI);
Owen Anderson83e3f672011-08-17 17:44:15 +0000799 return result;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000800 }
801
802 MI.clear();
James Molloya5d58562011-09-07 19:42:28 +0000803 result = decodeNEONDupInstruction32(MI, insn32, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000804 if (result != MCDisassembler::Fail) {
Owen Andersonef2865a2011-08-15 23:38:54 +0000805 Size = 4;
Owen Andersond2fc31b2011-09-08 22:42:49 +0000806 Check(result, AddThumbPredicate(MI));
Owen Anderson83e3f672011-08-17 17:44:15 +0000807 return result;
Owen Andersonef2865a2011-08-15 23:38:54 +0000808 }
809
810 if (fieldFromInstruction32(insn32, 24, 8) == 0xF9) {
811 MI.clear();
812 uint32_t NEONLdStInsn = insn32;
813 NEONLdStInsn &= 0xF0FFFFFF;
814 NEONLdStInsn |= 0x04000000;
James Molloya5d58562011-09-07 19:42:28 +0000815 result = decodeNEONLoadStoreInstruction32(MI, NEONLdStInsn, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000816 if (result != MCDisassembler::Fail) {
Owen Andersonef2865a2011-08-15 23:38:54 +0000817 Size = 4;
Owen Andersond2fc31b2011-09-08 22:42:49 +0000818 Check(result, AddThumbPredicate(MI));
Owen Anderson83e3f672011-08-17 17:44:15 +0000819 return result;
Owen Andersonef2865a2011-08-15 23:38:54 +0000820 }
821 }
822
Owen Anderson8533eba2011-08-10 19:01:10 +0000823 if (fieldFromInstruction32(insn32, 24, 4) == 0xF) {
Owen Andersonef2865a2011-08-15 23:38:54 +0000824 MI.clear();
Owen Anderson8533eba2011-08-10 19:01:10 +0000825 uint32_t NEONDataInsn = insn32;
826 NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
827 NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
828 NEONDataInsn |= 0x12000000; // Set bits 28 and 25
James Molloya5d58562011-09-07 19:42:28 +0000829 result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this, STI);
James Molloyc047dca2011-09-01 18:02:14 +0000830 if (result != MCDisassembler::Fail) {
Owen Anderson8533eba2011-08-10 19:01:10 +0000831 Size = 4;
Owen Andersond2fc31b2011-09-08 22:42:49 +0000832 Check(result, AddThumbPredicate(MI));
Owen Anderson83e3f672011-08-17 17:44:15 +0000833 return result;
Owen Anderson8533eba2011-08-10 19:01:10 +0000834 }
835 }
836
Benjamin Kramer86ce8522011-08-26 18:21:36 +0000837 Size = 0;
James Molloyc047dca2011-09-01 18:02:14 +0000838 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000839}
840
841
842extern "C" void LLVMInitializeARMDisassembler() {
843 TargetRegistry::RegisterMCDisassembler(TheARMTarget,
844 createARMDisassembler);
845 TargetRegistry::RegisterMCDisassembler(TheThumbTarget,
846 createThumbDisassembler);
847}
848
849static const unsigned GPRDecoderTable[] = {
850 ARM::R0, ARM::R1, ARM::R2, ARM::R3,
851 ARM::R4, ARM::R5, ARM::R6, ARM::R7,
852 ARM::R8, ARM::R9, ARM::R10, ARM::R11,
853 ARM::R12, ARM::SP, ARM::LR, ARM::PC
854};
855
Owen Andersona6804442011-09-01 23:23:50 +0000856static DecodeStatus DecodeGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000857 uint64_t Address, const void *Decoder) {
858 if (RegNo > 15)
James Molloyc047dca2011-09-01 18:02:14 +0000859 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000860
861 unsigned Register = GPRDecoderTable[RegNo];
862 Inst.addOperand(MCOperand::CreateReg(Register));
James Molloyc047dca2011-09-01 18:02:14 +0000863 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000864}
865
Owen Andersona6804442011-09-01 23:23:50 +0000866static DecodeStatus
Jim Grosbachc4057822011-08-17 21:58:18 +0000867DecodeGPRnopcRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
868 uint64_t Address, const void *Decoder) {
James Molloyc047dca2011-09-01 18:02:14 +0000869 if (RegNo == 15) return MCDisassembler::Fail;
Owen Anderson51c98052011-08-09 22:48:45 +0000870 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
871}
872
Owen Andersona6804442011-09-01 23:23:50 +0000873static DecodeStatus DecodetGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000874 uint64_t Address, const void *Decoder) {
875 if (RegNo > 7)
James Molloyc047dca2011-09-01 18:02:14 +0000876 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000877 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
878}
879
Owen Andersona6804442011-09-01 23:23:50 +0000880static DecodeStatus DecodetcGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000881 uint64_t Address, const void *Decoder) {
882 unsigned Register = 0;
883 switch (RegNo) {
884 case 0:
885 Register = ARM::R0;
886 break;
887 case 1:
888 Register = ARM::R1;
889 break;
890 case 2:
891 Register = ARM::R2;
892 break;
893 case 3:
894 Register = ARM::R3;
895 break;
896 case 9:
897 Register = ARM::R9;
898 break;
899 case 12:
900 Register = ARM::R12;
901 break;
902 default:
James Molloyc047dca2011-09-01 18:02:14 +0000903 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000904 }
905
906 Inst.addOperand(MCOperand::CreateReg(Register));
James Molloyc047dca2011-09-01 18:02:14 +0000907 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000908}
909
Owen Andersona6804442011-09-01 23:23:50 +0000910static DecodeStatus DecoderGPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000911 uint64_t Address, const void *Decoder) {
James Molloyc047dca2011-09-01 18:02:14 +0000912 if (RegNo == 13 || RegNo == 15) return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000913 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
914}
915
Jim Grosbachc4057822011-08-17 21:58:18 +0000916static const unsigned SPRDecoderTable[] = {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000917 ARM::S0, ARM::S1, ARM::S2, ARM::S3,
918 ARM::S4, ARM::S5, ARM::S6, ARM::S7,
919 ARM::S8, ARM::S9, ARM::S10, ARM::S11,
920 ARM::S12, ARM::S13, ARM::S14, ARM::S15,
921 ARM::S16, ARM::S17, ARM::S18, ARM::S19,
922 ARM::S20, ARM::S21, ARM::S22, ARM::S23,
923 ARM::S24, ARM::S25, ARM::S26, ARM::S27,
924 ARM::S28, ARM::S29, ARM::S30, ARM::S31
925};
926
Owen Andersona6804442011-09-01 23:23:50 +0000927static DecodeStatus DecodeSPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000928 uint64_t Address, const void *Decoder) {
929 if (RegNo > 31)
James Molloyc047dca2011-09-01 18:02:14 +0000930 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000931
932 unsigned Register = SPRDecoderTable[RegNo];
933 Inst.addOperand(MCOperand::CreateReg(Register));
James Molloyc047dca2011-09-01 18:02:14 +0000934 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000935}
936
Jim Grosbachc4057822011-08-17 21:58:18 +0000937static const unsigned DPRDecoderTable[] = {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000938 ARM::D0, ARM::D1, ARM::D2, ARM::D3,
939 ARM::D4, ARM::D5, ARM::D6, ARM::D7,
940 ARM::D8, ARM::D9, ARM::D10, ARM::D11,
941 ARM::D12, ARM::D13, ARM::D14, ARM::D15,
942 ARM::D16, ARM::D17, ARM::D18, ARM::D19,
943 ARM::D20, ARM::D21, ARM::D22, ARM::D23,
944 ARM::D24, ARM::D25, ARM::D26, ARM::D27,
945 ARM::D28, ARM::D29, ARM::D30, ARM::D31
946};
947
Owen Andersona6804442011-09-01 23:23:50 +0000948static DecodeStatus DecodeDPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000949 uint64_t Address, const void *Decoder) {
950 if (RegNo > 31)
James Molloyc047dca2011-09-01 18:02:14 +0000951 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000952
953 unsigned Register = DPRDecoderTable[RegNo];
954 Inst.addOperand(MCOperand::CreateReg(Register));
James Molloyc047dca2011-09-01 18:02:14 +0000955 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000956}
957
Owen Andersona6804442011-09-01 23:23:50 +0000958static DecodeStatus DecodeDPR_8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000959 uint64_t Address, const void *Decoder) {
960 if (RegNo > 7)
James Molloyc047dca2011-09-01 18:02:14 +0000961 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000962 return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
963}
964
Owen Andersona6804442011-09-01 23:23:50 +0000965static DecodeStatus
Jim Grosbachc4057822011-08-17 21:58:18 +0000966DecodeDPR_VFP2RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
967 uint64_t Address, const void *Decoder) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000968 if (RegNo > 15)
James Molloyc047dca2011-09-01 18:02:14 +0000969 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000970 return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
971}
972
Jim Grosbachc4057822011-08-17 21:58:18 +0000973static const unsigned QPRDecoderTable[] = {
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000974 ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3,
975 ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7,
976 ARM::Q8, ARM::Q9, ARM::Q10, ARM::Q11,
977 ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
978};
979
980
Owen Andersona6804442011-09-01 23:23:50 +0000981static DecodeStatus DecodeQPRRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000982 uint64_t Address, const void *Decoder) {
983 if (RegNo > 31)
James Molloyc047dca2011-09-01 18:02:14 +0000984 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000985 RegNo >>= 1;
986
987 unsigned Register = QPRDecoderTable[RegNo];
988 Inst.addOperand(MCOperand::CreateReg(Register));
James Molloyc047dca2011-09-01 18:02:14 +0000989 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +0000990}
991
Jim Grosbach28f08c92012-03-05 19:33:30 +0000992static const unsigned DPairDecoderTable[] = {
993 ARM::Q0, ARM::D1_D2, ARM::Q1, ARM::D3_D4, ARM::Q2, ARM::D5_D6,
994 ARM::Q3, ARM::D7_D8, ARM::Q4, ARM::D9_D10, ARM::Q5, ARM::D11_D12,
995 ARM::Q6, ARM::D13_D14, ARM::Q7, ARM::D15_D16, ARM::Q8, ARM::D17_D18,
996 ARM::Q9, ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
997 ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
998 ARM::Q15
999};
1000
1001static DecodeStatus DecodeDPairRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
1002 uint64_t Address, const void *Decoder) {
1003 if (RegNo > 30)
1004 return MCDisassembler::Fail;
1005
1006 unsigned Register = DPairDecoderTable[RegNo];
1007 Inst.addOperand(MCOperand::CreateReg(Register));
1008 return MCDisassembler::Success;
1009}
1010
Owen Andersona6804442011-09-01 23:23:50 +00001011static DecodeStatus DecodePredicateOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001012 uint64_t Address, const void *Decoder) {
James Molloyc047dca2011-09-01 18:02:14 +00001013 if (Val == 0xF) return MCDisassembler::Fail;
Owen Andersonbd9091c2011-08-09 21:07:45 +00001014 // AL predicate is not allowed on Thumb1 branches.
1015 if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
James Molloyc047dca2011-09-01 18:02:14 +00001016 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001017 Inst.addOperand(MCOperand::CreateImm(Val));
1018 if (Val == ARMCC::AL) {
1019 Inst.addOperand(MCOperand::CreateReg(0));
1020 } else
1021 Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
James Molloyc047dca2011-09-01 18:02:14 +00001022 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001023}
1024
Owen Andersona6804442011-09-01 23:23:50 +00001025static DecodeStatus DecodeCCOutOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001026 uint64_t Address, const void *Decoder) {
1027 if (Val)
1028 Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1029 else
1030 Inst.addOperand(MCOperand::CreateReg(0));
James Molloyc047dca2011-09-01 18:02:14 +00001031 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001032}
1033
Owen Andersona6804442011-09-01 23:23:50 +00001034static DecodeStatus DecodeSOImmOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001035 uint64_t Address, const void *Decoder) {
1036 uint32_t imm = Val & 0xFF;
1037 uint32_t rot = (Val & 0xF00) >> 7;
Eli Friedmanecb830e2011-10-13 23:36:06 +00001038 uint32_t rot_imm = (imm >> rot) | (imm << ((32-rot) & 0x1F));
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001039 Inst.addOperand(MCOperand::CreateImm(rot_imm));
James Molloyc047dca2011-09-01 18:02:14 +00001040 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001041}
1042
Owen Andersona6804442011-09-01 23:23:50 +00001043static DecodeStatus DecodeSORegImmOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001044 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001045 DecodeStatus S = MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001046
1047 unsigned Rm = fieldFromInstruction32(Val, 0, 4);
1048 unsigned type = fieldFromInstruction32(Val, 5, 2);
1049 unsigned imm = fieldFromInstruction32(Val, 7, 5);
1050
1051 // Register-immediate
Owen Andersona6804442011-09-01 23:23:50 +00001052 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1053 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001054
1055 ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1056 switch (type) {
1057 case 0:
1058 Shift = ARM_AM::lsl;
1059 break;
1060 case 1:
1061 Shift = ARM_AM::lsr;
1062 break;
1063 case 2:
1064 Shift = ARM_AM::asr;
1065 break;
1066 case 3:
1067 Shift = ARM_AM::ror;
1068 break;
1069 }
1070
1071 if (Shift == ARM_AM::ror && imm == 0)
1072 Shift = ARM_AM::rrx;
1073
1074 unsigned Op = Shift | (imm << 3);
1075 Inst.addOperand(MCOperand::CreateImm(Op));
1076
Owen Anderson83e3f672011-08-17 17:44:15 +00001077 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001078}
1079
Owen Andersona6804442011-09-01 23:23:50 +00001080static DecodeStatus DecodeSORegRegOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001081 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001082 DecodeStatus S = MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001083
1084 unsigned Rm = fieldFromInstruction32(Val, 0, 4);
1085 unsigned type = fieldFromInstruction32(Val, 5, 2);
1086 unsigned Rs = fieldFromInstruction32(Val, 8, 4);
1087
1088 // Register-register
Owen Andersona6804442011-09-01 23:23:50 +00001089 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1090 return MCDisassembler::Fail;
1091 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
1092 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001093
1094 ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
1095 switch (type) {
1096 case 0:
1097 Shift = ARM_AM::lsl;
1098 break;
1099 case 1:
1100 Shift = ARM_AM::lsr;
1101 break;
1102 case 2:
1103 Shift = ARM_AM::asr;
1104 break;
1105 case 3:
1106 Shift = ARM_AM::ror;
1107 break;
1108 }
1109
1110 Inst.addOperand(MCOperand::CreateImm(Shift));
1111
Owen Anderson83e3f672011-08-17 17:44:15 +00001112 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001113}
1114
Owen Andersona6804442011-09-01 23:23:50 +00001115static DecodeStatus DecodeRegListOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001116 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001117 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001118
Owen Anderson921d01a2011-09-09 23:13:33 +00001119 bool writebackLoad = false;
1120 unsigned writebackReg = 0;
1121 switch (Inst.getOpcode()) {
1122 default:
1123 break;
1124 case ARM::LDMIA_UPD:
1125 case ARM::LDMDB_UPD:
1126 case ARM::LDMIB_UPD:
1127 case ARM::LDMDA_UPD:
1128 case ARM::t2LDMIA_UPD:
1129 case ARM::t2LDMDB_UPD:
1130 writebackLoad = true;
1131 writebackReg = Inst.getOperand(0).getReg();
1132 break;
1133 }
1134
Owen Anderson26d2f0a2011-08-11 20:21:46 +00001135 // Empty register lists are not allowed.
Owen Anderson244006d2011-11-02 17:46:18 +00001136 if (CountPopulation_32(Val) == 0) return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001137 for (unsigned i = 0; i < 16; ++i) {
Owen Andersonae0bc5d2011-08-11 18:24:51 +00001138 if (Val & (1 << i)) {
Owen Andersona6804442011-09-01 23:23:50 +00001139 if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
1140 return MCDisassembler::Fail;
Owen Anderson921d01a2011-09-09 23:13:33 +00001141 // Writeback not allowed if Rn is in the target list.
1142 if (writebackLoad && writebackReg == Inst.end()[-1].getReg())
1143 Check(S, MCDisassembler::SoftFail);
Owen Andersonae0bc5d2011-08-11 18:24:51 +00001144 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001145 }
1146
Owen Anderson83e3f672011-08-17 17:44:15 +00001147 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001148}
1149
Owen Andersona6804442011-09-01 23:23:50 +00001150static DecodeStatus DecodeSPRRegListOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001151 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001152 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001153
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001154 unsigned Vd = fieldFromInstruction32(Val, 8, 4);
1155 unsigned regs = Val & 0xFF;
1156
Owen Andersona6804442011-09-01 23:23:50 +00001157 if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
1158 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00001159 for (unsigned i = 0; i < (regs - 1); ++i) {
Owen Andersona6804442011-09-01 23:23:50 +00001160 if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1161 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00001162 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001163
Owen Anderson83e3f672011-08-17 17:44:15 +00001164 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001165}
1166
Owen Andersona6804442011-09-01 23:23:50 +00001167static DecodeStatus DecodeDPRRegListOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001168 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001169 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001170
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001171 unsigned Vd = fieldFromInstruction32(Val, 8, 4);
1172 unsigned regs = (Val & 0xFF) / 2;
1173
Owen Andersona6804442011-09-01 23:23:50 +00001174 if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
1175 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00001176 for (unsigned i = 0; i < (regs - 1); ++i) {
Owen Andersona6804442011-09-01 23:23:50 +00001177 if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1178 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00001179 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001180
Owen Anderson83e3f672011-08-17 17:44:15 +00001181 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001182}
1183
Owen Andersona6804442011-09-01 23:23:50 +00001184static DecodeStatus DecodeBitfieldMaskOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001185 uint64_t Address, const void *Decoder) {
Owen Anderson10cbaab2011-08-10 17:36:48 +00001186 // This operand encodes a mask of contiguous zeros between a specified MSB
1187 // and LSB. To decode it, we create the mask of all bits MSB-and-lower,
1188 // the mask of all bits LSB-and-lower, and then xor them to create
Jim Grosbachc4057822011-08-17 21:58:18 +00001189 // the mask of that's all ones on [msb, lsb]. Finally we not it to
Owen Anderson10cbaab2011-08-10 17:36:48 +00001190 // create the final mask.
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001191 unsigned msb = fieldFromInstruction32(Val, 5, 5);
1192 unsigned lsb = fieldFromInstruction32(Val, 0, 5);
Owen Anderson89db0f62011-09-16 22:29:48 +00001193
Owen Andersoncb775512011-09-16 23:30:01 +00001194 DecodeStatus S = MCDisassembler::Success;
1195 if (lsb > msb) Check(S, MCDisassembler::SoftFail);
1196
Owen Anderson8b227782011-09-16 23:04:48 +00001197 uint32_t msb_mask = 0xFFFFFFFF;
1198 if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
1199 uint32_t lsb_mask = (1U << lsb) - 1;
Owen Anderson89db0f62011-09-16 22:29:48 +00001200
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001201 Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask)));
Owen Andersoncb775512011-09-16 23:30:01 +00001202 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001203}
1204
Owen Andersona6804442011-09-01 23:23:50 +00001205static DecodeStatus DecodeCopMemInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001206 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001207 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001208
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001209 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1210 unsigned CRd = fieldFromInstruction32(Insn, 12, 4);
1211 unsigned coproc = fieldFromInstruction32(Insn, 8, 4);
1212 unsigned imm = fieldFromInstruction32(Insn, 0, 8);
1213 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1214 unsigned U = fieldFromInstruction32(Insn, 23, 1);
1215
1216 switch (Inst.getOpcode()) {
1217 case ARM::LDC_OFFSET:
1218 case ARM::LDC_PRE:
1219 case ARM::LDC_POST:
1220 case ARM::LDC_OPTION:
1221 case ARM::LDCL_OFFSET:
1222 case ARM::LDCL_PRE:
1223 case ARM::LDCL_POST:
1224 case ARM::LDCL_OPTION:
1225 case ARM::STC_OFFSET:
1226 case ARM::STC_PRE:
1227 case ARM::STC_POST:
1228 case ARM::STC_OPTION:
1229 case ARM::STCL_OFFSET:
1230 case ARM::STCL_PRE:
1231 case ARM::STCL_POST:
1232 case ARM::STCL_OPTION:
Owen Anderson8a83f712011-09-07 21:10:42 +00001233 case ARM::t2LDC_OFFSET:
1234 case ARM::t2LDC_PRE:
1235 case ARM::t2LDC_POST:
1236 case ARM::t2LDC_OPTION:
1237 case ARM::t2LDCL_OFFSET:
1238 case ARM::t2LDCL_PRE:
1239 case ARM::t2LDCL_POST:
1240 case ARM::t2LDCL_OPTION:
1241 case ARM::t2STC_OFFSET:
1242 case ARM::t2STC_PRE:
1243 case ARM::t2STC_POST:
1244 case ARM::t2STC_OPTION:
1245 case ARM::t2STCL_OFFSET:
1246 case ARM::t2STCL_PRE:
1247 case ARM::t2STCL_POST:
1248 case ARM::t2STCL_OPTION:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001249 if (coproc == 0xA || coproc == 0xB)
James Molloyc047dca2011-09-01 18:02:14 +00001250 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001251 break;
1252 default:
1253 break;
1254 }
1255
1256 Inst.addOperand(MCOperand::CreateImm(coproc));
1257 Inst.addOperand(MCOperand::CreateImm(CRd));
Owen Andersona6804442011-09-01 23:23:50 +00001258 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1259 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001260
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001261 switch (Inst.getOpcode()) {
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001262 case ARM::t2LDC2_OFFSET:
1263 case ARM::t2LDC2L_OFFSET:
1264 case ARM::t2LDC2_PRE:
1265 case ARM::t2LDC2L_PRE:
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001266 case ARM::t2STC2_OFFSET:
1267 case ARM::t2STC2L_OFFSET:
1268 case ARM::t2STC2_PRE:
1269 case ARM::t2STC2L_PRE:
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001270 case ARM::LDC2_OFFSET:
1271 case ARM::LDC2L_OFFSET:
1272 case ARM::LDC2_PRE:
1273 case ARM::LDC2L_PRE:
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001274 case ARM::STC2_OFFSET:
1275 case ARM::STC2L_OFFSET:
1276 case ARM::STC2_PRE:
1277 case ARM::STC2L_PRE:
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001278 case ARM::t2LDC_OFFSET:
1279 case ARM::t2LDCL_OFFSET:
1280 case ARM::t2LDC_PRE:
1281 case ARM::t2LDCL_PRE:
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001282 case ARM::t2STC_OFFSET:
1283 case ARM::t2STCL_OFFSET:
1284 case ARM::t2STC_PRE:
1285 case ARM::t2STCL_PRE:
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001286 case ARM::LDC_OFFSET:
1287 case ARM::LDCL_OFFSET:
1288 case ARM::LDC_PRE:
1289 case ARM::LDCL_PRE:
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001290 case ARM::STC_OFFSET:
1291 case ARM::STCL_OFFSET:
1292 case ARM::STC_PRE:
1293 case ARM::STCL_PRE:
Jim Grosbach81b29282011-10-12 21:59:02 +00001294 imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
1295 Inst.addOperand(MCOperand::CreateImm(imm));
1296 break;
1297 case ARM::t2LDC2_POST:
1298 case ARM::t2LDC2L_POST:
1299 case ARM::t2STC2_POST:
1300 case ARM::t2STC2L_POST:
1301 case ARM::LDC2_POST:
1302 case ARM::LDC2L_POST:
1303 case ARM::STC2_POST:
1304 case ARM::STC2L_POST:
1305 case ARM::t2LDC_POST:
1306 case ARM::t2LDCL_POST:
1307 case ARM::t2STC_POST:
1308 case ARM::t2STCL_POST:
1309 case ARM::LDC_POST:
1310 case ARM::LDCL_POST:
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001311 case ARM::STC_POST:
1312 case ARM::STCL_POST:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001313 imm |= U << 8;
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001314 // fall through.
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001315 default:
Jim Grosbachc66e7af2011-10-12 20:54:17 +00001316 // The 'option' variant doesn't encode 'U' in the immediate since
1317 // the immediate is unsigned [0,255].
1318 Inst.addOperand(MCOperand::CreateImm(imm));
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001319 break;
1320 }
1321
1322 switch (Inst.getOpcode()) {
1323 case ARM::LDC_OFFSET:
1324 case ARM::LDC_PRE:
1325 case ARM::LDC_POST:
1326 case ARM::LDC_OPTION:
1327 case ARM::LDCL_OFFSET:
1328 case ARM::LDCL_PRE:
1329 case ARM::LDCL_POST:
1330 case ARM::LDCL_OPTION:
1331 case ARM::STC_OFFSET:
1332 case ARM::STC_PRE:
1333 case ARM::STC_POST:
1334 case ARM::STC_OPTION:
1335 case ARM::STCL_OFFSET:
1336 case ARM::STCL_PRE:
1337 case ARM::STCL_POST:
1338 case ARM::STCL_OPTION:
Owen Andersona6804442011-09-01 23:23:50 +00001339 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1340 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001341 break;
1342 default:
1343 break;
1344 }
1345
Owen Anderson83e3f672011-08-17 17:44:15 +00001346 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001347}
1348
Owen Andersona6804442011-09-01 23:23:50 +00001349static DecodeStatus
Jim Grosbachc4057822011-08-17 21:58:18 +00001350DecodeAddrMode2IdxInstruction(llvm::MCInst &Inst, unsigned Insn,
1351 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001352 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001353
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001354 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1355 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
1356 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
1357 unsigned imm = fieldFromInstruction32(Insn, 0, 12);
1358 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1359 unsigned reg = fieldFromInstruction32(Insn, 25, 1);
1360 unsigned P = fieldFromInstruction32(Insn, 24, 1);
1361 unsigned W = fieldFromInstruction32(Insn, 21, 1);
1362
1363 // On stores, the writeback operand precedes Rt.
1364 switch (Inst.getOpcode()) {
1365 case ARM::STR_POST_IMM:
1366 case ARM::STR_POST_REG:
Owen Anderson508e1d32011-08-11 20:47:56 +00001367 case ARM::STRB_POST_IMM:
1368 case ARM::STRB_POST_REG:
Jim Grosbach342ebd52011-08-11 22:18:00 +00001369 case ARM::STRT_POST_REG:
1370 case ARM::STRT_POST_IMM:
Jim Grosbach10348e72011-08-11 20:04:56 +00001371 case ARM::STRBT_POST_REG:
1372 case ARM::STRBT_POST_IMM:
Owen Andersona6804442011-09-01 23:23:50 +00001373 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1374 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001375 break;
1376 default:
1377 break;
1378 }
1379
Owen Andersona6804442011-09-01 23:23:50 +00001380 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1381 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001382
1383 // On loads, the writeback operand comes after Rt.
1384 switch (Inst.getOpcode()) {
1385 case ARM::LDR_POST_IMM:
1386 case ARM::LDR_POST_REG:
Owen Anderson508e1d32011-08-11 20:47:56 +00001387 case ARM::LDRB_POST_IMM:
1388 case ARM::LDRB_POST_REG:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001389 case ARM::LDRBT_POST_REG:
1390 case ARM::LDRBT_POST_IMM:
Jim Grosbach59999262011-08-10 23:43:54 +00001391 case ARM::LDRT_POST_REG:
1392 case ARM::LDRT_POST_IMM:
Owen Andersona6804442011-09-01 23:23:50 +00001393 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1394 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001395 break;
1396 default:
1397 break;
1398 }
1399
Owen Andersona6804442011-09-01 23:23:50 +00001400 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1401 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001402
1403 ARM_AM::AddrOpc Op = ARM_AM::add;
1404 if (!fieldFromInstruction32(Insn, 23, 1))
1405 Op = ARM_AM::sub;
1406
1407 bool writeback = (P == 0) || (W == 1);
1408 unsigned idx_mode = 0;
1409 if (P && writeback)
1410 idx_mode = ARMII::IndexModePre;
1411 else if (!P && writeback)
1412 idx_mode = ARMII::IndexModePost;
1413
Owen Andersona6804442011-09-01 23:23:50 +00001414 if (writeback && (Rn == 15 || Rn == Rt))
1415 S = MCDisassembler::SoftFail; // UNPREDICTABLE
Owen Anderson71156a62011-08-11 19:00:18 +00001416
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001417 if (reg) {
Owen Andersona6804442011-09-01 23:23:50 +00001418 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1419 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001420 ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
1421 switch( fieldFromInstruction32(Insn, 5, 2)) {
1422 case 0:
1423 Opc = ARM_AM::lsl;
1424 break;
1425 case 1:
1426 Opc = ARM_AM::lsr;
1427 break;
1428 case 2:
1429 Opc = ARM_AM::asr;
1430 break;
1431 case 3:
1432 Opc = ARM_AM::ror;
1433 break;
1434 default:
James Molloyc047dca2011-09-01 18:02:14 +00001435 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001436 }
1437 unsigned amt = fieldFromInstruction32(Insn, 7, 5);
1438 unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
1439
1440 Inst.addOperand(MCOperand::CreateImm(imm));
1441 } else {
1442 Inst.addOperand(MCOperand::CreateReg(0));
1443 unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
1444 Inst.addOperand(MCOperand::CreateImm(tmp));
1445 }
1446
Owen Andersona6804442011-09-01 23:23:50 +00001447 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1448 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001449
Owen Anderson83e3f672011-08-17 17:44:15 +00001450 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001451}
1452
Owen Andersona6804442011-09-01 23:23:50 +00001453static DecodeStatus DecodeSORegMemOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001454 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001455 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001456
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001457 unsigned Rn = fieldFromInstruction32(Val, 13, 4);
1458 unsigned Rm = fieldFromInstruction32(Val, 0, 4);
1459 unsigned type = fieldFromInstruction32(Val, 5, 2);
1460 unsigned imm = fieldFromInstruction32(Val, 7, 5);
1461 unsigned U = fieldFromInstruction32(Val, 12, 1);
1462
Owen Anderson51157d22011-08-09 21:38:14 +00001463 ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001464 switch (type) {
1465 case 0:
1466 ShOp = ARM_AM::lsl;
1467 break;
1468 case 1:
1469 ShOp = ARM_AM::lsr;
1470 break;
1471 case 2:
1472 ShOp = ARM_AM::asr;
1473 break;
1474 case 3:
1475 ShOp = ARM_AM::ror;
1476 break;
1477 }
1478
Owen Andersona6804442011-09-01 23:23:50 +00001479 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1480 return MCDisassembler::Fail;
1481 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1482 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001483 unsigned shift;
1484 if (U)
1485 shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
1486 else
1487 shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
1488 Inst.addOperand(MCOperand::CreateImm(shift));
1489
Owen Anderson83e3f672011-08-17 17:44:15 +00001490 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001491}
1492
Owen Andersona6804442011-09-01 23:23:50 +00001493static DecodeStatus
Jim Grosbachc4057822011-08-17 21:58:18 +00001494DecodeAddrMode3Instruction(llvm::MCInst &Inst, unsigned Insn,
1495 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001496 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001497
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001498 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
1499 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1500 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
1501 unsigned type = fieldFromInstruction32(Insn, 22, 1);
1502 unsigned imm = fieldFromInstruction32(Insn, 8, 4);
1503 unsigned U = ((~fieldFromInstruction32(Insn, 23, 1)) & 1) << 8;
1504 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1505 unsigned W = fieldFromInstruction32(Insn, 21, 1);
1506 unsigned P = fieldFromInstruction32(Insn, 24, 1);
1507
1508 bool writeback = (W == 1) | (P == 0);
Owen Andersonc537f3b2011-08-15 20:51:32 +00001509
1510 // For {LD,ST}RD, Rt must be even, else undefined.
1511 switch (Inst.getOpcode()) {
1512 case ARM::STRD:
1513 case ARM::STRD_PRE:
1514 case ARM::STRD_POST:
1515 case ARM::LDRD:
1516 case ARM::LDRD_PRE:
1517 case ARM::LDRD_POST:
James Molloyc047dca2011-09-01 18:02:14 +00001518 if (Rt & 0x1) return MCDisassembler::Fail;
Owen Andersonc537f3b2011-08-15 20:51:32 +00001519 break;
Owen Andersona6804442011-09-01 23:23:50 +00001520 default:
1521 break;
Owen Andersonc537f3b2011-08-15 20:51:32 +00001522 }
1523
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001524 if (writeback) { // Writeback
1525 if (P)
1526 U |= ARMII::IndexModePre << 9;
1527 else
1528 U |= ARMII::IndexModePost << 9;
1529
1530 // On stores, the writeback operand precedes Rt.
1531 switch (Inst.getOpcode()) {
1532 case ARM::STRD:
1533 case ARM::STRD_PRE:
1534 case ARM::STRD_POST:
Owen Anderson79628e92011-08-12 20:02:50 +00001535 case ARM::STRH:
1536 case ARM::STRH_PRE:
1537 case ARM::STRH_POST:
Owen Andersona6804442011-09-01 23:23:50 +00001538 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1539 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001540 break;
1541 default:
1542 break;
1543 }
1544 }
1545
Owen Andersona6804442011-09-01 23:23:50 +00001546 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1547 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001548 switch (Inst.getOpcode()) {
1549 case ARM::STRD:
1550 case ARM::STRD_PRE:
1551 case ARM::STRD_POST:
1552 case ARM::LDRD:
1553 case ARM::LDRD_PRE:
1554 case ARM::LDRD_POST:
Owen Andersona6804442011-09-01 23:23:50 +00001555 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
1556 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001557 break;
1558 default:
1559 break;
1560 }
1561
1562 if (writeback) {
1563 // On loads, the writeback operand comes after Rt.
1564 switch (Inst.getOpcode()) {
1565 case ARM::LDRD:
1566 case ARM::LDRD_PRE:
1567 case ARM::LDRD_POST:
Owen Anderson0d094992011-08-12 20:36:11 +00001568 case ARM::LDRH:
1569 case ARM::LDRH_PRE:
1570 case ARM::LDRH_POST:
1571 case ARM::LDRSH:
1572 case ARM::LDRSH_PRE:
1573 case ARM::LDRSH_POST:
1574 case ARM::LDRSB:
1575 case ARM::LDRSB_PRE:
1576 case ARM::LDRSB_POST:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001577 case ARM::LDRHTr:
1578 case ARM::LDRSBTr:
Owen Andersona6804442011-09-01 23:23:50 +00001579 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1580 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001581 break;
1582 default:
1583 break;
1584 }
1585 }
1586
Owen Andersona6804442011-09-01 23:23:50 +00001587 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1588 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001589
1590 if (type) {
1591 Inst.addOperand(MCOperand::CreateReg(0));
1592 Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm));
1593 } else {
Owen Andersona6804442011-09-01 23:23:50 +00001594 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1595 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001596 Inst.addOperand(MCOperand::CreateImm(U));
1597 }
1598
Owen Andersona6804442011-09-01 23:23:50 +00001599 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1600 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001601
Owen Anderson83e3f672011-08-17 17:44:15 +00001602 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001603}
1604
Owen Andersona6804442011-09-01 23:23:50 +00001605static DecodeStatus DecodeRFEInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001606 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001607 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001608
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001609 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1610 unsigned mode = fieldFromInstruction32(Insn, 23, 2);
1611
1612 switch (mode) {
1613 case 0:
1614 mode = ARM_AM::da;
1615 break;
1616 case 1:
1617 mode = ARM_AM::ia;
1618 break;
1619 case 2:
1620 mode = ARM_AM::db;
1621 break;
1622 case 3:
1623 mode = ARM_AM::ib;
1624 break;
1625 }
1626
1627 Inst.addOperand(MCOperand::CreateImm(mode));
Owen Andersona6804442011-09-01 23:23:50 +00001628 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1629 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001630
Owen Anderson83e3f672011-08-17 17:44:15 +00001631 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001632}
1633
Owen Andersona6804442011-09-01 23:23:50 +00001634static DecodeStatus DecodeMemMultipleWritebackInstruction(llvm::MCInst &Inst,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001635 unsigned Insn,
1636 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001637 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001638
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001639 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1640 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1641 unsigned reglist = fieldFromInstruction32(Insn, 0, 16);
1642
1643 if (pred == 0xF) {
1644 switch (Inst.getOpcode()) {
Owen Anderson846dd952011-08-18 22:31:17 +00001645 case ARM::LDMDA:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001646 Inst.setOpcode(ARM::RFEDA);
1647 break;
Owen Anderson846dd952011-08-18 22:31:17 +00001648 case ARM::LDMDA_UPD:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001649 Inst.setOpcode(ARM::RFEDA_UPD);
1650 break;
Owen Anderson846dd952011-08-18 22:31:17 +00001651 case ARM::LDMDB:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001652 Inst.setOpcode(ARM::RFEDB);
1653 break;
Owen Anderson846dd952011-08-18 22:31:17 +00001654 case ARM::LDMDB_UPD:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001655 Inst.setOpcode(ARM::RFEDB_UPD);
1656 break;
Owen Anderson846dd952011-08-18 22:31:17 +00001657 case ARM::LDMIA:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001658 Inst.setOpcode(ARM::RFEIA);
1659 break;
Owen Anderson846dd952011-08-18 22:31:17 +00001660 case ARM::LDMIA_UPD:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001661 Inst.setOpcode(ARM::RFEIA_UPD);
1662 break;
Owen Anderson846dd952011-08-18 22:31:17 +00001663 case ARM::LDMIB:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001664 Inst.setOpcode(ARM::RFEIB);
1665 break;
Owen Anderson846dd952011-08-18 22:31:17 +00001666 case ARM::LDMIB_UPD:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001667 Inst.setOpcode(ARM::RFEIB_UPD);
1668 break;
Owen Anderson846dd952011-08-18 22:31:17 +00001669 case ARM::STMDA:
1670 Inst.setOpcode(ARM::SRSDA);
1671 break;
1672 case ARM::STMDA_UPD:
1673 Inst.setOpcode(ARM::SRSDA_UPD);
1674 break;
1675 case ARM::STMDB:
1676 Inst.setOpcode(ARM::SRSDB);
1677 break;
1678 case ARM::STMDB_UPD:
1679 Inst.setOpcode(ARM::SRSDB_UPD);
1680 break;
1681 case ARM::STMIA:
1682 Inst.setOpcode(ARM::SRSIA);
1683 break;
1684 case ARM::STMIA_UPD:
1685 Inst.setOpcode(ARM::SRSIA_UPD);
1686 break;
1687 case ARM::STMIB:
1688 Inst.setOpcode(ARM::SRSIB);
1689 break;
1690 case ARM::STMIB_UPD:
1691 Inst.setOpcode(ARM::SRSIB_UPD);
1692 break;
1693 default:
James Molloyc047dca2011-09-01 18:02:14 +00001694 if (!Check(S, MCDisassembler::Fail)) return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001695 }
Owen Anderson846dd952011-08-18 22:31:17 +00001696
1697 // For stores (which become SRS's, the only operand is the mode.
1698 if (fieldFromInstruction32(Insn, 20, 1) == 0) {
1699 Inst.addOperand(
1700 MCOperand::CreateImm(fieldFromInstruction32(Insn, 0, 4)));
1701 return S;
1702 }
1703
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001704 return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
1705 }
1706
Owen Andersona6804442011-09-01 23:23:50 +00001707 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1708 return MCDisassembler::Fail;
1709 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1710 return MCDisassembler::Fail; // Tied
1711 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1712 return MCDisassembler::Fail;
1713 if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
1714 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001715
Owen Anderson83e3f672011-08-17 17:44:15 +00001716 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001717}
1718
Owen Andersona6804442011-09-01 23:23:50 +00001719static DecodeStatus DecodeCPSInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001720 uint64_t Address, const void *Decoder) {
1721 unsigned imod = fieldFromInstruction32(Insn, 18, 2);
1722 unsigned M = fieldFromInstruction32(Insn, 17, 1);
1723 unsigned iflags = fieldFromInstruction32(Insn, 6, 3);
1724 unsigned mode = fieldFromInstruction32(Insn, 0, 5);
1725
Owen Andersona6804442011-09-01 23:23:50 +00001726 DecodeStatus S = MCDisassembler::Success;
Owen Anderson35008c22011-08-09 23:05:39 +00001727
Owen Anderson14090bf2011-08-18 22:11:02 +00001728 // imod == '01' --> UNPREDICTABLE
1729 // NOTE: Even though this is technically UNPREDICTABLE, we choose to
1730 // return failure here. The '01' imod value is unprintable, so there's
1731 // nothing useful we could do even if we returned UNPREDICTABLE.
1732
James Molloyc047dca2011-09-01 18:02:14 +00001733 if (imod == 1) return MCDisassembler::Fail;
Owen Anderson14090bf2011-08-18 22:11:02 +00001734
1735 if (imod && M) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001736 Inst.setOpcode(ARM::CPS3p);
1737 Inst.addOperand(MCOperand::CreateImm(imod));
1738 Inst.addOperand(MCOperand::CreateImm(iflags));
1739 Inst.addOperand(MCOperand::CreateImm(mode));
Owen Anderson14090bf2011-08-18 22:11:02 +00001740 } else if (imod && !M) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001741 Inst.setOpcode(ARM::CPS2p);
1742 Inst.addOperand(MCOperand::CreateImm(imod));
1743 Inst.addOperand(MCOperand::CreateImm(iflags));
James Molloyc047dca2011-09-01 18:02:14 +00001744 if (mode) S = MCDisassembler::SoftFail;
Owen Anderson14090bf2011-08-18 22:11:02 +00001745 } else if (!imod && M) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001746 Inst.setOpcode(ARM::CPS1p);
1747 Inst.addOperand(MCOperand::CreateImm(mode));
James Molloyc047dca2011-09-01 18:02:14 +00001748 if (iflags) S = MCDisassembler::SoftFail;
Owen Anderson1dd56f02011-08-18 22:15:25 +00001749 } else {
Owen Anderson14090bf2011-08-18 22:11:02 +00001750 // imod == '00' && M == '0' --> UNPREDICTABLE
Owen Anderson1dd56f02011-08-18 22:15:25 +00001751 Inst.setOpcode(ARM::CPS1p);
1752 Inst.addOperand(MCOperand::CreateImm(mode));
James Molloyc047dca2011-09-01 18:02:14 +00001753 S = MCDisassembler::SoftFail;
Owen Anderson1dd56f02011-08-18 22:15:25 +00001754 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001755
Owen Anderson14090bf2011-08-18 22:11:02 +00001756 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001757}
1758
Owen Andersona6804442011-09-01 23:23:50 +00001759static DecodeStatus DecodeT2CPSInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson6153a032011-08-23 17:45:18 +00001760 uint64_t Address, const void *Decoder) {
1761 unsigned imod = fieldFromInstruction32(Insn, 9, 2);
1762 unsigned M = fieldFromInstruction32(Insn, 8, 1);
1763 unsigned iflags = fieldFromInstruction32(Insn, 5, 3);
1764 unsigned mode = fieldFromInstruction32(Insn, 0, 5);
1765
Owen Andersona6804442011-09-01 23:23:50 +00001766 DecodeStatus S = MCDisassembler::Success;
Owen Anderson6153a032011-08-23 17:45:18 +00001767
1768 // imod == '01' --> UNPREDICTABLE
1769 // NOTE: Even though this is technically UNPREDICTABLE, we choose to
1770 // return failure here. The '01' imod value is unprintable, so there's
1771 // nothing useful we could do even if we returned UNPREDICTABLE.
1772
James Molloyc047dca2011-09-01 18:02:14 +00001773 if (imod == 1) return MCDisassembler::Fail;
Owen Anderson6153a032011-08-23 17:45:18 +00001774
1775 if (imod && M) {
1776 Inst.setOpcode(ARM::t2CPS3p);
1777 Inst.addOperand(MCOperand::CreateImm(imod));
1778 Inst.addOperand(MCOperand::CreateImm(iflags));
1779 Inst.addOperand(MCOperand::CreateImm(mode));
1780 } else if (imod && !M) {
1781 Inst.setOpcode(ARM::t2CPS2p);
1782 Inst.addOperand(MCOperand::CreateImm(imod));
1783 Inst.addOperand(MCOperand::CreateImm(iflags));
James Molloyc047dca2011-09-01 18:02:14 +00001784 if (mode) S = MCDisassembler::SoftFail;
Owen Anderson6153a032011-08-23 17:45:18 +00001785 } else if (!imod && M) {
1786 Inst.setOpcode(ARM::t2CPS1p);
1787 Inst.addOperand(MCOperand::CreateImm(mode));
James Molloyc047dca2011-09-01 18:02:14 +00001788 if (iflags) S = MCDisassembler::SoftFail;
Owen Anderson6153a032011-08-23 17:45:18 +00001789 } else {
1790 // imod == '00' && M == '0' --> UNPREDICTABLE
1791 Inst.setOpcode(ARM::t2CPS1p);
1792 Inst.addOperand(MCOperand::CreateImm(mode));
James Molloyc047dca2011-09-01 18:02:14 +00001793 S = MCDisassembler::SoftFail;
Owen Anderson6153a032011-08-23 17:45:18 +00001794 }
1795
1796 return S;
1797}
1798
Kevin Enderby9e5887b2011-10-04 22:44:48 +00001799static DecodeStatus DecodeT2MOVTWInstruction(llvm::MCInst &Inst, unsigned Insn,
1800 uint64_t Address, const void *Decoder) {
1801 DecodeStatus S = MCDisassembler::Success;
1802
1803 unsigned Rd = fieldFromInstruction32(Insn, 8, 4);
1804 unsigned imm = 0;
1805
1806 imm |= (fieldFromInstruction32(Insn, 0, 8) << 0);
1807 imm |= (fieldFromInstruction32(Insn, 12, 3) << 8);
1808 imm |= (fieldFromInstruction32(Insn, 16, 4) << 12);
1809 imm |= (fieldFromInstruction32(Insn, 26, 1) << 11);
1810
1811 if (Inst.getOpcode() == ARM::t2MOVTi16)
1812 if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1813 return MCDisassembler::Fail;
1814 if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1815 return MCDisassembler::Fail;
1816
1817 if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
1818 Inst.addOperand(MCOperand::CreateImm(imm));
1819
1820 return S;
1821}
1822
1823static DecodeStatus DecodeArmMOVTWInstruction(llvm::MCInst &Inst, unsigned Insn,
1824 uint64_t Address, const void *Decoder) {
1825 DecodeStatus S = MCDisassembler::Success;
1826
1827 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
1828 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1829 unsigned imm = 0;
1830
1831 imm |= (fieldFromInstruction32(Insn, 0, 12) << 0);
1832 imm |= (fieldFromInstruction32(Insn, 16, 4) << 12);
1833
1834 if (Inst.getOpcode() == ARM::MOVTi16)
1835 if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1836 return MCDisassembler::Fail;
1837 if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
1838 return MCDisassembler::Fail;
1839
1840 if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
1841 Inst.addOperand(MCOperand::CreateImm(imm));
1842
1843 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1844 return MCDisassembler::Fail;
1845
1846 return S;
1847}
Owen Anderson6153a032011-08-23 17:45:18 +00001848
Owen Andersona6804442011-09-01 23:23:50 +00001849static DecodeStatus DecodeSMLAInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001850 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001851 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001852
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001853 unsigned Rd = fieldFromInstruction32(Insn, 16, 4);
1854 unsigned Rn = fieldFromInstruction32(Insn, 0, 4);
1855 unsigned Rm = fieldFromInstruction32(Insn, 8, 4);
1856 unsigned Ra = fieldFromInstruction32(Insn, 12, 4);
1857 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1858
1859 if (pred == 0xF)
1860 return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
1861
Owen Andersona6804442011-09-01 23:23:50 +00001862 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
1863 return MCDisassembler::Fail;
1864 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
1865 return MCDisassembler::Fail;
1866 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1867 return MCDisassembler::Fail;
1868 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
1869 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001870
Owen Andersona6804442011-09-01 23:23:50 +00001871 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1872 return MCDisassembler::Fail;
Owen Anderson1fb66732011-08-11 22:05:38 +00001873
Owen Anderson83e3f672011-08-17 17:44:15 +00001874 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001875}
1876
Owen Andersona6804442011-09-01 23:23:50 +00001877static DecodeStatus DecodeAddrModeImm12Operand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001878 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001879 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001880
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001881 unsigned add = fieldFromInstruction32(Val, 12, 1);
1882 unsigned imm = fieldFromInstruction32(Val, 0, 12);
1883 unsigned Rn = fieldFromInstruction32(Val, 13, 4);
1884
Owen Andersona6804442011-09-01 23:23:50 +00001885 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1886 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001887
1888 if (!add) imm *= -1;
1889 if (imm == 0 && !add) imm = INT32_MIN;
1890 Inst.addOperand(MCOperand::CreateImm(imm));
Kevin Enderby9e5887b2011-10-04 22:44:48 +00001891 if (Rn == 15)
1892 tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001893
Owen Anderson83e3f672011-08-17 17:44:15 +00001894 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001895}
1896
Owen Andersona6804442011-09-01 23:23:50 +00001897static DecodeStatus DecodeAddrMode5Operand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001898 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001899 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001900
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001901 unsigned Rn = fieldFromInstruction32(Val, 9, 4);
1902 unsigned U = fieldFromInstruction32(Val, 8, 1);
1903 unsigned imm = fieldFromInstruction32(Val, 0, 8);
1904
Owen Andersona6804442011-09-01 23:23:50 +00001905 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1906 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001907
1908 if (U)
1909 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
1910 else
1911 Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
1912
Owen Anderson83e3f672011-08-17 17:44:15 +00001913 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001914}
1915
Owen Andersona6804442011-09-01 23:23:50 +00001916static DecodeStatus DecodeAddrMode7Operand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001917 uint64_t Address, const void *Decoder) {
1918 return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
1919}
1920
Owen Andersona6804442011-09-01 23:23:50 +00001921static DecodeStatus
Jim Grosbachc4057822011-08-17 21:58:18 +00001922DecodeBranchImmInstruction(llvm::MCInst &Inst, unsigned Insn,
1923 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001924 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001925
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001926 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
1927 unsigned imm = fieldFromInstruction32(Insn, 0, 24) << 2;
1928
1929 if (pred == 0xF) {
1930 Inst.setOpcode(ARM::BLXi);
1931 imm |= fieldFromInstruction32(Insn, 24, 1) << 1;
Kevin Enderbyb80d5712012-02-23 18:18:17 +00001932 if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
1933 true, 4, Inst, Decoder))
Benjamin Kramer793b8112011-08-09 22:02:50 +00001934 Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
Owen Anderson83e3f672011-08-17 17:44:15 +00001935 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001936 }
1937
Kevin Enderbyb80d5712012-02-23 18:18:17 +00001938 if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
1939 true, 4, Inst, Decoder))
Kevin Enderby9e5887b2011-10-04 22:44:48 +00001940 Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
Owen Andersona6804442011-09-01 23:23:50 +00001941 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1942 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001943
Owen Anderson83e3f672011-08-17 17:44:15 +00001944 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001945}
1946
1947
Owen Andersona6804442011-09-01 23:23:50 +00001948static DecodeStatus DecodeAddrMode6Operand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001949 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001950 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001951
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001952 unsigned Rm = fieldFromInstruction32(Val, 0, 4);
1953 unsigned align = fieldFromInstruction32(Val, 4, 2);
1954
Owen Andersona6804442011-09-01 23:23:50 +00001955 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1956 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001957 if (!align)
1958 Inst.addOperand(MCOperand::CreateImm(0));
1959 else
1960 Inst.addOperand(MCOperand::CreateImm(4 << align));
1961
Owen Anderson83e3f672011-08-17 17:44:15 +00001962 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001963}
1964
Owen Andersona6804442011-09-01 23:23:50 +00001965static DecodeStatus DecodeVLDInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001966 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00001967 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00001968
Owen Anderson8d7d2e12011-08-09 20:55:18 +00001969 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
1970 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
1971 unsigned wb = fieldFromInstruction32(Insn, 16, 4);
1972 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
1973 Rn |= fieldFromInstruction32(Insn, 4, 2) << 4;
1974 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
1975
1976 // First output register
Jim Grosbach28f08c92012-03-05 19:33:30 +00001977 switch (Inst.getOpcode()) {
1978 case ARM::VLD1q16:
1979 case ARM::VLD1q32:
1980 case ARM::VLD1q64:
1981 case ARM::VLD1q8:
1982 case ARM::VLD1q16wb_fixed:
1983 case ARM::VLD1q16wb_register:
1984 case ARM::VLD1q32wb_fixed:
1985 case ARM::VLD1q32wb_register:
1986 case ARM::VLD1q64wb_fixed:
1987 case ARM::VLD1q64wb_register:
1988 case ARM::VLD1q8wb_fixed:
1989 case ARM::VLD1q8wb_register:
1990 case ARM::VLD2d16:
1991 case ARM::VLD2d32:
1992 case ARM::VLD2d8:
1993 case ARM::VLD2d16wb_fixed:
1994 case ARM::VLD2d16wb_register:
1995 case ARM::VLD2d32wb_fixed:
1996 case ARM::VLD2d32wb_register:
1997 case ARM::VLD2d8wb_fixed:
1998 case ARM::VLD2d8wb_register:
1999 if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2000 return MCDisassembler::Fail;
2001 break;
2002 default:
2003 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2004 return MCDisassembler::Fail;
2005 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002006
2007 // Second output register
2008 switch (Inst.getOpcode()) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002009 case ARM::VLD3d8:
2010 case ARM::VLD3d16:
2011 case ARM::VLD3d32:
2012 case ARM::VLD3d8_UPD:
2013 case ARM::VLD3d16_UPD:
2014 case ARM::VLD3d32_UPD:
2015 case ARM::VLD4d8:
2016 case ARM::VLD4d16:
2017 case ARM::VLD4d32:
2018 case ARM::VLD4d8_UPD:
2019 case ARM::VLD4d16_UPD:
2020 case ARM::VLD4d32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002021 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2022 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002023 break;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002024 case ARM::VLD3q8:
2025 case ARM::VLD3q16:
2026 case ARM::VLD3q32:
2027 case ARM::VLD3q8_UPD:
2028 case ARM::VLD3q16_UPD:
2029 case ARM::VLD3q32_UPD:
2030 case ARM::VLD4q8:
2031 case ARM::VLD4q16:
2032 case ARM::VLD4q32:
2033 case ARM::VLD4q8_UPD:
2034 case ARM::VLD4q16_UPD:
2035 case ARM::VLD4q32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002036 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2037 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002038 default:
2039 break;
2040 }
2041
2042 // Third output register
2043 switch(Inst.getOpcode()) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002044 case ARM::VLD3d8:
2045 case ARM::VLD3d16:
2046 case ARM::VLD3d32:
2047 case ARM::VLD3d8_UPD:
2048 case ARM::VLD3d16_UPD:
2049 case ARM::VLD3d32_UPD:
2050 case ARM::VLD4d8:
2051 case ARM::VLD4d16:
2052 case ARM::VLD4d32:
2053 case ARM::VLD4d8_UPD:
2054 case ARM::VLD4d16_UPD:
2055 case ARM::VLD4d32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002056 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2057 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002058 break;
2059 case ARM::VLD3q8:
2060 case ARM::VLD3q16:
2061 case ARM::VLD3q32:
2062 case ARM::VLD3q8_UPD:
2063 case ARM::VLD3q16_UPD:
2064 case ARM::VLD3q32_UPD:
2065 case ARM::VLD4q8:
2066 case ARM::VLD4q16:
2067 case ARM::VLD4q32:
2068 case ARM::VLD4q8_UPD:
2069 case ARM::VLD4q16_UPD:
2070 case ARM::VLD4q32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002071 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2072 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002073 break;
2074 default:
2075 break;
2076 }
2077
2078 // Fourth output register
2079 switch (Inst.getOpcode()) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002080 case ARM::VLD4d8:
2081 case ARM::VLD4d16:
2082 case ARM::VLD4d32:
2083 case ARM::VLD4d8_UPD:
2084 case ARM::VLD4d16_UPD:
2085 case ARM::VLD4d32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002086 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2087 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002088 break;
2089 case ARM::VLD4q8:
2090 case ARM::VLD4q16:
2091 case ARM::VLD4q32:
2092 case ARM::VLD4q8_UPD:
2093 case ARM::VLD4q16_UPD:
2094 case ARM::VLD4q32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002095 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2096 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002097 break;
2098 default:
2099 break;
2100 }
2101
2102 // Writeback operand
2103 switch (Inst.getOpcode()) {
Jim Grosbach10b90a92011-10-24 21:45:13 +00002104 case ARM::VLD1d8wb_fixed:
2105 case ARM::VLD1d16wb_fixed:
2106 case ARM::VLD1d32wb_fixed:
2107 case ARM::VLD1d64wb_fixed:
2108 case ARM::VLD1d8wb_register:
2109 case ARM::VLD1d16wb_register:
2110 case ARM::VLD1d32wb_register:
2111 case ARM::VLD1d64wb_register:
2112 case ARM::VLD1q8wb_fixed:
2113 case ARM::VLD1q16wb_fixed:
2114 case ARM::VLD1q32wb_fixed:
2115 case ARM::VLD1q64wb_fixed:
2116 case ARM::VLD1q8wb_register:
2117 case ARM::VLD1q16wb_register:
2118 case ARM::VLD1q32wb_register:
2119 case ARM::VLD1q64wb_register:
Jim Grosbach59216752011-10-24 23:26:05 +00002120 case ARM::VLD1d8Twb_fixed:
2121 case ARM::VLD1d8Twb_register:
2122 case ARM::VLD1d16Twb_fixed:
2123 case ARM::VLD1d16Twb_register:
2124 case ARM::VLD1d32Twb_fixed:
2125 case ARM::VLD1d32Twb_register:
2126 case ARM::VLD1d64Twb_fixed:
2127 case ARM::VLD1d64Twb_register:
Jim Grosbach399cdca2011-10-25 00:14:01 +00002128 case ARM::VLD1d8Qwb_fixed:
2129 case ARM::VLD1d8Qwb_register:
2130 case ARM::VLD1d16Qwb_fixed:
2131 case ARM::VLD1d16Qwb_register:
2132 case ARM::VLD1d32Qwb_fixed:
2133 case ARM::VLD1d32Qwb_register:
2134 case ARM::VLD1d64Qwb_fixed:
2135 case ARM::VLD1d64Qwb_register:
Jim Grosbacha4e3c7f2011-12-09 21:28:25 +00002136 case ARM::VLD2d8wb_fixed:
2137 case ARM::VLD2d16wb_fixed:
2138 case ARM::VLD2d32wb_fixed:
2139 case ARM::VLD2q8wb_fixed:
2140 case ARM::VLD2q16wb_fixed:
2141 case ARM::VLD2q32wb_fixed:
2142 case ARM::VLD2d8wb_register:
2143 case ARM::VLD2d16wb_register:
2144 case ARM::VLD2d32wb_register:
2145 case ARM::VLD2q8wb_register:
2146 case ARM::VLD2q16wb_register:
2147 case ARM::VLD2q32wb_register:
2148 case ARM::VLD2b8wb_fixed:
2149 case ARM::VLD2b16wb_fixed:
2150 case ARM::VLD2b32wb_fixed:
2151 case ARM::VLD2b8wb_register:
2152 case ARM::VLD2b16wb_register:
2153 case ARM::VLD2b32wb_register:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002154 case ARM::VLD3d8_UPD:
2155 case ARM::VLD3d16_UPD:
2156 case ARM::VLD3d32_UPD:
2157 case ARM::VLD3q8_UPD:
2158 case ARM::VLD3q16_UPD:
2159 case ARM::VLD3q32_UPD:
2160 case ARM::VLD4d8_UPD:
2161 case ARM::VLD4d16_UPD:
2162 case ARM::VLD4d32_UPD:
2163 case ARM::VLD4q8_UPD:
2164 case ARM::VLD4q16_UPD:
2165 case ARM::VLD4q32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002166 if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2167 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002168 break;
2169 default:
2170 break;
2171 }
2172
2173 // AddrMode6 Base (register+alignment)
Owen Andersona6804442011-09-01 23:23:50 +00002174 if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2175 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002176
2177 // AddrMode6 Offset (register)
Jim Grosbach10b90a92011-10-24 21:45:13 +00002178 switch (Inst.getOpcode()) {
2179 default:
2180 // The below have been updated to have explicit am6offset split
2181 // between fixed and register offset. For those instructions not
2182 // yet updated, we need to add an additional reg0 operand for the
2183 // fixed variant.
2184 //
2185 // The fixed offset encodes as Rm == 0xd, so we check for that.
2186 if (Rm == 0xd) {
2187 Inst.addOperand(MCOperand::CreateReg(0));
2188 break;
2189 }
2190 // Fall through to handle the register offset variant.
2191 case ARM::VLD1d8wb_fixed:
2192 case ARM::VLD1d16wb_fixed:
2193 case ARM::VLD1d32wb_fixed:
2194 case ARM::VLD1d64wb_fixed:
Owen Anderson04b12a42011-10-27 22:53:10 +00002195 case ARM::VLD1d8Twb_fixed:
2196 case ARM::VLD1d16Twb_fixed:
2197 case ARM::VLD1d32Twb_fixed:
2198 case ARM::VLD1d64Twb_fixed:
Owen Andersonfb6ab2b2011-10-31 17:17:32 +00002199 case ARM::VLD1d8Qwb_fixed:
2200 case ARM::VLD1d16Qwb_fixed:
2201 case ARM::VLD1d32Qwb_fixed:
2202 case ARM::VLD1d64Qwb_fixed:
Jim Grosbach10b90a92011-10-24 21:45:13 +00002203 case ARM::VLD1d8wb_register:
2204 case ARM::VLD1d16wb_register:
2205 case ARM::VLD1d32wb_register:
2206 case ARM::VLD1d64wb_register:
2207 case ARM::VLD1q8wb_fixed:
2208 case ARM::VLD1q16wb_fixed:
2209 case ARM::VLD1q32wb_fixed:
2210 case ARM::VLD1q64wb_fixed:
2211 case ARM::VLD1q8wb_register:
2212 case ARM::VLD1q16wb_register:
2213 case ARM::VLD1q32wb_register:
2214 case ARM::VLD1q64wb_register:
2215 // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2216 // variant encodes Rm == 0xf. Anything else is a register offset post-
2217 // increment and we need to add the register operand to the instruction.
2218 if (Rm != 0xD && Rm != 0xF &&
2219 !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
Owen Andersona6804442011-09-01 23:23:50 +00002220 return MCDisassembler::Fail;
Jim Grosbach10b90a92011-10-24 21:45:13 +00002221 break;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002222 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002223
Owen Anderson83e3f672011-08-17 17:44:15 +00002224 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002225}
2226
Owen Andersona6804442011-09-01 23:23:50 +00002227static DecodeStatus DecodeVSTInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002228 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002229 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002230
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002231 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2232 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2233 unsigned wb = fieldFromInstruction32(Insn, 16, 4);
2234 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2235 Rn |= fieldFromInstruction32(Insn, 4, 2) << 4;
2236 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2237
2238 // Writeback Operand
2239 switch (Inst.getOpcode()) {
Jim Grosbach4334e032011-10-31 21:50:31 +00002240 case ARM::VST1d8wb_fixed:
2241 case ARM::VST1d16wb_fixed:
2242 case ARM::VST1d32wb_fixed:
2243 case ARM::VST1d64wb_fixed:
2244 case ARM::VST1d8wb_register:
2245 case ARM::VST1d16wb_register:
2246 case ARM::VST1d32wb_register:
2247 case ARM::VST1d64wb_register:
2248 case ARM::VST1q8wb_fixed:
2249 case ARM::VST1q16wb_fixed:
2250 case ARM::VST1q32wb_fixed:
2251 case ARM::VST1q64wb_fixed:
2252 case ARM::VST1q8wb_register:
2253 case ARM::VST1q16wb_register:
2254 case ARM::VST1q32wb_register:
2255 case ARM::VST1q64wb_register:
Jim Grosbachd5ca2012011-11-29 22:38:04 +00002256 case ARM::VST1d8Twb_fixed:
2257 case ARM::VST1d16Twb_fixed:
2258 case ARM::VST1d32Twb_fixed:
2259 case ARM::VST1d64Twb_fixed:
2260 case ARM::VST1d8Twb_register:
2261 case ARM::VST1d16Twb_register:
2262 case ARM::VST1d32Twb_register:
2263 case ARM::VST1d64Twb_register:
Jim Grosbach4c7edb32011-11-29 22:58:48 +00002264 case ARM::VST1d8Qwb_fixed:
2265 case ARM::VST1d16Qwb_fixed:
2266 case ARM::VST1d32Qwb_fixed:
2267 case ARM::VST1d64Qwb_fixed:
2268 case ARM::VST1d8Qwb_register:
2269 case ARM::VST1d16Qwb_register:
2270 case ARM::VST1d32Qwb_register:
2271 case ARM::VST1d64Qwb_register:
Jim Grosbachbb3a2e42011-12-14 21:32:11 +00002272 case ARM::VST2d8wb_fixed:
2273 case ARM::VST2d16wb_fixed:
2274 case ARM::VST2d32wb_fixed:
2275 case ARM::VST2d8wb_register:
2276 case ARM::VST2d16wb_register:
2277 case ARM::VST2d32wb_register:
2278 case ARM::VST2q8wb_fixed:
2279 case ARM::VST2q16wb_fixed:
2280 case ARM::VST2q32wb_fixed:
2281 case ARM::VST2q8wb_register:
2282 case ARM::VST2q16wb_register:
2283 case ARM::VST2q32wb_register:
2284 case ARM::VST2b8wb_fixed:
2285 case ARM::VST2b16wb_fixed:
2286 case ARM::VST2b32wb_fixed:
2287 case ARM::VST2b8wb_register:
2288 case ARM::VST2b16wb_register:
2289 case ARM::VST2b32wb_register:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002290 case ARM::VST3d8_UPD:
2291 case ARM::VST3d16_UPD:
2292 case ARM::VST3d32_UPD:
2293 case ARM::VST3q8_UPD:
2294 case ARM::VST3q16_UPD:
2295 case ARM::VST3q32_UPD:
2296 case ARM::VST4d8_UPD:
2297 case ARM::VST4d16_UPD:
2298 case ARM::VST4d32_UPD:
2299 case ARM::VST4q8_UPD:
2300 case ARM::VST4q16_UPD:
2301 case ARM::VST4q32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002302 if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2303 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002304 break;
2305 default:
2306 break;
2307 }
2308
2309 // AddrMode6 Base (register+alignment)
Owen Andersona6804442011-09-01 23:23:50 +00002310 if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2311 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002312
2313 // AddrMode6 Offset (register)
Owen Anderson60cb6432011-11-01 22:18:13 +00002314 switch (Inst.getOpcode()) {
2315 default:
2316 if (Rm == 0xD)
2317 Inst.addOperand(MCOperand::CreateReg(0));
2318 else if (Rm != 0xF) {
2319 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2320 return MCDisassembler::Fail;
2321 }
2322 break;
2323 case ARM::VST1d8wb_fixed:
2324 case ARM::VST1d16wb_fixed:
2325 case ARM::VST1d32wb_fixed:
2326 case ARM::VST1d64wb_fixed:
2327 case ARM::VST1q8wb_fixed:
2328 case ARM::VST1q16wb_fixed:
2329 case ARM::VST1q32wb_fixed:
2330 case ARM::VST1q64wb_fixed:
2331 break;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002332 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002333
Owen Anderson60cb6432011-11-01 22:18:13 +00002334
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002335 // First input register
Jim Grosbach28f08c92012-03-05 19:33:30 +00002336 switch (Inst.getOpcode()) {
2337 case ARM::VST1q16:
2338 case ARM::VST1q32:
2339 case ARM::VST1q64:
2340 case ARM::VST1q8:
2341 case ARM::VST1q16wb_fixed:
2342 case ARM::VST1q16wb_register:
2343 case ARM::VST1q32wb_fixed:
2344 case ARM::VST1q32wb_register:
2345 case ARM::VST1q64wb_fixed:
2346 case ARM::VST1q64wb_register:
2347 case ARM::VST1q8wb_fixed:
2348 case ARM::VST1q8wb_register:
2349 case ARM::VST2d16:
2350 case ARM::VST2d32:
2351 case ARM::VST2d8:
2352 case ARM::VST2d16wb_fixed:
2353 case ARM::VST2d16wb_register:
2354 case ARM::VST2d32wb_fixed:
2355 case ARM::VST2d32wb_register:
2356 case ARM::VST2d8wb_fixed:
2357 case ARM::VST2d8wb_register:
2358 if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2359 return MCDisassembler::Fail;
2360 break;
2361 default:
2362 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2363 return MCDisassembler::Fail;
2364 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002365
2366 // Second input register
2367 switch (Inst.getOpcode()) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002368 case ARM::VST3d8:
2369 case ARM::VST3d16:
2370 case ARM::VST3d32:
2371 case ARM::VST3d8_UPD:
2372 case ARM::VST3d16_UPD:
2373 case ARM::VST3d32_UPD:
2374 case ARM::VST4d8:
2375 case ARM::VST4d16:
2376 case ARM::VST4d32:
2377 case ARM::VST4d8_UPD:
2378 case ARM::VST4d16_UPD:
2379 case ARM::VST4d32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002380 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2381 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002382 break;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002383 case ARM::VST3q8:
2384 case ARM::VST3q16:
2385 case ARM::VST3q32:
2386 case ARM::VST3q8_UPD:
2387 case ARM::VST3q16_UPD:
2388 case ARM::VST3q32_UPD:
2389 case ARM::VST4q8:
2390 case ARM::VST4q16:
2391 case ARM::VST4q32:
2392 case ARM::VST4q8_UPD:
2393 case ARM::VST4q16_UPD:
2394 case ARM::VST4q32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002395 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2396 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002397 break;
2398 default:
2399 break;
2400 }
2401
2402 // Third input register
2403 switch (Inst.getOpcode()) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002404 case ARM::VST3d8:
2405 case ARM::VST3d16:
2406 case ARM::VST3d32:
2407 case ARM::VST3d8_UPD:
2408 case ARM::VST3d16_UPD:
2409 case ARM::VST3d32_UPD:
2410 case ARM::VST4d8:
2411 case ARM::VST4d16:
2412 case ARM::VST4d32:
2413 case ARM::VST4d8_UPD:
2414 case ARM::VST4d16_UPD:
2415 case ARM::VST4d32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002416 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2417 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002418 break;
2419 case ARM::VST3q8:
2420 case ARM::VST3q16:
2421 case ARM::VST3q32:
2422 case ARM::VST3q8_UPD:
2423 case ARM::VST3q16_UPD:
2424 case ARM::VST3q32_UPD:
2425 case ARM::VST4q8:
2426 case ARM::VST4q16:
2427 case ARM::VST4q32:
2428 case ARM::VST4q8_UPD:
2429 case ARM::VST4q16_UPD:
2430 case ARM::VST4q32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002431 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2432 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002433 break;
2434 default:
2435 break;
2436 }
2437
2438 // Fourth input register
2439 switch (Inst.getOpcode()) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002440 case ARM::VST4d8:
2441 case ARM::VST4d16:
2442 case ARM::VST4d32:
2443 case ARM::VST4d8_UPD:
2444 case ARM::VST4d16_UPD:
2445 case ARM::VST4d32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002446 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2447 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002448 break;
2449 case ARM::VST4q8:
2450 case ARM::VST4q16:
2451 case ARM::VST4q32:
2452 case ARM::VST4q8_UPD:
2453 case ARM::VST4q16_UPD:
2454 case ARM::VST4q32_UPD:
Owen Andersona6804442011-09-01 23:23:50 +00002455 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2456 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002457 break;
2458 default:
2459 break;
2460 }
2461
Owen Anderson83e3f672011-08-17 17:44:15 +00002462 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002463}
2464
Owen Andersona6804442011-09-01 23:23:50 +00002465static DecodeStatus DecodeVLD1DupInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002466 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002467 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002468
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002469 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2470 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2471 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2472 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2473 unsigned align = fieldFromInstruction32(Insn, 4, 1);
2474 unsigned size = fieldFromInstruction32(Insn, 6, 2);
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002475
2476 align *= (1 << size);
2477
Owen Andersona6804442011-09-01 23:23:50 +00002478 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2479 return MCDisassembler::Fail;
Owen Andersonf1c8e3e2011-08-22 18:22:06 +00002480 if (Rm != 0xF) {
Owen Andersona6804442011-09-01 23:23:50 +00002481 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2482 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002483 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002484
Owen Andersona6804442011-09-01 23:23:50 +00002485 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2486 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002487 Inst.addOperand(MCOperand::CreateImm(align));
2488
Jim Grosbach096334e2011-11-30 19:35:44 +00002489 // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2490 // variant encodes Rm == 0xf. Anything else is a register offset post-
2491 // increment and we need to add the register operand to the instruction.
2492 if (Rm != 0xD && Rm != 0xF &&
2493 !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2494 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002495
Owen Anderson83e3f672011-08-17 17:44:15 +00002496 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002497}
2498
Owen Andersona6804442011-09-01 23:23:50 +00002499static DecodeStatus DecodeVLD2DupInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002500 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002501 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002502
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002503 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2504 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2505 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2506 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2507 unsigned align = fieldFromInstruction32(Insn, 4, 1);
2508 unsigned size = 1 << fieldFromInstruction32(Insn, 6, 2);
2509 unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
2510 align *= 2*size;
2511
Owen Andersona6804442011-09-01 23:23:50 +00002512 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2513 return MCDisassembler::Fail;
2514 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2515 return MCDisassembler::Fail;
Owen Andersonf1c8e3e2011-08-22 18:22:06 +00002516 if (Rm != 0xF) {
Owen Andersona6804442011-09-01 23:23:50 +00002517 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2518 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002519 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002520
Owen Andersona6804442011-09-01 23:23:50 +00002521 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2522 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002523 Inst.addOperand(MCOperand::CreateImm(align));
2524
2525 if (Rm == 0xD)
2526 Inst.addOperand(MCOperand::CreateReg(0));
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002527 else if (Rm != 0xF) {
Owen Andersona6804442011-09-01 23:23:50 +00002528 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2529 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002530 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002531
Owen Anderson83e3f672011-08-17 17:44:15 +00002532 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002533}
2534
Owen Andersona6804442011-09-01 23:23:50 +00002535static DecodeStatus DecodeVLD3DupInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002536 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002537 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002538
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002539 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2540 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2541 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2542 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2543 unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
2544
Owen Andersona6804442011-09-01 23:23:50 +00002545 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2546 return MCDisassembler::Fail;
2547 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2548 return MCDisassembler::Fail;
2549 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2550 return MCDisassembler::Fail;
Owen Andersonf1c8e3e2011-08-22 18:22:06 +00002551 if (Rm != 0xF) {
Owen Andersona6804442011-09-01 23:23:50 +00002552 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2553 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002554 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002555
Owen Andersona6804442011-09-01 23:23:50 +00002556 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2557 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002558 Inst.addOperand(MCOperand::CreateImm(0));
2559
2560 if (Rm == 0xD)
2561 Inst.addOperand(MCOperand::CreateReg(0));
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002562 else if (Rm != 0xF) {
Owen Andersona6804442011-09-01 23:23:50 +00002563 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2564 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002565 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002566
Owen Anderson83e3f672011-08-17 17:44:15 +00002567 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002568}
2569
Owen Andersona6804442011-09-01 23:23:50 +00002570static DecodeStatus DecodeVLD4DupInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002571 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002572 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002573
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002574 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2575 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2576 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2577 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2578 unsigned size = fieldFromInstruction32(Insn, 6, 2);
2579 unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
2580 unsigned align = fieldFromInstruction32(Insn, 4, 1);
2581
2582 if (size == 0x3) {
2583 size = 4;
2584 align = 16;
2585 } else {
2586 if (size == 2) {
2587 size = 1 << size;
2588 align *= 8;
2589 } else {
2590 size = 1 << size;
2591 align *= 4*size;
2592 }
2593 }
2594
Owen Andersona6804442011-09-01 23:23:50 +00002595 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2596 return MCDisassembler::Fail;
2597 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2598 return MCDisassembler::Fail;
2599 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2600 return MCDisassembler::Fail;
2601 if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
2602 return MCDisassembler::Fail;
Owen Andersonf1c8e3e2011-08-22 18:22:06 +00002603 if (Rm != 0xF) {
Owen Andersona6804442011-09-01 23:23:50 +00002604 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2605 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002606 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002607
Owen Andersona6804442011-09-01 23:23:50 +00002608 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2609 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002610 Inst.addOperand(MCOperand::CreateImm(align));
2611
2612 if (Rm == 0xD)
2613 Inst.addOperand(MCOperand::CreateReg(0));
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002614 else if (Rm != 0xF) {
Owen Andersona6804442011-09-01 23:23:50 +00002615 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2616 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002617 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002618
Owen Anderson83e3f672011-08-17 17:44:15 +00002619 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002620}
2621
Owen Andersona6804442011-09-01 23:23:50 +00002622static DecodeStatus
Jim Grosbachc4057822011-08-17 21:58:18 +00002623DecodeNEONModImmInstruction(llvm::MCInst &Inst, unsigned Insn,
2624 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002625 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002626
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002627 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2628 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2629 unsigned imm = fieldFromInstruction32(Insn, 0, 4);
2630 imm |= fieldFromInstruction32(Insn, 16, 3) << 4;
2631 imm |= fieldFromInstruction32(Insn, 24, 1) << 7;
2632 imm |= fieldFromInstruction32(Insn, 8, 4) << 8;
2633 imm |= fieldFromInstruction32(Insn, 5, 1) << 12;
2634 unsigned Q = fieldFromInstruction32(Insn, 6, 1);
2635
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002636 if (Q) {
Owen Andersona6804442011-09-01 23:23:50 +00002637 if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
2638 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002639 } else {
Owen Andersona6804442011-09-01 23:23:50 +00002640 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2641 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002642 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002643
2644 Inst.addOperand(MCOperand::CreateImm(imm));
2645
2646 switch (Inst.getOpcode()) {
2647 case ARM::VORRiv4i16:
2648 case ARM::VORRiv2i32:
2649 case ARM::VBICiv4i16:
2650 case ARM::VBICiv2i32:
Owen Andersona6804442011-09-01 23:23:50 +00002651 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2652 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002653 break;
2654 case ARM::VORRiv8i16:
2655 case ARM::VORRiv4i32:
2656 case ARM::VBICiv8i16:
2657 case ARM::VBICiv4i32:
Owen Andersona6804442011-09-01 23:23:50 +00002658 if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
2659 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002660 break;
2661 default:
2662 break;
2663 }
2664
Owen Anderson83e3f672011-08-17 17:44:15 +00002665 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002666}
2667
Owen Andersona6804442011-09-01 23:23:50 +00002668static DecodeStatus DecodeVSHLMaxInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002669 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002670 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002671
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002672 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2673 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2674 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2675 Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
2676 unsigned size = fieldFromInstruction32(Insn, 18, 2);
2677
Owen Andersona6804442011-09-01 23:23:50 +00002678 if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
2679 return MCDisassembler::Fail;
2680 if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
2681 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002682 Inst.addOperand(MCOperand::CreateImm(8 << size));
2683
Owen Anderson83e3f672011-08-17 17:44:15 +00002684 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002685}
2686
Owen Andersona6804442011-09-01 23:23:50 +00002687static DecodeStatus DecodeShiftRight8Imm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002688 uint64_t Address, const void *Decoder) {
2689 Inst.addOperand(MCOperand::CreateImm(8 - Val));
James Molloyc047dca2011-09-01 18:02:14 +00002690 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002691}
2692
Owen Andersona6804442011-09-01 23:23:50 +00002693static DecodeStatus DecodeShiftRight16Imm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002694 uint64_t Address, const void *Decoder) {
2695 Inst.addOperand(MCOperand::CreateImm(16 - Val));
James Molloyc047dca2011-09-01 18:02:14 +00002696 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002697}
2698
Owen Andersona6804442011-09-01 23:23:50 +00002699static DecodeStatus DecodeShiftRight32Imm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002700 uint64_t Address, const void *Decoder) {
2701 Inst.addOperand(MCOperand::CreateImm(32 - Val));
James Molloyc047dca2011-09-01 18:02:14 +00002702 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002703}
2704
Owen Andersona6804442011-09-01 23:23:50 +00002705static DecodeStatus DecodeShiftRight64Imm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002706 uint64_t Address, const void *Decoder) {
2707 Inst.addOperand(MCOperand::CreateImm(64 - Val));
James Molloyc047dca2011-09-01 18:02:14 +00002708 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002709}
2710
Owen Andersona6804442011-09-01 23:23:50 +00002711static DecodeStatus DecodeTBLInstruction(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002712 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002713 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002714
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002715 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
2716 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
2717 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2718 Rn |= fieldFromInstruction32(Insn, 7, 1) << 4;
2719 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
2720 Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
2721 unsigned op = fieldFromInstruction32(Insn, 6, 1);
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002722
Owen Andersona6804442011-09-01 23:23:50 +00002723 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2724 return MCDisassembler::Fail;
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002725 if (op) {
Owen Andersona6804442011-09-01 23:23:50 +00002726 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2727 return MCDisassembler::Fail; // Writeback
Owen Andersonae0bc5d2011-08-11 18:24:51 +00002728 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002729
Jim Grosbach28f08c92012-03-05 19:33:30 +00002730 switch (Inst.getOpcode()) {
2731 case ARM::VTBL2:
2732 case ARM::VTBX2:
2733 if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
2734 return MCDisassembler::Fail;
2735 break;
2736 default:
2737 if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
2738 return MCDisassembler::Fail;
2739 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002740
Owen Andersona6804442011-09-01 23:23:50 +00002741 if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
2742 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002743
Owen Anderson83e3f672011-08-17 17:44:15 +00002744 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002745}
2746
Owen Andersona6804442011-09-01 23:23:50 +00002747static DecodeStatus DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002748 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002749 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002750
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002751 unsigned dst = fieldFromInstruction16(Insn, 8, 3);
2752 unsigned imm = fieldFromInstruction16(Insn, 0, 8);
2753
Owen Andersona6804442011-09-01 23:23:50 +00002754 if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
2755 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002756
Owen Anderson96425c82011-08-26 18:09:22 +00002757 switch(Inst.getOpcode()) {
Owen Anderson1af7f722011-08-26 19:39:26 +00002758 default:
James Molloyc047dca2011-09-01 18:02:14 +00002759 return MCDisassembler::Fail;
Owen Anderson96425c82011-08-26 18:09:22 +00002760 case ARM::tADR:
Owen Anderson9f7e8312011-08-26 21:47:57 +00002761 break; // tADR does not explicitly represent the PC as an operand.
Owen Anderson96425c82011-08-26 18:09:22 +00002762 case ARM::tADDrSPi:
2763 Inst.addOperand(MCOperand::CreateReg(ARM::SP));
2764 break;
Owen Anderson96425c82011-08-26 18:09:22 +00002765 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002766
2767 Inst.addOperand(MCOperand::CreateImm(imm));
Owen Anderson83e3f672011-08-17 17:44:15 +00002768 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002769}
2770
Owen Andersona6804442011-09-01 23:23:50 +00002771static DecodeStatus DecodeThumbBROperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002772 uint64_t Address, const void *Decoder) {
2773 Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
James Molloyc047dca2011-09-01 18:02:14 +00002774 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002775}
2776
Owen Andersona6804442011-09-01 23:23:50 +00002777static DecodeStatus DecodeT2BROperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002778 uint64_t Address, const void *Decoder) {
2779 Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
James Molloyc047dca2011-09-01 18:02:14 +00002780 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002781}
2782
Owen Andersona6804442011-09-01 23:23:50 +00002783static DecodeStatus DecodeThumbCmpBROperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002784 uint64_t Address, const void *Decoder) {
2785 Inst.addOperand(MCOperand::CreateImm(SignExtend32<7>(Val << 1)));
James Molloyc047dca2011-09-01 18:02:14 +00002786 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002787}
2788
Owen Andersona6804442011-09-01 23:23:50 +00002789static DecodeStatus DecodeThumbAddrModeRR(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002790 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002791 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002792
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002793 unsigned Rn = fieldFromInstruction32(Val, 0, 3);
2794 unsigned Rm = fieldFromInstruction32(Val, 3, 3);
2795
Owen Andersona6804442011-09-01 23:23:50 +00002796 if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
2797 return MCDisassembler::Fail;
2798 if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
2799 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002800
Owen Anderson83e3f672011-08-17 17:44:15 +00002801 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002802}
2803
Owen Andersona6804442011-09-01 23:23:50 +00002804static DecodeStatus DecodeThumbAddrModeIS(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002805 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002806 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002807
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002808 unsigned Rn = fieldFromInstruction32(Val, 0, 3);
2809 unsigned imm = fieldFromInstruction32(Val, 3, 5);
2810
Owen Andersona6804442011-09-01 23:23:50 +00002811 if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
2812 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002813 Inst.addOperand(MCOperand::CreateImm(imm));
2814
Owen Anderson83e3f672011-08-17 17:44:15 +00002815 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002816}
2817
Owen Andersona6804442011-09-01 23:23:50 +00002818static DecodeStatus DecodeThumbAddrModePC(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002819 uint64_t Address, const void *Decoder) {
Kevin Enderby9e5887b2011-10-04 22:44:48 +00002820 unsigned imm = Val << 2;
2821
2822 Inst.addOperand(MCOperand::CreateImm(imm));
2823 tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002824
James Molloyc047dca2011-09-01 18:02:14 +00002825 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002826}
2827
Owen Andersona6804442011-09-01 23:23:50 +00002828static DecodeStatus DecodeThumbAddrModeSP(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002829 uint64_t Address, const void *Decoder) {
2830 Inst.addOperand(MCOperand::CreateReg(ARM::SP));
Owen Andersonb113ec52011-08-22 17:56:58 +00002831 Inst.addOperand(MCOperand::CreateImm(Val));
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002832
James Molloyc047dca2011-09-01 18:02:14 +00002833 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002834}
2835
Owen Andersona6804442011-09-01 23:23:50 +00002836static DecodeStatus DecodeT2AddrModeSOReg(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002837 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002838 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002839
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002840 unsigned Rn = fieldFromInstruction32(Val, 6, 4);
2841 unsigned Rm = fieldFromInstruction32(Val, 2, 4);
2842 unsigned imm = fieldFromInstruction32(Val, 0, 2);
2843
Owen Andersona6804442011-09-01 23:23:50 +00002844 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2845 return MCDisassembler::Fail;
2846 if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
2847 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002848 Inst.addOperand(MCOperand::CreateImm(imm));
2849
Owen Anderson83e3f672011-08-17 17:44:15 +00002850 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002851}
2852
Owen Andersona6804442011-09-01 23:23:50 +00002853static DecodeStatus DecodeT2LoadShift(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002854 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002855 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002856
Owen Anderson82265a22011-08-23 17:51:38 +00002857 switch (Inst.getOpcode()) {
2858 case ARM::t2PLDs:
2859 case ARM::t2PLDWs:
2860 case ARM::t2PLIs:
2861 break;
2862 default: {
2863 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
Owen Anderson31d485e2011-09-23 21:07:25 +00002864 if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
Owen Andersona6804442011-09-01 23:23:50 +00002865 return MCDisassembler::Fail;
Owen Anderson82265a22011-08-23 17:51:38 +00002866 }
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002867 }
2868
2869 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2870 if (Rn == 0xF) {
2871 switch (Inst.getOpcode()) {
2872 case ARM::t2LDRBs:
2873 Inst.setOpcode(ARM::t2LDRBpci);
2874 break;
2875 case ARM::t2LDRHs:
2876 Inst.setOpcode(ARM::t2LDRHpci);
2877 break;
2878 case ARM::t2LDRSHs:
2879 Inst.setOpcode(ARM::t2LDRSHpci);
2880 break;
2881 case ARM::t2LDRSBs:
2882 Inst.setOpcode(ARM::t2LDRSBpci);
2883 break;
2884 case ARM::t2PLDs:
2885 Inst.setOpcode(ARM::t2PLDi12);
2886 Inst.addOperand(MCOperand::CreateReg(ARM::PC));
2887 break;
2888 default:
James Molloyc047dca2011-09-01 18:02:14 +00002889 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002890 }
2891
2892 int imm = fieldFromInstruction32(Insn, 0, 12);
2893 if (!fieldFromInstruction32(Insn, 23, 1)) imm *= -1;
2894 Inst.addOperand(MCOperand::CreateImm(imm));
2895
Owen Anderson83e3f672011-08-17 17:44:15 +00002896 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002897 }
2898
2899 unsigned addrmode = fieldFromInstruction32(Insn, 4, 2);
2900 addrmode |= fieldFromInstruction32(Insn, 0, 4) << 2;
2901 addrmode |= fieldFromInstruction32(Insn, 16, 4) << 6;
Owen Andersona6804442011-09-01 23:23:50 +00002902 if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
2903 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002904
Owen Anderson83e3f672011-08-17 17:44:15 +00002905 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002906}
2907
Owen Andersona6804442011-09-01 23:23:50 +00002908static DecodeStatus DecodeT2Imm8S4(llvm::MCInst &Inst, unsigned Val,
Owen Anderson10cbaab2011-08-10 17:36:48 +00002909 uint64_t Address, const void *Decoder) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002910 int imm = Val & 0xFF;
2911 if (!(Val & 0x100)) imm *= -1;
2912 Inst.addOperand(MCOperand::CreateImm(imm << 2));
2913
James Molloyc047dca2011-09-01 18:02:14 +00002914 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002915}
2916
Owen Andersona6804442011-09-01 23:23:50 +00002917static DecodeStatus DecodeT2AddrModeImm8s4(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002918 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002919 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002920
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002921 unsigned Rn = fieldFromInstruction32(Val, 9, 4);
2922 unsigned imm = fieldFromInstruction32(Val, 0, 9);
2923
Owen Andersona6804442011-09-01 23:23:50 +00002924 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2925 return MCDisassembler::Fail;
2926 if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
2927 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002928
Owen Anderson83e3f672011-08-17 17:44:15 +00002929 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002930}
2931
Jim Grosbachb6aed502011-09-09 18:37:27 +00002932static DecodeStatus DecodeT2AddrModeImm0_1020s4(llvm::MCInst &Inst,unsigned Val,
2933 uint64_t Address, const void *Decoder) {
2934 DecodeStatus S = MCDisassembler::Success;
2935
2936 unsigned Rn = fieldFromInstruction32(Val, 8, 4);
2937 unsigned imm = fieldFromInstruction32(Val, 0, 8);
2938
2939 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2940 return MCDisassembler::Fail;
2941
2942 Inst.addOperand(MCOperand::CreateImm(imm));
2943
2944 return S;
2945}
2946
Owen Andersona6804442011-09-01 23:23:50 +00002947static DecodeStatus DecodeT2Imm8(llvm::MCInst &Inst, unsigned Val,
Owen Anderson10cbaab2011-08-10 17:36:48 +00002948 uint64_t Address, const void *Decoder) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002949 int imm = Val & 0xFF;
Owen Anderson705b48f2011-09-16 21:08:33 +00002950 if (Val == 0)
2951 imm = INT32_MIN;
2952 else if (!(Val & 0x100))
2953 imm *= -1;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002954 Inst.addOperand(MCOperand::CreateImm(imm));
2955
James Molloyc047dca2011-09-01 18:02:14 +00002956 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002957}
2958
2959
Owen Andersona6804442011-09-01 23:23:50 +00002960static DecodeStatus DecodeT2AddrModeImm8(llvm::MCInst &Inst, unsigned Val,
Owen Anderson10cbaab2011-08-10 17:36:48 +00002961 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00002962 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00002963
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002964 unsigned Rn = fieldFromInstruction32(Val, 9, 4);
2965 unsigned imm = fieldFromInstruction32(Val, 0, 9);
2966
2967 // Some instructions always use an additive offset.
2968 switch (Inst.getOpcode()) {
2969 case ARM::t2LDRT:
2970 case ARM::t2LDRBT:
2971 case ARM::t2LDRHT:
2972 case ARM::t2LDRSBT:
2973 case ARM::t2LDRSHT:
Owen Andersonecd1c552011-09-19 18:07:10 +00002974 case ARM::t2STRT:
2975 case ARM::t2STRBT:
2976 case ARM::t2STRHT:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002977 imm |= 0x100;
2978 break;
2979 default:
2980 break;
2981 }
2982
Owen Andersona6804442011-09-01 23:23:50 +00002983 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2984 return MCDisassembler::Fail;
2985 if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
2986 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002987
Owen Anderson83e3f672011-08-17 17:44:15 +00002988 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00002989}
2990
Owen Andersona3157b42011-09-12 18:56:30 +00002991static DecodeStatus DecodeT2LdStPre(llvm::MCInst &Inst, unsigned Insn,
2992 uint64_t Address, const void *Decoder) {
2993 DecodeStatus S = MCDisassembler::Success;
2994
2995 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
2996 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
2997 unsigned addr = fieldFromInstruction32(Insn, 0, 8);
2998 addr |= fieldFromInstruction32(Insn, 9, 1) << 8;
2999 addr |= Rn << 9;
3000 unsigned load = fieldFromInstruction32(Insn, 20, 1);
3001
3002 if (!load) {
3003 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3004 return MCDisassembler::Fail;
3005 }
3006
Owen Andersone4f2df92011-09-16 22:42:36 +00003007 if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
Owen Andersona3157b42011-09-12 18:56:30 +00003008 return MCDisassembler::Fail;
3009
3010 if (load) {
3011 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3012 return MCDisassembler::Fail;
3013 }
3014
3015 if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
3016 return MCDisassembler::Fail;
3017
3018 return S;
3019}
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003020
Owen Andersona6804442011-09-01 23:23:50 +00003021static DecodeStatus DecodeT2AddrModeImm12(llvm::MCInst &Inst, unsigned Val,
Owen Anderson10cbaab2011-08-10 17:36:48 +00003022 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003023 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003024
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003025 unsigned Rn = fieldFromInstruction32(Val, 13, 4);
3026 unsigned imm = fieldFromInstruction32(Val, 0, 12);
3027
Owen Andersona6804442011-09-01 23:23:50 +00003028 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3029 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003030 Inst.addOperand(MCOperand::CreateImm(imm));
3031
Owen Anderson83e3f672011-08-17 17:44:15 +00003032 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003033}
3034
3035
Owen Andersona6804442011-09-01 23:23:50 +00003036static DecodeStatus DecodeThumbAddSPImm(llvm::MCInst &Inst, uint16_t Insn,
Owen Anderson10cbaab2011-08-10 17:36:48 +00003037 uint64_t Address, const void *Decoder) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003038 unsigned imm = fieldFromInstruction16(Insn, 0, 7);
3039
3040 Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3041 Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3042 Inst.addOperand(MCOperand::CreateImm(imm));
3043
James Molloyc047dca2011-09-01 18:02:14 +00003044 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003045}
3046
Owen Andersona6804442011-09-01 23:23:50 +00003047static DecodeStatus DecodeThumbAddSPReg(llvm::MCInst &Inst, uint16_t Insn,
Owen Anderson10cbaab2011-08-10 17:36:48 +00003048 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003049 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003050
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003051 if (Inst.getOpcode() == ARM::tADDrSP) {
3052 unsigned Rdm = fieldFromInstruction16(Insn, 0, 3);
3053 Rdm |= fieldFromInstruction16(Insn, 7, 1) << 3;
3054
Owen Andersona6804442011-09-01 23:23:50 +00003055 if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3056 return MCDisassembler::Fail;
3057 if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3058 return MCDisassembler::Fail;
Owen Anderson99906832011-08-25 18:30:18 +00003059 Inst.addOperand(MCOperand::CreateReg(ARM::SP));
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003060 } else if (Inst.getOpcode() == ARM::tADDspr) {
3061 unsigned Rm = fieldFromInstruction16(Insn, 3, 4);
3062
3063 Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3064 Inst.addOperand(MCOperand::CreateReg(ARM::SP));
Owen Andersona6804442011-09-01 23:23:50 +00003065 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3066 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003067 }
3068
Owen Anderson83e3f672011-08-17 17:44:15 +00003069 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003070}
3071
Owen Andersona6804442011-09-01 23:23:50 +00003072static DecodeStatus DecodeThumbCPS(llvm::MCInst &Inst, uint16_t Insn,
Owen Anderson10cbaab2011-08-10 17:36:48 +00003073 uint64_t Address, const void *Decoder) {
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003074 unsigned imod = fieldFromInstruction16(Insn, 4, 1) | 0x2;
3075 unsigned flags = fieldFromInstruction16(Insn, 0, 3);
3076
3077 Inst.addOperand(MCOperand::CreateImm(imod));
3078 Inst.addOperand(MCOperand::CreateImm(flags));
3079
James Molloyc047dca2011-09-01 18:02:14 +00003080 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003081}
3082
Owen Andersona6804442011-09-01 23:23:50 +00003083static DecodeStatus DecodePostIdxReg(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson10cbaab2011-08-10 17:36:48 +00003084 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003085 DecodeStatus S = MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003086 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3087 unsigned add = fieldFromInstruction32(Insn, 4, 1);
3088
Owen Andersona6804442011-09-01 23:23:50 +00003089 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3090 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003091 Inst.addOperand(MCOperand::CreateImm(add));
3092
Owen Anderson83e3f672011-08-17 17:44:15 +00003093 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003094}
3095
Owen Andersona6804442011-09-01 23:23:50 +00003096static DecodeStatus DecodeThumbBLXOffset(llvm::MCInst &Inst, unsigned Val,
Owen Anderson10cbaab2011-08-10 17:36:48 +00003097 uint64_t Address, const void *Decoder) {
Jim Grosbach01817c32011-10-20 17:28:20 +00003098 if (!tryAddingSymbolicOperand(Address,
Kevin Enderby9e5887b2011-10-04 22:44:48 +00003099 (Address & ~2u) + SignExtend32<22>(Val << 1) + 4,
3100 true, 4, Inst, Decoder))
3101 Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
James Molloyc047dca2011-09-01 18:02:14 +00003102 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003103}
3104
Owen Andersona6804442011-09-01 23:23:50 +00003105static DecodeStatus DecodeCoprocessor(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003106 uint64_t Address, const void *Decoder) {
3107 if (Val == 0xA || Val == 0xB)
James Molloyc047dca2011-09-01 18:02:14 +00003108 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003109
3110 Inst.addOperand(MCOperand::CreateImm(Val));
James Molloyc047dca2011-09-01 18:02:14 +00003111 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003112}
3113
Owen Andersona6804442011-09-01 23:23:50 +00003114static DecodeStatus
Jim Grosbach7f739be2011-09-19 22:21:13 +00003115DecodeThumbTableBranch(llvm::MCInst &Inst, unsigned Insn,
3116 uint64_t Address, const void *Decoder) {
3117 DecodeStatus S = MCDisassembler::Success;
3118
3119 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3120 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3121
3122 if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
3123 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3124 return MCDisassembler::Fail;
3125 if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3126 return MCDisassembler::Fail;
3127 return S;
3128}
3129
3130static DecodeStatus
Jim Grosbachc4057822011-08-17 21:58:18 +00003131DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Insn,
3132 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003133 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003134
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003135 unsigned pred = fieldFromInstruction32(Insn, 22, 4);
3136 if (pred == 0xE || pred == 0xF) {
Owen Andersonb45b11b2011-08-31 22:00:41 +00003137 unsigned opc = fieldFromInstruction32(Insn, 4, 28);
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003138 switch (opc) {
3139 default:
James Molloyc047dca2011-09-01 18:02:14 +00003140 return MCDisassembler::Fail;
Owen Andersonb45b11b2011-08-31 22:00:41 +00003141 case 0xf3bf8f4:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003142 Inst.setOpcode(ARM::t2DSB);
3143 break;
Owen Andersonb45b11b2011-08-31 22:00:41 +00003144 case 0xf3bf8f5:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003145 Inst.setOpcode(ARM::t2DMB);
3146 break;
Owen Andersonb45b11b2011-08-31 22:00:41 +00003147 case 0xf3bf8f6:
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003148 Inst.setOpcode(ARM::t2ISB);
Owen Anderson6de3c6f2011-09-07 17:55:19 +00003149 break;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003150 }
3151
3152 unsigned imm = fieldFromInstruction32(Insn, 0, 4);
Owen Andersonc36481c2011-08-09 23:25:42 +00003153 return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003154 }
3155
3156 unsigned brtarget = fieldFromInstruction32(Insn, 0, 11) << 1;
3157 brtarget |= fieldFromInstruction32(Insn, 11, 1) << 19;
3158 brtarget |= fieldFromInstruction32(Insn, 13, 1) << 18;
3159 brtarget |= fieldFromInstruction32(Insn, 16, 6) << 12;
3160 brtarget |= fieldFromInstruction32(Insn, 26, 1) << 20;
3161
Owen Andersona6804442011-09-01 23:23:50 +00003162 if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
3163 return MCDisassembler::Fail;
3164 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3165 return MCDisassembler::Fail;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003166
Owen Anderson83e3f672011-08-17 17:44:15 +00003167 return S;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003168}
3169
3170// Decode a shifted immediate operand. These basically consist
3171// of an 8-bit value, and a 4-bit directive that specifies either
3172// a splat operation or a rotation.
Owen Andersona6804442011-09-01 23:23:50 +00003173static DecodeStatus DecodeT2SOImm(llvm::MCInst &Inst, unsigned Val,
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003174 uint64_t Address, const void *Decoder) {
3175 unsigned ctrl = fieldFromInstruction32(Val, 10, 2);
3176 if (ctrl == 0) {
3177 unsigned byte = fieldFromInstruction32(Val, 8, 2);
3178 unsigned imm = fieldFromInstruction32(Val, 0, 8);
3179 switch (byte) {
3180 case 0:
3181 Inst.addOperand(MCOperand::CreateImm(imm));
3182 break;
3183 case 1:
3184 Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm));
3185 break;
3186 case 2:
3187 Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8)));
3188 break;
3189 case 3:
3190 Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) |
3191 (imm << 8) | imm));
3192 break;
3193 }
3194 } else {
3195 unsigned unrot = fieldFromInstruction32(Val, 0, 7) | 0x80;
3196 unsigned rot = fieldFromInstruction32(Val, 7, 5);
3197 unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
3198 Inst.addOperand(MCOperand::CreateImm(imm));
3199 }
3200
James Molloyc047dca2011-09-01 18:02:14 +00003201 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003202}
3203
Owen Andersona6804442011-09-01 23:23:50 +00003204static DecodeStatus
Jim Grosbachc4057822011-08-17 21:58:18 +00003205DecodeThumbBCCTargetOperand(llvm::MCInst &Inst, unsigned Val,
3206 uint64_t Address, const void *Decoder){
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003207 Inst.addOperand(MCOperand::CreateImm(Val << 1));
James Molloyc047dca2011-09-01 18:02:14 +00003208 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003209}
3210
Owen Andersona6804442011-09-01 23:23:50 +00003211static DecodeStatus DecodeThumbBLTargetOperand(llvm::MCInst &Inst, unsigned Val,
Owen Anderson10cbaab2011-08-10 17:36:48 +00003212 uint64_t Address, const void *Decoder){
Kevin Enderby09433032012-02-27 18:15:15 +00003213 if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<22>(Val<<1) + 4,
Kevin Enderbyb80d5712012-02-23 18:18:17 +00003214 true, 4, Inst, Decoder))
3215 Inst.addOperand(MCOperand::CreateImm(SignExtend32<22>(Val << 1)));
James Molloyc047dca2011-09-01 18:02:14 +00003216 return MCDisassembler::Success;
Owen Anderson8d7d2e12011-08-09 20:55:18 +00003217}
3218
Owen Andersona6804442011-09-01 23:23:50 +00003219static DecodeStatus DecodeMemBarrierOption(llvm::MCInst &Inst, unsigned Val,
Owen Andersonc36481c2011-08-09 23:25:42 +00003220 uint64_t Address, const void *Decoder) {
3221 switch (Val) {
3222 default:
James Molloyc047dca2011-09-01 18:02:14 +00003223 return MCDisassembler::Fail;
Owen Andersonc36481c2011-08-09 23:25:42 +00003224 case 0xF: // SY
3225 case 0xE: // ST
3226 case 0xB: // ISH
3227 case 0xA: // ISHST
3228 case 0x7: // NSH
3229 case 0x6: // NSHST
3230 case 0x3: // OSH
3231 case 0x2: // OSHST
3232 break;
3233 }
3234
3235 Inst.addOperand(MCOperand::CreateImm(Val));
James Molloyc047dca2011-09-01 18:02:14 +00003236 return MCDisassembler::Success;
Owen Andersonc36481c2011-08-09 23:25:42 +00003237}
3238
Owen Andersona6804442011-09-01 23:23:50 +00003239static DecodeStatus DecodeMSRMask(llvm::MCInst &Inst, unsigned Val,
Owen Anderson26d2f0a2011-08-11 20:21:46 +00003240 uint64_t Address, const void *Decoder) {
James Molloyc047dca2011-09-01 18:02:14 +00003241 if (!Val) return MCDisassembler::Fail;
Owen Anderson26d2f0a2011-08-11 20:21:46 +00003242 Inst.addOperand(MCOperand::CreateImm(Val));
James Molloyc047dca2011-09-01 18:02:14 +00003243 return MCDisassembler::Success;
Owen Anderson26d2f0a2011-08-11 20:21:46 +00003244}
Owen Andersoncbfc0442011-08-11 21:34:58 +00003245
Owen Andersona6804442011-09-01 23:23:50 +00003246static DecodeStatus DecodeDoubleRegLoad(llvm::MCInst &Inst, unsigned Insn,
Jim Grosbachc4057822011-08-17 21:58:18 +00003247 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003248 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003249
Owen Anderson3f3570a2011-08-12 17:58:32 +00003250 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3251 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3252 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3253
James Molloyc047dca2011-09-01 18:02:14 +00003254 if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail;
Owen Anderson3f3570a2011-08-12 17:58:32 +00003255
Owen Andersona6804442011-09-01 23:23:50 +00003256 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3257 return MCDisassembler::Fail;
3258 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
3259 return MCDisassembler::Fail;
3260 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3261 return MCDisassembler::Fail;
3262 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3263 return MCDisassembler::Fail;
Owen Anderson3f3570a2011-08-12 17:58:32 +00003264
Owen Anderson83e3f672011-08-17 17:44:15 +00003265 return S;
Owen Anderson3f3570a2011-08-12 17:58:32 +00003266}
3267
3268
Owen Andersona6804442011-09-01 23:23:50 +00003269static DecodeStatus DecodeDoubleRegStore(llvm::MCInst &Inst, unsigned Insn,
Jim Grosbachc4057822011-08-17 21:58:18 +00003270 uint64_t Address, const void *Decoder){
Owen Andersona6804442011-09-01 23:23:50 +00003271 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003272
Owen Andersoncbfc0442011-08-11 21:34:58 +00003273 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3274 unsigned Rt = fieldFromInstruction32(Insn, 0, 4);
3275 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
Owen Andersonadf2b092011-08-11 22:08:38 +00003276 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
Owen Andersoncbfc0442011-08-11 21:34:58 +00003277
Owen Andersona6804442011-09-01 23:23:50 +00003278 if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
3279 return MCDisassembler::Fail;
Owen Andersoncbfc0442011-08-11 21:34:58 +00003280
James Molloyc047dca2011-09-01 18:02:14 +00003281 if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail;
3282 if (Rd == Rn || Rd == Rt || Rd == Rt+1) return MCDisassembler::Fail;
Owen Andersoncbfc0442011-08-11 21:34:58 +00003283
Owen Andersona6804442011-09-01 23:23:50 +00003284 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3285 return MCDisassembler::Fail;
3286 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
3287 return MCDisassembler::Fail;
3288 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3289 return MCDisassembler::Fail;
3290 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3291 return MCDisassembler::Fail;
Owen Andersoncbfc0442011-08-11 21:34:58 +00003292
Owen Anderson83e3f672011-08-17 17:44:15 +00003293 return S;
Owen Andersoncbfc0442011-08-11 21:34:58 +00003294}
3295
Owen Andersona6804442011-09-01 23:23:50 +00003296static DecodeStatus DecodeLDRPreImm(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson9ab0f252011-08-26 20:43:14 +00003297 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003298 DecodeStatus S = MCDisassembler::Success;
Owen Anderson9ab0f252011-08-26 20:43:14 +00003299
3300 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3301 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3302 unsigned imm = fieldFromInstruction32(Insn, 0, 12);
3303 imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
3304 imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
3305 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3306
James Molloyc047dca2011-09-01 18:02:14 +00003307 if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
Owen Anderson9ab0f252011-08-26 20:43:14 +00003308
Owen Andersona6804442011-09-01 23:23:50 +00003309 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3310 return MCDisassembler::Fail;
3311 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3312 return MCDisassembler::Fail;
3313 if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
3314 return MCDisassembler::Fail;
3315 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3316 return MCDisassembler::Fail;
Owen Anderson9ab0f252011-08-26 20:43:14 +00003317
3318 return S;
3319}
3320
Owen Andersona6804442011-09-01 23:23:50 +00003321static DecodeStatus DecodeLDRPreReg(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson9ab0f252011-08-26 20:43:14 +00003322 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003323 DecodeStatus S = MCDisassembler::Success;
Owen Anderson9ab0f252011-08-26 20:43:14 +00003324
3325 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3326 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3327 unsigned imm = fieldFromInstruction32(Insn, 0, 12);
3328 imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
3329 imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
3330 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3331 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3332
James Molloyc047dca2011-09-01 18:02:14 +00003333 if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
3334 if (Rm == 0xF) S = MCDisassembler::SoftFail;
Owen Anderson9ab0f252011-08-26 20:43:14 +00003335
Owen Andersona6804442011-09-01 23:23:50 +00003336 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3337 return MCDisassembler::Fail;
3338 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3339 return MCDisassembler::Fail;
3340 if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
3341 return MCDisassembler::Fail;
3342 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3343 return MCDisassembler::Fail;
Owen Anderson9ab0f252011-08-26 20:43:14 +00003344
3345 return S;
3346}
3347
3348
Owen Andersona6804442011-09-01 23:23:50 +00003349static DecodeStatus DecodeSTRPreImm(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7cdbf082011-08-12 18:12:39 +00003350 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003351 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003352
Owen Anderson7cdbf082011-08-12 18:12:39 +00003353 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3354 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3355 unsigned imm = fieldFromInstruction32(Insn, 0, 12);
3356 imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
3357 imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
3358 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
Owen Andersoncbfc0442011-08-11 21:34:58 +00003359
James Molloyc047dca2011-09-01 18:02:14 +00003360 if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
Owen Anderson7cdbf082011-08-12 18:12:39 +00003361
Owen Andersona6804442011-09-01 23:23:50 +00003362 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3363 return MCDisassembler::Fail;
3364 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3365 return MCDisassembler::Fail;
3366 if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
3367 return MCDisassembler::Fail;
3368 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3369 return MCDisassembler::Fail;
Owen Anderson7cdbf082011-08-12 18:12:39 +00003370
Owen Anderson83e3f672011-08-17 17:44:15 +00003371 return S;
Owen Anderson7cdbf082011-08-12 18:12:39 +00003372}
3373
Owen Andersona6804442011-09-01 23:23:50 +00003374static DecodeStatus DecodeSTRPreReg(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7cdbf082011-08-12 18:12:39 +00003375 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003376 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003377
Owen Anderson7cdbf082011-08-12 18:12:39 +00003378 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3379 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3380 unsigned imm = fieldFromInstruction32(Insn, 0, 12);
3381 imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
3382 imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
3383 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3384
James Molloyc047dca2011-09-01 18:02:14 +00003385 if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
Owen Anderson7cdbf082011-08-12 18:12:39 +00003386
Owen Andersona6804442011-09-01 23:23:50 +00003387 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3388 return MCDisassembler::Fail;
3389 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3390 return MCDisassembler::Fail;
3391 if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
3392 return MCDisassembler::Fail;
3393 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3394 return MCDisassembler::Fail;
Owen Anderson7cdbf082011-08-12 18:12:39 +00003395
Owen Anderson83e3f672011-08-17 17:44:15 +00003396 return S;
Owen Anderson7cdbf082011-08-12 18:12:39 +00003397}
Owen Anderson7a2e1772011-08-15 18:44:44 +00003398
Owen Andersona6804442011-09-01 23:23:50 +00003399static DecodeStatus DecodeVLD1LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +00003400 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003401 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003402
Owen Anderson7a2e1772011-08-15 18:44:44 +00003403 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3404 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3405 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3406 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3407 unsigned size = fieldFromInstruction32(Insn, 10, 2);
3408
3409 unsigned align = 0;
3410 unsigned index = 0;
3411 switch (size) {
3412 default:
James Molloyc047dca2011-09-01 18:02:14 +00003413 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003414 case 0:
3415 if (fieldFromInstruction32(Insn, 4, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003416 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003417 index = fieldFromInstruction32(Insn, 5, 3);
3418 break;
3419 case 1:
3420 if (fieldFromInstruction32(Insn, 5, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003421 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003422 index = fieldFromInstruction32(Insn, 6, 2);
3423 if (fieldFromInstruction32(Insn, 4, 1))
3424 align = 2;
3425 break;
3426 case 2:
3427 if (fieldFromInstruction32(Insn, 6, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003428 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003429 index = fieldFromInstruction32(Insn, 7, 1);
3430 if (fieldFromInstruction32(Insn, 4, 2) != 0)
3431 align = 4;
3432 }
3433
Owen Andersona6804442011-09-01 23:23:50 +00003434 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3435 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003436 if (Rm != 0xF) { // Writeback
Owen Andersona6804442011-09-01 23:23:50 +00003437 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3438 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003439 }
Owen Andersona6804442011-09-01 23:23:50 +00003440 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3441 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003442 Inst.addOperand(MCOperand::CreateImm(align));
Owen Anderson2cbf2102011-08-22 18:42:13 +00003443 if (Rm != 0xF) {
James Molloyc047dca2011-09-01 18:02:14 +00003444 if (Rm != 0xD) {
Owen Andersona6804442011-09-01 23:23:50 +00003445 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3446 return MCDisassembler::Fail;
James Molloyc047dca2011-09-01 18:02:14 +00003447 } else
Owen Anderson2cbf2102011-08-22 18:42:13 +00003448 Inst.addOperand(MCOperand::CreateReg(0));
Owen Anderson7a2e1772011-08-15 18:44:44 +00003449 }
3450
Owen Andersona6804442011-09-01 23:23:50 +00003451 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3452 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003453 Inst.addOperand(MCOperand::CreateImm(index));
3454
Owen Anderson83e3f672011-08-17 17:44:15 +00003455 return S;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003456}
3457
Owen Andersona6804442011-09-01 23:23:50 +00003458static DecodeStatus DecodeVST1LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +00003459 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003460 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003461
Owen Anderson7a2e1772011-08-15 18:44:44 +00003462 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3463 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3464 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3465 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3466 unsigned size = fieldFromInstruction32(Insn, 10, 2);
3467
3468 unsigned align = 0;
3469 unsigned index = 0;
3470 switch (size) {
3471 default:
James Molloyc047dca2011-09-01 18:02:14 +00003472 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003473 case 0:
3474 if (fieldFromInstruction32(Insn, 4, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003475 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003476 index = fieldFromInstruction32(Insn, 5, 3);
3477 break;
3478 case 1:
3479 if (fieldFromInstruction32(Insn, 5, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003480 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003481 index = fieldFromInstruction32(Insn, 6, 2);
3482 if (fieldFromInstruction32(Insn, 4, 1))
3483 align = 2;
3484 break;
3485 case 2:
3486 if (fieldFromInstruction32(Insn, 6, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003487 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003488 index = fieldFromInstruction32(Insn, 7, 1);
3489 if (fieldFromInstruction32(Insn, 4, 2) != 0)
3490 align = 4;
3491 }
3492
3493 if (Rm != 0xF) { // Writeback
Owen Andersona6804442011-09-01 23:23:50 +00003494 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3495 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003496 }
Owen Andersona6804442011-09-01 23:23:50 +00003497 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3498 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003499 Inst.addOperand(MCOperand::CreateImm(align));
Owen Anderson2cbf2102011-08-22 18:42:13 +00003500 if (Rm != 0xF) {
James Molloyc047dca2011-09-01 18:02:14 +00003501 if (Rm != 0xD) {
Owen Andersona6804442011-09-01 23:23:50 +00003502 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3503 return MCDisassembler::Fail;
James Molloyc047dca2011-09-01 18:02:14 +00003504 } else
Owen Anderson2cbf2102011-08-22 18:42:13 +00003505 Inst.addOperand(MCOperand::CreateReg(0));
Owen Anderson7a2e1772011-08-15 18:44:44 +00003506 }
3507
Owen Andersona6804442011-09-01 23:23:50 +00003508 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3509 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003510 Inst.addOperand(MCOperand::CreateImm(index));
3511
Owen Anderson83e3f672011-08-17 17:44:15 +00003512 return S;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003513}
3514
3515
Owen Andersona6804442011-09-01 23:23:50 +00003516static DecodeStatus DecodeVLD2LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +00003517 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003518 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003519
Owen Anderson7a2e1772011-08-15 18:44:44 +00003520 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3521 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3522 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3523 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3524 unsigned size = fieldFromInstruction32(Insn, 10, 2);
3525
3526 unsigned align = 0;
3527 unsigned index = 0;
3528 unsigned inc = 1;
3529 switch (size) {
3530 default:
James Molloyc047dca2011-09-01 18:02:14 +00003531 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003532 case 0:
3533 index = fieldFromInstruction32(Insn, 5, 3);
3534 if (fieldFromInstruction32(Insn, 4, 1))
3535 align = 2;
3536 break;
3537 case 1:
3538 index = fieldFromInstruction32(Insn, 6, 2);
3539 if (fieldFromInstruction32(Insn, 4, 1))
3540 align = 4;
3541 if (fieldFromInstruction32(Insn, 5, 1))
3542 inc = 2;
3543 break;
3544 case 2:
3545 if (fieldFromInstruction32(Insn, 5, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003546 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003547 index = fieldFromInstruction32(Insn, 7, 1);
3548 if (fieldFromInstruction32(Insn, 4, 1) != 0)
3549 align = 8;
3550 if (fieldFromInstruction32(Insn, 6, 1))
3551 inc = 2;
3552 break;
3553 }
3554
Owen Andersona6804442011-09-01 23:23:50 +00003555 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3556 return MCDisassembler::Fail;
3557 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3558 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003559 if (Rm != 0xF) { // Writeback
Owen Andersona6804442011-09-01 23:23:50 +00003560 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3561 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003562 }
Owen Andersona6804442011-09-01 23:23:50 +00003563 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3564 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003565 Inst.addOperand(MCOperand::CreateImm(align));
Owen Anderson2cbf2102011-08-22 18:42:13 +00003566 if (Rm != 0xF) {
James Molloyc047dca2011-09-01 18:02:14 +00003567 if (Rm != 0xD) {
Owen Andersona6804442011-09-01 23:23:50 +00003568 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3569 return MCDisassembler::Fail;
James Molloyc047dca2011-09-01 18:02:14 +00003570 } else
Owen Anderson2cbf2102011-08-22 18:42:13 +00003571 Inst.addOperand(MCOperand::CreateReg(0));
Owen Anderson7a2e1772011-08-15 18:44:44 +00003572 }
3573
Owen Andersona6804442011-09-01 23:23:50 +00003574 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3575 return MCDisassembler::Fail;
3576 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3577 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003578 Inst.addOperand(MCOperand::CreateImm(index));
3579
Owen Anderson83e3f672011-08-17 17:44:15 +00003580 return S;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003581}
3582
Owen Andersona6804442011-09-01 23:23:50 +00003583static DecodeStatus DecodeVST2LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +00003584 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003585 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003586
Owen Anderson7a2e1772011-08-15 18:44:44 +00003587 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3588 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3589 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3590 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3591 unsigned size = fieldFromInstruction32(Insn, 10, 2);
3592
3593 unsigned align = 0;
3594 unsigned index = 0;
3595 unsigned inc = 1;
3596 switch (size) {
3597 default:
James Molloyc047dca2011-09-01 18:02:14 +00003598 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003599 case 0:
3600 index = fieldFromInstruction32(Insn, 5, 3);
3601 if (fieldFromInstruction32(Insn, 4, 1))
3602 align = 2;
3603 break;
3604 case 1:
3605 index = fieldFromInstruction32(Insn, 6, 2);
3606 if (fieldFromInstruction32(Insn, 4, 1))
3607 align = 4;
3608 if (fieldFromInstruction32(Insn, 5, 1))
3609 inc = 2;
3610 break;
3611 case 2:
3612 if (fieldFromInstruction32(Insn, 5, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003613 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003614 index = fieldFromInstruction32(Insn, 7, 1);
3615 if (fieldFromInstruction32(Insn, 4, 1) != 0)
3616 align = 8;
3617 if (fieldFromInstruction32(Insn, 6, 1))
3618 inc = 2;
3619 break;
3620 }
3621
3622 if (Rm != 0xF) { // Writeback
Owen Andersona6804442011-09-01 23:23:50 +00003623 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3624 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003625 }
Owen Andersona6804442011-09-01 23:23:50 +00003626 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3627 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003628 Inst.addOperand(MCOperand::CreateImm(align));
Owen Anderson2cbf2102011-08-22 18:42:13 +00003629 if (Rm != 0xF) {
James Molloyc047dca2011-09-01 18:02:14 +00003630 if (Rm != 0xD) {
Owen Andersona6804442011-09-01 23:23:50 +00003631 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3632 return MCDisassembler::Fail;
James Molloyc047dca2011-09-01 18:02:14 +00003633 } else
Owen Anderson2cbf2102011-08-22 18:42:13 +00003634 Inst.addOperand(MCOperand::CreateReg(0));
Owen Anderson7a2e1772011-08-15 18:44:44 +00003635 }
3636
Owen Andersona6804442011-09-01 23:23:50 +00003637 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3638 return MCDisassembler::Fail;
3639 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3640 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003641 Inst.addOperand(MCOperand::CreateImm(index));
3642
Owen Anderson83e3f672011-08-17 17:44:15 +00003643 return S;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003644}
3645
3646
Owen Andersona6804442011-09-01 23:23:50 +00003647static DecodeStatus DecodeVLD3LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +00003648 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003649 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003650
Owen Anderson7a2e1772011-08-15 18:44:44 +00003651 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3652 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3653 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3654 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3655 unsigned size = fieldFromInstruction32(Insn, 10, 2);
3656
3657 unsigned align = 0;
3658 unsigned index = 0;
3659 unsigned inc = 1;
3660 switch (size) {
3661 default:
James Molloyc047dca2011-09-01 18:02:14 +00003662 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003663 case 0:
3664 if (fieldFromInstruction32(Insn, 4, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003665 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003666 index = fieldFromInstruction32(Insn, 5, 3);
3667 break;
3668 case 1:
3669 if (fieldFromInstruction32(Insn, 4, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003670 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003671 index = fieldFromInstruction32(Insn, 6, 2);
3672 if (fieldFromInstruction32(Insn, 5, 1))
3673 inc = 2;
3674 break;
3675 case 2:
3676 if (fieldFromInstruction32(Insn, 4, 2))
James Molloyc047dca2011-09-01 18:02:14 +00003677 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003678 index = fieldFromInstruction32(Insn, 7, 1);
3679 if (fieldFromInstruction32(Insn, 6, 1))
3680 inc = 2;
3681 break;
3682 }
3683
Owen Andersona6804442011-09-01 23:23:50 +00003684 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3685 return MCDisassembler::Fail;
3686 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3687 return MCDisassembler::Fail;
3688 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
3689 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003690
3691 if (Rm != 0xF) { // Writeback
Owen Andersona6804442011-09-01 23:23:50 +00003692 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3693 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003694 }
Owen Andersona6804442011-09-01 23:23:50 +00003695 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3696 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003697 Inst.addOperand(MCOperand::CreateImm(align));
Owen Andersoneaca9282011-08-30 22:58:27 +00003698 if (Rm != 0xF) {
James Molloyc047dca2011-09-01 18:02:14 +00003699 if (Rm != 0xD) {
Owen Andersona6804442011-09-01 23:23:50 +00003700 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3701 return MCDisassembler::Fail;
James Molloyc047dca2011-09-01 18:02:14 +00003702 } else
Owen Anderson2cbf2102011-08-22 18:42:13 +00003703 Inst.addOperand(MCOperand::CreateReg(0));
Owen Anderson7a2e1772011-08-15 18:44:44 +00003704 }
3705
Owen Andersona6804442011-09-01 23:23:50 +00003706 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3707 return MCDisassembler::Fail;
3708 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3709 return MCDisassembler::Fail;
3710 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
3711 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003712 Inst.addOperand(MCOperand::CreateImm(index));
3713
Owen Anderson83e3f672011-08-17 17:44:15 +00003714 return S;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003715}
3716
Owen Andersona6804442011-09-01 23:23:50 +00003717static DecodeStatus DecodeVST3LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +00003718 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003719 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003720
Owen Anderson7a2e1772011-08-15 18:44:44 +00003721 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3722 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3723 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3724 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3725 unsigned size = fieldFromInstruction32(Insn, 10, 2);
3726
3727 unsigned align = 0;
3728 unsigned index = 0;
3729 unsigned inc = 1;
3730 switch (size) {
3731 default:
James Molloyc047dca2011-09-01 18:02:14 +00003732 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003733 case 0:
3734 if (fieldFromInstruction32(Insn, 4, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003735 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003736 index = fieldFromInstruction32(Insn, 5, 3);
3737 break;
3738 case 1:
3739 if (fieldFromInstruction32(Insn, 4, 1))
James Molloyc047dca2011-09-01 18:02:14 +00003740 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003741 index = fieldFromInstruction32(Insn, 6, 2);
3742 if (fieldFromInstruction32(Insn, 5, 1))
3743 inc = 2;
3744 break;
3745 case 2:
3746 if (fieldFromInstruction32(Insn, 4, 2))
James Molloyc047dca2011-09-01 18:02:14 +00003747 return MCDisassembler::Fail; // UNDEFINED
Owen Anderson7a2e1772011-08-15 18:44:44 +00003748 index = fieldFromInstruction32(Insn, 7, 1);
3749 if (fieldFromInstruction32(Insn, 6, 1))
3750 inc = 2;
3751 break;
3752 }
3753
3754 if (Rm != 0xF) { // Writeback
Owen Andersona6804442011-09-01 23:23:50 +00003755 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3756 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003757 }
Owen Andersona6804442011-09-01 23:23:50 +00003758 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3759 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003760 Inst.addOperand(MCOperand::CreateImm(align));
Owen Anderson2cbf2102011-08-22 18:42:13 +00003761 if (Rm != 0xF) {
James Molloyc047dca2011-09-01 18:02:14 +00003762 if (Rm != 0xD) {
Owen Andersona6804442011-09-01 23:23:50 +00003763 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3764 return MCDisassembler::Fail;
James Molloyc047dca2011-09-01 18:02:14 +00003765 } else
Owen Anderson2cbf2102011-08-22 18:42:13 +00003766 Inst.addOperand(MCOperand::CreateReg(0));
Owen Anderson7a2e1772011-08-15 18:44:44 +00003767 }
3768
Owen Andersona6804442011-09-01 23:23:50 +00003769 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3770 return MCDisassembler::Fail;
3771 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3772 return MCDisassembler::Fail;
3773 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
3774 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003775 Inst.addOperand(MCOperand::CreateImm(index));
3776
Owen Anderson83e3f672011-08-17 17:44:15 +00003777 return S;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003778}
3779
3780
Owen Andersona6804442011-09-01 23:23:50 +00003781static DecodeStatus DecodeVLD4LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +00003782 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003783 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003784
Owen Anderson7a2e1772011-08-15 18:44:44 +00003785 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3786 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3787 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3788 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3789 unsigned size = fieldFromInstruction32(Insn, 10, 2);
3790
3791 unsigned align = 0;
3792 unsigned index = 0;
3793 unsigned inc = 1;
3794 switch (size) {
3795 default:
James Molloyc047dca2011-09-01 18:02:14 +00003796 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003797 case 0:
3798 if (fieldFromInstruction32(Insn, 4, 1))
3799 align = 4;
3800 index = fieldFromInstruction32(Insn, 5, 3);
3801 break;
3802 case 1:
3803 if (fieldFromInstruction32(Insn, 4, 1))
3804 align = 8;
3805 index = fieldFromInstruction32(Insn, 6, 2);
3806 if (fieldFromInstruction32(Insn, 5, 1))
3807 inc = 2;
3808 break;
3809 case 2:
3810 if (fieldFromInstruction32(Insn, 4, 2))
3811 align = 4 << fieldFromInstruction32(Insn, 4, 2);
3812 index = fieldFromInstruction32(Insn, 7, 1);
3813 if (fieldFromInstruction32(Insn, 6, 1))
3814 inc = 2;
3815 break;
3816 }
3817
Owen Andersona6804442011-09-01 23:23:50 +00003818 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3819 return MCDisassembler::Fail;
3820 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3821 return MCDisassembler::Fail;
3822 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
3823 return MCDisassembler::Fail;
3824 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
3825 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003826
3827 if (Rm != 0xF) { // Writeback
Owen Andersona6804442011-09-01 23:23:50 +00003828 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3829 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003830 }
Owen Andersona6804442011-09-01 23:23:50 +00003831 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3832 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003833 Inst.addOperand(MCOperand::CreateImm(align));
Owen Anderson2cbf2102011-08-22 18:42:13 +00003834 if (Rm != 0xF) {
James Molloyc047dca2011-09-01 18:02:14 +00003835 if (Rm != 0xD) {
Owen Andersona6804442011-09-01 23:23:50 +00003836 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3837 return MCDisassembler::Fail;
James Molloyc047dca2011-09-01 18:02:14 +00003838 } else
Owen Anderson2cbf2102011-08-22 18:42:13 +00003839 Inst.addOperand(MCOperand::CreateReg(0));
Owen Anderson7a2e1772011-08-15 18:44:44 +00003840 }
3841
Owen Andersona6804442011-09-01 23:23:50 +00003842 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3843 return MCDisassembler::Fail;
3844 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3845 return MCDisassembler::Fail;
3846 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
3847 return MCDisassembler::Fail;
3848 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
3849 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003850 Inst.addOperand(MCOperand::CreateImm(index));
3851
Owen Anderson83e3f672011-08-17 17:44:15 +00003852 return S;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003853}
3854
Owen Andersona6804442011-09-01 23:23:50 +00003855static DecodeStatus DecodeVST4LN(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson7a2e1772011-08-15 18:44:44 +00003856 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003857 DecodeStatus S = MCDisassembler::Success;
Owen Anderson83e3f672011-08-17 17:44:15 +00003858
Owen Anderson7a2e1772011-08-15 18:44:44 +00003859 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
3860 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3861 unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
3862 Rd |= fieldFromInstruction32(Insn, 22, 1) << 4;
3863 unsigned size = fieldFromInstruction32(Insn, 10, 2);
3864
3865 unsigned align = 0;
3866 unsigned index = 0;
3867 unsigned inc = 1;
3868 switch (size) {
3869 default:
James Molloyc047dca2011-09-01 18:02:14 +00003870 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003871 case 0:
3872 if (fieldFromInstruction32(Insn, 4, 1))
3873 align = 4;
3874 index = fieldFromInstruction32(Insn, 5, 3);
3875 break;
3876 case 1:
3877 if (fieldFromInstruction32(Insn, 4, 1))
3878 align = 8;
3879 index = fieldFromInstruction32(Insn, 6, 2);
3880 if (fieldFromInstruction32(Insn, 5, 1))
3881 inc = 2;
3882 break;
3883 case 2:
3884 if (fieldFromInstruction32(Insn, 4, 2))
3885 align = 4 << fieldFromInstruction32(Insn, 4, 2);
3886 index = fieldFromInstruction32(Insn, 7, 1);
3887 if (fieldFromInstruction32(Insn, 6, 1))
3888 inc = 2;
3889 break;
3890 }
3891
3892 if (Rm != 0xF) { // Writeback
Owen Andersona6804442011-09-01 23:23:50 +00003893 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3894 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003895 }
Owen Andersona6804442011-09-01 23:23:50 +00003896 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3897 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003898 Inst.addOperand(MCOperand::CreateImm(align));
Owen Anderson2cbf2102011-08-22 18:42:13 +00003899 if (Rm != 0xF) {
James Molloyc047dca2011-09-01 18:02:14 +00003900 if (Rm != 0xD) {
Owen Andersona6804442011-09-01 23:23:50 +00003901 if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3902 return MCDisassembler::Fail;
James Molloyc047dca2011-09-01 18:02:14 +00003903 } else
Owen Anderson2cbf2102011-08-22 18:42:13 +00003904 Inst.addOperand(MCOperand::CreateReg(0));
Owen Anderson7a2e1772011-08-15 18:44:44 +00003905 }
3906
Owen Andersona6804442011-09-01 23:23:50 +00003907 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3908 return MCDisassembler::Fail;
3909 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
3910 return MCDisassembler::Fail;
3911 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
3912 return MCDisassembler::Fail;
3913 if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
3914 return MCDisassembler::Fail;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003915 Inst.addOperand(MCOperand::CreateImm(index));
3916
Owen Anderson83e3f672011-08-17 17:44:15 +00003917 return S;
Owen Anderson7a2e1772011-08-15 18:44:44 +00003918}
3919
Owen Andersona6804442011-09-01 23:23:50 +00003920static DecodeStatus DecodeVMOVSRR(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson357ec682011-08-22 20:27:12 +00003921 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003922 DecodeStatus S = MCDisassembler::Success;
Owen Anderson357ec682011-08-22 20:27:12 +00003923 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3924 unsigned Rt2 = fieldFromInstruction32(Insn, 16, 4);
3925 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3926 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3927 Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
3928
3929 if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
James Molloyc047dca2011-09-01 18:02:14 +00003930 S = MCDisassembler::SoftFail;
Owen Anderson357ec682011-08-22 20:27:12 +00003931
Owen Andersona6804442011-09-01 23:23:50 +00003932 if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)))
3933 return MCDisassembler::Fail;
3934 if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
3935 return MCDisassembler::Fail;
3936 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)))
3937 return MCDisassembler::Fail;
3938 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
3939 return MCDisassembler::Fail;
3940 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3941 return MCDisassembler::Fail;
Owen Anderson357ec682011-08-22 20:27:12 +00003942
3943 return S;
3944}
3945
Owen Andersona6804442011-09-01 23:23:50 +00003946static DecodeStatus DecodeVMOVRRS(llvm::MCInst &Inst, unsigned Insn,
Owen Anderson357ec682011-08-22 20:27:12 +00003947 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003948 DecodeStatus S = MCDisassembler::Success;
Owen Anderson357ec682011-08-22 20:27:12 +00003949 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
3950 unsigned Rt2 = fieldFromInstruction32(Insn, 16, 4);
3951 unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
3952 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
3953 Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
3954
3955 if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
James Molloyc047dca2011-09-01 18:02:14 +00003956 S = MCDisassembler::SoftFail;
Owen Anderson357ec682011-08-22 20:27:12 +00003957
Owen Andersona6804442011-09-01 23:23:50 +00003958 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)))
3959 return MCDisassembler::Fail;
3960 if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
3961 return MCDisassembler::Fail;
3962 if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)))
3963 return MCDisassembler::Fail;
3964 if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
3965 return MCDisassembler::Fail;
3966 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3967 return MCDisassembler::Fail;
Owen Anderson357ec682011-08-22 20:27:12 +00003968
3969 return S;
3970}
Owen Anderson8e1e60b2011-08-22 23:44:04 +00003971
Owen Andersona6804442011-09-01 23:23:50 +00003972static DecodeStatus DecodeIT(llvm::MCInst &Inst, unsigned Insn,
Owen Andersoneaca9282011-08-30 22:58:27 +00003973 uint64_t Address, const void *Decoder) {
Owen Andersona6804442011-09-01 23:23:50 +00003974 DecodeStatus S = MCDisassembler::Success;
Owen Andersoneaca9282011-08-30 22:58:27 +00003975 unsigned pred = fieldFromInstruction16(Insn, 4, 4);
3976 // The InstPrinter needs to have the low bit of the predicate in
3977 // the mask operand to be able to print it properly.
3978 unsigned mask = fieldFromInstruction16(Insn, 0, 5);
3979
3980 if (pred == 0xF) {
3981 pred = 0xE;
James Molloyc047dca2011-09-01 18:02:14 +00003982 S = MCDisassembler::SoftFail;
Owen Andersone234d022011-08-24 17:21:43 +00003983 }
3984
Owen Andersoneaca9282011-08-30 22:58:27 +00003985 if ((mask & 0xF) == 0) {
3986 // Preserve the high bit of the mask, which is the low bit of
3987 // the predicate.
3988 mask &= 0x10;
3989 mask |= 0x8;
James Molloyc047dca2011-09-01 18:02:14 +00003990 S = MCDisassembler::SoftFail;
Owen Andersonf4408202011-08-24 22:40:22 +00003991 }
Owen Andersoneaca9282011-08-30 22:58:27 +00003992
3993 Inst.addOperand(MCOperand::CreateImm(pred));
3994 Inst.addOperand(MCOperand::CreateImm(mask));
Owen Andersonf4408202011-08-24 22:40:22 +00003995 return S;
3996}
Jim Grosbacha77295d2011-09-08 22:07:06 +00003997
3998static DecodeStatus
3999DecodeT2LDRDPreInstruction(llvm::MCInst &Inst, unsigned Insn,
4000 uint64_t Address, const void *Decoder) {
4001 DecodeStatus S = MCDisassembler::Success;
4002
4003 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
4004 unsigned Rt2 = fieldFromInstruction32(Insn, 8, 4);
4005 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
4006 unsigned addr = fieldFromInstruction32(Insn, 0, 8);
4007 unsigned W = fieldFromInstruction32(Insn, 21, 1);
4008 unsigned U = fieldFromInstruction32(Insn, 23, 1);
4009 unsigned P = fieldFromInstruction32(Insn, 24, 1);
4010 bool writeback = (W == 1) | (P == 0);
4011
4012 addr |= (U << 8) | (Rn << 9);
4013
4014 if (writeback && (Rn == Rt || Rn == Rt2))
4015 Check(S, MCDisassembler::SoftFail);
4016 if (Rt == Rt2)
4017 Check(S, MCDisassembler::SoftFail);
4018
4019 // Rt
4020 if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4021 return MCDisassembler::Fail;
4022 // Rt2
4023 if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4024 return MCDisassembler::Fail;
4025 // Writeback operand
4026 if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4027 return MCDisassembler::Fail;
4028 // addr
4029 if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4030 return MCDisassembler::Fail;
4031
4032 return S;
4033}
4034
4035static DecodeStatus
4036DecodeT2STRDPreInstruction(llvm::MCInst &Inst, unsigned Insn,
4037 uint64_t Address, const void *Decoder) {
4038 DecodeStatus S = MCDisassembler::Success;
4039
4040 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
4041 unsigned Rt2 = fieldFromInstruction32(Insn, 8, 4);
4042 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
4043 unsigned addr = fieldFromInstruction32(Insn, 0, 8);
4044 unsigned W = fieldFromInstruction32(Insn, 21, 1);
4045 unsigned U = fieldFromInstruction32(Insn, 23, 1);
4046 unsigned P = fieldFromInstruction32(Insn, 24, 1);
4047 bool writeback = (W == 1) | (P == 0);
4048
4049 addr |= (U << 8) | (Rn << 9);
4050
4051 if (writeback && (Rn == Rt || Rn == Rt2))
4052 Check(S, MCDisassembler::SoftFail);
4053
4054 // Writeback operand
4055 if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4056 return MCDisassembler::Fail;
4057 // Rt
4058 if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4059 return MCDisassembler::Fail;
4060 // Rt2
4061 if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4062 return MCDisassembler::Fail;
4063 // addr
4064 if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4065 return MCDisassembler::Fail;
4066
4067 return S;
4068}
Owen Anderson08fef882011-09-09 22:24:36 +00004069
4070static DecodeStatus DecodeT2Adr(llvm::MCInst &Inst, uint32_t Insn,
4071 uint64_t Address, const void *Decoder) {
4072 unsigned sign1 = fieldFromInstruction32(Insn, 21, 1);
4073 unsigned sign2 = fieldFromInstruction32(Insn, 23, 1);
4074 if (sign1 != sign2) return MCDisassembler::Fail;
4075
4076 unsigned Val = fieldFromInstruction32(Insn, 0, 8);
4077 Val |= fieldFromInstruction32(Insn, 12, 3) << 8;
4078 Val |= fieldFromInstruction32(Insn, 26, 1) << 11;
4079 Val |= sign1 << 12;
4080 Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val)));
4081
4082 return MCDisassembler::Success;
4083}
4084
Owen Anderson0afa0092011-09-26 21:06:22 +00004085static DecodeStatus DecodeT2ShifterImmOperand(llvm::MCInst &Inst, uint32_t Val,
4086 uint64_t Address,
4087 const void *Decoder) {
4088 DecodeStatus S = MCDisassembler::Success;
4089
4090 // Shift of "asr #32" is not allowed in Thumb2 mode.
4091 if (Val == 0x20) S = MCDisassembler::SoftFail;
4092 Inst.addOperand(MCOperand::CreateImm(Val));
4093 return S;
4094}
4095
Owen Andersoncb9fed62011-10-28 18:02:13 +00004096static DecodeStatus DecodeSwap(llvm::MCInst &Inst, unsigned Insn,
4097 uint64_t Address, const void *Decoder) {
4098 unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
4099 unsigned Rt2 = fieldFromInstruction32(Insn, 0, 4);
4100 unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
4101 unsigned pred = fieldFromInstruction32(Insn, 28, 4);
4102
4103 if (pred == 0xF)
4104 return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
4105
4106 DecodeStatus S = MCDisassembler::Success;
4107 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4108 return MCDisassembler::Fail;
4109 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
4110 return MCDisassembler::Fail;
4111 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4112 return MCDisassembler::Fail;
4113 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4114 return MCDisassembler::Fail;
4115
4116 return S;
4117}
Owen Andersonb589be92011-11-15 19:55:00 +00004118
4119static DecodeStatus DecodeVCVTD(llvm::MCInst &Inst, unsigned Insn,
4120 uint64_t Address, const void *Decoder) {
4121 unsigned Vd = (fieldFromInstruction32(Insn, 12, 4) << 0);
4122 Vd |= (fieldFromInstruction32(Insn, 22, 1) << 4);
4123 unsigned Vm = (fieldFromInstruction32(Insn, 0, 4) << 0);
4124 Vm |= (fieldFromInstruction32(Insn, 5, 1) << 4);
4125 unsigned imm = fieldFromInstruction32(Insn, 16, 6);
4126 unsigned cmode = fieldFromInstruction32(Insn, 8, 4);
4127
4128 DecodeStatus S = MCDisassembler::Success;
4129
4130 // VMOVv2f32 is ambiguous with these decodings.
Owen Anderson22925d92011-11-15 20:30:41 +00004131 if (!(imm & 0x38) && cmode == 0xF) {
Owen Andersonb589be92011-11-15 19:55:00 +00004132 Inst.setOpcode(ARM::VMOVv2f32);
4133 return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
4134 }
4135
4136 if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail);
4137
4138 if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
4139 return MCDisassembler::Fail;
4140 if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
4141 return MCDisassembler::Fail;
4142 Inst.addOperand(MCOperand::CreateImm(64 - imm));
4143
4144 return S;
4145}
4146
4147static DecodeStatus DecodeVCVTQ(llvm::MCInst &Inst, unsigned Insn,
4148 uint64_t Address, const void *Decoder) {
4149 unsigned Vd = (fieldFromInstruction32(Insn, 12, 4) << 0);
4150 Vd |= (fieldFromInstruction32(Insn, 22, 1) << 4);
4151 unsigned Vm = (fieldFromInstruction32(Insn, 0, 4) << 0);
4152 Vm |= (fieldFromInstruction32(Insn, 5, 1) << 4);
4153 unsigned imm = fieldFromInstruction32(Insn, 16, 6);
4154 unsigned cmode = fieldFromInstruction32(Insn, 8, 4);
4155
4156 DecodeStatus S = MCDisassembler::Success;
4157
4158 // VMOVv4f32 is ambiguous with these decodings.
4159 if (!(imm & 0x38) && cmode == 0xF) {
4160 Inst.setOpcode(ARM::VMOVv4f32);
4161 return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
4162 }
4163
4164 if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail);
4165
4166 if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
4167 return MCDisassembler::Fail;
4168 if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
4169 return MCDisassembler::Fail;
4170 Inst.addOperand(MCOperand::CreateImm(64 - imm));
4171
4172 return S;
4173}