]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===// |
2 | // | |
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 | //===----------------------------------------------------------------------===// | |
9 | ||
10 | #define DEBUG_TYPE "arm-disassembler" | |
11 | ||
970d7e83 | 12 | #include "llvm/MC/MCDisassembler.h" |
223e47cc | 13 | #include "MCTargetDesc/ARMAddressingModes.h" |
223e47cc | 14 | #include "MCTargetDesc/ARMBaseInfo.h" |
970d7e83 | 15 | #include "MCTargetDesc/ARMMCExpr.h" |
223e47cc | 16 | #include "llvm/MC/MCContext.h" |
970d7e83 | 17 | #include "llvm/MC/MCExpr.h" |
223e47cc | 18 | #include "llvm/MC/MCFixedLenDisassembler.h" |
970d7e83 LB |
19 | #include "llvm/MC/MCInst.h" |
20 | #include "llvm/MC/MCInstrDesc.h" | |
223e47cc LB |
21 | #include "llvm/MC/MCSubtargetInfo.h" |
22 | #include "llvm/Support/Debug.h" | |
223e47cc LB |
23 | #include "llvm/Support/ErrorHandling.h" |
24 | #include "llvm/Support/LEB128.h" | |
970d7e83 | 25 | #include "llvm/Support/MemoryObject.h" |
223e47cc LB |
26 | #include "llvm/Support/TargetRegistry.h" |
27 | #include "llvm/Support/raw_ostream.h" | |
28 | #include <vector> | |
29 | ||
30 | using namespace llvm; | |
31 | ||
32 | typedef MCDisassembler::DecodeStatus DecodeStatus; | |
33 | ||
34 | namespace { | |
35 | // Handles the condition code status of instructions in IT blocks | |
36 | class ITStatus | |
37 | { | |
38 | public: | |
39 | // Returns the condition code for instruction in IT block | |
40 | unsigned getITCC() { | |
41 | unsigned CC = ARMCC::AL; | |
42 | if (instrInITBlock()) | |
43 | CC = ITStates.back(); | |
44 | return CC; | |
45 | } | |
46 | ||
47 | // Advances the IT block state to the next T or E | |
48 | void advanceITState() { | |
49 | ITStates.pop_back(); | |
50 | } | |
51 | ||
52 | // Returns true if the current instruction is in an IT block | |
53 | bool instrInITBlock() { | |
54 | return !ITStates.empty(); | |
55 | } | |
56 | ||
57 | // Returns true if current instruction is the last instruction in an IT block | |
58 | bool instrLastInITBlock() { | |
59 | return ITStates.size() == 1; | |
60 | } | |
61 | ||
62 | // Called when decoding an IT instruction. Sets the IT state for the following | |
63 | // instructions that for the IT block. Firstcond and Mask correspond to the | |
64 | // fields in the IT instruction encoding. | |
65 | void setITState(char Firstcond, char Mask) { | |
66 | // (3 - the number of trailing zeros) is the number of then / else. | |
67 | unsigned CondBit0 = Firstcond & 1; | |
68 | unsigned NumTZ = CountTrailingZeros_32(Mask); | |
69 | unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf); | |
70 | assert(NumTZ <= 3 && "Invalid IT mask!"); | |
71 | // push condition codes onto the stack the correct order for the pops | |
72 | for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) { | |
73 | bool T = ((Mask >> Pos) & 1) == CondBit0; | |
74 | if (T) | |
75 | ITStates.push_back(CCBits); | |
76 | else | |
77 | ITStates.push_back(CCBits ^ 1); | |
78 | } | |
79 | ITStates.push_back(CCBits); | |
80 | } | |
81 | ||
82 | private: | |
83 | std::vector<unsigned char> ITStates; | |
84 | }; | |
85 | } | |
86 | ||
87 | namespace { | |
88 | /// ARMDisassembler - ARM disassembler for all ARM platforms. | |
89 | class ARMDisassembler : public MCDisassembler { | |
90 | public: | |
91 | /// Constructor - Initializes the disassembler. | |
92 | /// | |
93 | ARMDisassembler(const MCSubtargetInfo &STI) : | |
94 | MCDisassembler(STI) { | |
95 | } | |
96 | ||
97 | ~ARMDisassembler() { | |
98 | } | |
99 | ||
100 | /// getInstruction - See MCDisassembler. | |
101 | DecodeStatus getInstruction(MCInst &instr, | |
102 | uint64_t &size, | |
103 | const MemoryObject ®ion, | |
104 | uint64_t address, | |
105 | raw_ostream &vStream, | |
106 | raw_ostream &cStream) const; | |
223e47cc LB |
107 | }; |
108 | ||
109 | /// ThumbDisassembler - Thumb disassembler for all Thumb platforms. | |
110 | class ThumbDisassembler : public MCDisassembler { | |
111 | public: | |
112 | /// Constructor - Initializes the disassembler. | |
113 | /// | |
114 | ThumbDisassembler(const MCSubtargetInfo &STI) : | |
115 | MCDisassembler(STI) { | |
116 | } | |
117 | ||
118 | ~ThumbDisassembler() { | |
119 | } | |
120 | ||
121 | /// getInstruction - See MCDisassembler. | |
122 | DecodeStatus getInstruction(MCInst &instr, | |
123 | uint64_t &size, | |
124 | const MemoryObject ®ion, | |
125 | uint64_t address, | |
126 | raw_ostream &vStream, | |
127 | raw_ostream &cStream) const; | |
128 | ||
223e47cc LB |
129 | private: |
130 | mutable ITStatus ITBlock; | |
131 | DecodeStatus AddThumbPredicate(MCInst&) const; | |
132 | void UpdateThumbVFPPredicate(MCInst&) const; | |
133 | }; | |
134 | } | |
135 | ||
136 | static bool Check(DecodeStatus &Out, DecodeStatus In) { | |
137 | switch (In) { | |
138 | case MCDisassembler::Success: | |
139 | // Out stays the same. | |
140 | return true; | |
141 | case MCDisassembler::SoftFail: | |
142 | Out = In; | |
143 | return true; | |
144 | case MCDisassembler::Fail: | |
145 | Out = In; | |
146 | return false; | |
147 | } | |
148 | llvm_unreachable("Invalid DecodeStatus!"); | |
149 | } | |
150 | ||
151 | ||
152 | // Forward declare these because the autogenerated code will reference them. | |
153 | // Definitions are further down. | |
154 | static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
155 | uint64_t Address, const void *Decoder); | |
156 | static DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst, | |
157 | unsigned RegNo, uint64_t Address, | |
158 | const void *Decoder); | |
159 | static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
160 | uint64_t Address, const void *Decoder); | |
161 | static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
162 | uint64_t Address, const void *Decoder); | |
163 | static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
164 | uint64_t Address, const void *Decoder); | |
165 | static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
166 | uint64_t Address, const void *Decoder); | |
167 | static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
168 | uint64_t Address, const void *Decoder); | |
169 | static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, | |
170 | uint64_t Address, const void *Decoder); | |
171 | static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst, | |
172 | unsigned RegNo, | |
173 | uint64_t Address, | |
174 | const void *Decoder); | |
175 | static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
176 | uint64_t Address, const void *Decoder); | |
177 | static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, | |
178 | uint64_t Address, const void *Decoder); | |
179 | static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, | |
180 | unsigned RegNo, uint64_t Address, | |
181 | const void *Decoder); | |
182 | ||
183 | static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, | |
184 | uint64_t Address, const void *Decoder); | |
185 | static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, | |
186 | uint64_t Address, const void *Decoder); | |
187 | static DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val, | |
188 | uint64_t Address, const void *Decoder); | |
189 | static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, | |
190 | uint64_t Address, const void *Decoder); | |
191 | static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, | |
192 | uint64_t Address, const void *Decoder); | |
193 | static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, | |
194 | uint64_t Address, const void *Decoder); | |
195 | ||
196 | static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn, | |
197 | uint64_t Address, const void *Decoder); | |
198 | static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, | |
199 | uint64_t Address, const void *Decoder); | |
200 | static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst, | |
201 | unsigned Insn, | |
202 | uint64_t Address, | |
203 | const void *Decoder); | |
204 | static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn, | |
205 | uint64_t Address, const void *Decoder); | |
206 | static DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn, | |
207 | uint64_t Address, const void *Decoder); | |
208 | static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn, | |
209 | uint64_t Address, const void *Decoder); | |
210 | static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn, | |
211 | uint64_t Address, const void *Decoder); | |
212 | ||
213 | static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst, | |
214 | unsigned Insn, | |
215 | uint64_t Adddress, | |
216 | const void *Decoder); | |
217 | static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, | |
218 | uint64_t Address, const void *Decoder); | |
219 | static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, | |
220 | uint64_t Address, const void *Decoder); | |
221 | static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, | |
222 | uint64_t Address, const void *Decoder); | |
223 | static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, | |
224 | uint64_t Address, const void *Decoder); | |
225 | static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, | |
226 | uint64_t Address, const void *Decoder); | |
227 | static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, | |
228 | uint64_t Address, const void *Decoder); | |
229 | static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, | |
230 | uint64_t Address, const void *Decoder); | |
231 | static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, | |
232 | uint64_t Address, const void *Decoder); | |
233 | static DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn, | |
234 | uint64_t Address, const void *Decoder); | |
235 | static DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn, | |
236 | uint64_t Address, const void *Decoder); | |
237 | static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, | |
238 | uint64_t Address, const void *Decoder); | |
239 | static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val, | |
240 | uint64_t Address, const void *Decoder); | |
241 | static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val, | |
242 | uint64_t Address, const void *Decoder); | |
243 | static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val, | |
244 | uint64_t Address, const void *Decoder); | |
245 | static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val, | |
246 | uint64_t Address, const void *Decoder); | |
247 | static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val, | |
248 | uint64_t Address, const void *Decoder); | |
249 | static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val, | |
250 | uint64_t Address, const void *Decoder); | |
251 | static DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val, | |
252 | uint64_t Address, const void *Decoder); | |
253 | static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val, | |
254 | uint64_t Address, const void *Decoder); | |
255 | static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, | |
256 | uint64_t Address, const void *Decoder); | |
257 | static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, | |
258 | uint64_t Address, const void *Decoder); | |
259 | static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, | |
260 | uint64_t Address, const void *Decoder); | |
261 | static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, | |
262 | uint64_t Address, const void *Decoder); | |
263 | static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, | |
264 | uint64_t Address, const void *Decoder); | |
265 | static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, | |
266 | uint64_t Address, const void *Decoder); | |
267 | static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn, | |
268 | uint64_t Address, const void *Decoder); | |
269 | static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn, | |
270 | uint64_t Address, const void *Decoder); | |
271 | static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn, | |
272 | uint64_t Address, const void *Decoder); | |
273 | static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, | |
274 | uint64_t Address, const void *Decoder); | |
275 | static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, | |
276 | uint64_t Address, const void *Decoder); | |
277 | static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, | |
278 | uint64_t Address, const void *Decoder); | |
279 | static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, | |
280 | uint64_t Address, const void *Decoder); | |
281 | static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, | |
282 | uint64_t Address, const void *Decoder); | |
283 | static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, | |
284 | uint64_t Address, const void *Decoder); | |
285 | static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, | |
286 | uint64_t Address, const void *Decoder); | |
287 | static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, | |
288 | uint64_t Address, const void *Decoder); | |
289 | static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, | |
290 | uint64_t Address, const void *Decoder); | |
291 | static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, | |
292 | uint64_t Address, const void *Decoder); | |
293 | static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, | |
294 | uint64_t Address, const void *Decoder); | |
295 | static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, | |
296 | uint64_t Address, const void *Decoder); | |
297 | static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, | |
298 | uint64_t Address, const void *Decoder); | |
299 | static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, | |
300 | uint64_t Address, const void *Decoder); | |
301 | static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, | |
302 | uint64_t Address, const void *Decoder); | |
303 | static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, | |
304 | uint64_t Address, const void *Decoder); | |
305 | static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, | |
306 | uint64_t Address, const void *Decoder); | |
307 | static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, | |
308 | uint64_t Address, const void *Decoder); | |
309 | static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, | |
310 | uint64_t Address, const void *Decoder); | |
311 | ||
312 | ||
313 | static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, | |
314 | uint64_t Address, const void *Decoder); | |
315 | static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, | |
316 | uint64_t Address, const void *Decoder); | |
317 | static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, | |
318 | uint64_t Address, const void *Decoder); | |
319 | static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, | |
320 | uint64_t Address, const void *Decoder); | |
321 | static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, | |
322 | uint64_t Address, const void *Decoder); | |
323 | static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, | |
324 | uint64_t Address, const void *Decoder); | |
325 | static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, | |
326 | uint64_t Address, const void *Decoder); | |
327 | static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, | |
328 | uint64_t Address, const void *Decoder); | |
329 | static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, | |
330 | uint64_t Address, const void *Decoder); | |
331 | static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val, | |
332 | uint64_t Address, const void *Decoder); | |
333 | static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, | |
334 | uint64_t Address, const void *Decoder); | |
335 | static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, | |
336 | uint64_t Address, const void *Decoder); | |
337 | static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, | |
338 | uint64_t Address, const void *Decoder); | |
339 | static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, | |
340 | uint64_t Address, const void *Decoder); | |
341 | static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, | |
342 | uint64_t Address, const void *Decoder); | |
343 | static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val, | |
344 | uint64_t Address, const void *Decoder); | |
345 | static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, | |
346 | uint64_t Address, const void *Decoder); | |
347 | static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, | |
348 | uint64_t Address, const void *Decoder); | |
349 | static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn, | |
350 | uint64_t Address, const void *Decoder); | |
351 | static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, | |
352 | uint64_t Address, const void *Decoder); | |
353 | static DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val, | |
354 | uint64_t Address, const void *Decoder); | |
355 | static DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val, | |
356 | uint64_t Address, const void *Decoder); | |
357 | static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, | |
358 | uint64_t Address, const void *Decoder); | |
359 | static DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val, | |
360 | uint64_t Address, const void *Decoder); | |
361 | static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, | |
362 | uint64_t Address, const void *Decoder); | |
363 | static DecodeStatus DecodeIT(MCInst &Inst, unsigned Val, | |
364 | uint64_t Address, const void *Decoder); | |
365 | static DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn, | |
366 | uint64_t Address, const void *Decoder); | |
367 | static DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn, | |
368 | uint64_t Address, const void *Decoder); | |
369 | static DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val, | |
370 | uint64_t Address, const void *Decoder); | |
371 | static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val, | |
372 | uint64_t Address, const void *Decoder); | |
373 | static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val, | |
374 | uint64_t Address, const void *Decoder); | |
375 | ||
376 | static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, | |
377 | uint64_t Address, const void *Decoder); | |
378 | static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, | |
379 | uint64_t Address, const void *Decoder); | |
380 | #include "ARMGenDisassemblerTables.inc" | |
223e47cc LB |
381 | |
382 | static MCDisassembler *createARMDisassembler(const Target &T, const MCSubtargetInfo &STI) { | |
383 | return new ARMDisassembler(STI); | |
384 | } | |
385 | ||
386 | static MCDisassembler *createThumbDisassembler(const Target &T, const MCSubtargetInfo &STI) { | |
387 | return new ThumbDisassembler(STI); | |
388 | } | |
389 | ||
223e47cc LB |
390 | DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, |
391 | const MemoryObject &Region, | |
392 | uint64_t Address, | |
393 | raw_ostream &os, | |
394 | raw_ostream &cs) const { | |
395 | CommentStream = &cs; | |
396 | ||
397 | uint8_t bytes[4]; | |
398 | ||
399 | assert(!(STI.getFeatureBits() & ARM::ModeThumb) && | |
400 | "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!"); | |
401 | ||
402 | // We want to read exactly 4 bytes of data. | |
403 | if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) { | |
404 | Size = 0; | |
405 | return MCDisassembler::Fail; | |
406 | } | |
407 | ||
408 | // Encoded as a small-endian 32-bit word in the stream. | |
409 | uint32_t insn = (bytes[3] << 24) | | |
410 | (bytes[2] << 16) | | |
411 | (bytes[1] << 8) | | |
412 | (bytes[0] << 0); | |
413 | ||
414 | // Calling the auto-generated decoder function. | |
415 | DecodeStatus result = decodeInstruction(DecoderTableARM32, MI, insn, | |
416 | Address, this, STI); | |
417 | if (result != MCDisassembler::Fail) { | |
418 | Size = 4; | |
419 | return result; | |
420 | } | |
421 | ||
422 | // VFP and NEON instructions, similarly, are shared between ARM | |
423 | // and Thumb modes. | |
424 | MI.clear(); | |
425 | result = decodeInstruction(DecoderTableVFP32, MI, insn, Address, this, STI); | |
426 | if (result != MCDisassembler::Fail) { | |
427 | Size = 4; | |
428 | return result; | |
429 | } | |
430 | ||
431 | MI.clear(); | |
432 | result = decodeInstruction(DecoderTableNEONData32, MI, insn, Address, | |
433 | this, STI); | |
434 | if (result != MCDisassembler::Fail) { | |
435 | Size = 4; | |
436 | // Add a fake predicate operand, because we share these instruction | |
437 | // definitions with Thumb2 where these instructions are predicable. | |
438 | if (!DecodePredicateOperand(MI, 0xE, Address, this)) | |
439 | return MCDisassembler::Fail; | |
440 | return result; | |
441 | } | |
442 | ||
443 | MI.clear(); | |
444 | result = decodeInstruction(DecoderTableNEONLoadStore32, MI, insn, Address, | |
445 | this, STI); | |
446 | if (result != MCDisassembler::Fail) { | |
447 | Size = 4; | |
448 | // Add a fake predicate operand, because we share these instruction | |
449 | // definitions with Thumb2 where these instructions are predicable. | |
450 | if (!DecodePredicateOperand(MI, 0xE, Address, this)) | |
451 | return MCDisassembler::Fail; | |
452 | return result; | |
453 | } | |
454 | ||
455 | MI.clear(); | |
456 | result = decodeInstruction(DecoderTableNEONDup32, MI, insn, Address, | |
457 | this, STI); | |
458 | if (result != MCDisassembler::Fail) { | |
459 | Size = 4; | |
460 | // Add a fake predicate operand, because we share these instruction | |
461 | // definitions with Thumb2 where these instructions are predicable. | |
462 | if (!DecodePredicateOperand(MI, 0xE, Address, this)) | |
463 | return MCDisassembler::Fail; | |
464 | return result; | |
465 | } | |
466 | ||
467 | MI.clear(); | |
468 | ||
469 | Size = 0; | |
470 | return MCDisassembler::Fail; | |
471 | } | |
472 | ||
473 | namespace llvm { | |
474 | extern const MCInstrDesc ARMInsts[]; | |
475 | } | |
476 | ||
477 | /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the | |
478 | /// immediate Value in the MCInst. The immediate Value has had any PC | |
479 | /// adjustment made by the caller. If the instruction is a branch instruction | |
480 | /// then isBranch is true, else false. If the getOpInfo() function was set as | |
481 | /// part of the setupForSymbolicDisassembly() call then that function is called | |
482 | /// to get any symbolic information at the Address for this instruction. If | |
483 | /// that returns non-zero then the symbolic information it returns is used to | |
484 | /// create an MCExpr and that is added as an operand to the MCInst. If | |
485 | /// getOpInfo() returns zero and isBranch is true then a symbol look up for | |
486 | /// Value is done and if a symbol is found an MCExpr is created with that, else | |
487 | /// an MCExpr with Value is created. This function returns true if it adds an | |
488 | /// operand to the MCInst and false otherwise. | |
489 | static bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value, | |
490 | bool isBranch, uint64_t InstSize, | |
491 | MCInst &MI, const void *Decoder) { | |
492 | const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); | |
493 | LLVMOpInfoCallback getOpInfo = Dis->getLLVMOpInfoCallback(); | |
494 | struct LLVMOpInfo1 SymbolicOp; | |
495 | memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1)); | |
496 | SymbolicOp.Value = Value; | |
497 | void *DisInfo = Dis->getDisInfoBlock(); | |
498 | ||
499 | if (!getOpInfo || | |
500 | !getOpInfo(DisInfo, Address, 0 /* Offset */, InstSize, 1, &SymbolicOp)) { | |
501 | // Clear SymbolicOp.Value from above and also all other fields. | |
502 | memset(&SymbolicOp, '\0', sizeof(struct LLVMOpInfo1)); | |
503 | LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback(); | |
504 | if (!SymbolLookUp) | |
505 | return false; | |
506 | uint64_t ReferenceType; | |
507 | if (isBranch) | |
508 | ReferenceType = LLVMDisassembler_ReferenceType_In_Branch; | |
509 | else | |
510 | ReferenceType = LLVMDisassembler_ReferenceType_InOut_None; | |
511 | const char *ReferenceName; | |
970d7e83 LB |
512 | uint64_t SymbolValue = 0x00000000ffffffffULL & Value; |
513 | const char *Name = SymbolLookUp(DisInfo, SymbolValue, &ReferenceType, | |
514 | Address, &ReferenceName); | |
223e47cc LB |
515 | if (Name) { |
516 | SymbolicOp.AddSymbol.Name = Name; | |
517 | SymbolicOp.AddSymbol.Present = true; | |
518 | } | |
519 | // For branches always create an MCExpr so it gets printed as hex address. | |
520 | else if (isBranch) { | |
521 | SymbolicOp.Value = Value; | |
522 | } | |
523 | if(ReferenceType == LLVMDisassembler_ReferenceType_Out_SymbolStub) | |
524 | (*Dis->CommentStream) << "symbol stub for: " << ReferenceName; | |
525 | if (!Name && !isBranch) | |
526 | return false; | |
527 | } | |
528 | ||
529 | MCContext *Ctx = Dis->getMCContext(); | |
530 | const MCExpr *Add = NULL; | |
531 | if (SymbolicOp.AddSymbol.Present) { | |
532 | if (SymbolicOp.AddSymbol.Name) { | |
533 | StringRef Name(SymbolicOp.AddSymbol.Name); | |
534 | MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name); | |
535 | Add = MCSymbolRefExpr::Create(Sym, *Ctx); | |
536 | } else { | |
537 | Add = MCConstantExpr::Create(SymbolicOp.AddSymbol.Value, *Ctx); | |
538 | } | |
539 | } | |
540 | ||
541 | const MCExpr *Sub = NULL; | |
542 | if (SymbolicOp.SubtractSymbol.Present) { | |
543 | if (SymbolicOp.SubtractSymbol.Name) { | |
544 | StringRef Name(SymbolicOp.SubtractSymbol.Name); | |
545 | MCSymbol *Sym = Ctx->GetOrCreateSymbol(Name); | |
546 | Sub = MCSymbolRefExpr::Create(Sym, *Ctx); | |
547 | } else { | |
548 | Sub = MCConstantExpr::Create(SymbolicOp.SubtractSymbol.Value, *Ctx); | |
549 | } | |
550 | } | |
551 | ||
552 | const MCExpr *Off = NULL; | |
553 | if (SymbolicOp.Value != 0) | |
554 | Off = MCConstantExpr::Create(SymbolicOp.Value, *Ctx); | |
555 | ||
556 | const MCExpr *Expr; | |
557 | if (Sub) { | |
558 | const MCExpr *LHS; | |
559 | if (Add) | |
560 | LHS = MCBinaryExpr::CreateSub(Add, Sub, *Ctx); | |
561 | else | |
562 | LHS = MCUnaryExpr::CreateMinus(Sub, *Ctx); | |
563 | if (Off != 0) | |
564 | Expr = MCBinaryExpr::CreateAdd(LHS, Off, *Ctx); | |
565 | else | |
566 | Expr = LHS; | |
567 | } else if (Add) { | |
568 | if (Off != 0) | |
569 | Expr = MCBinaryExpr::CreateAdd(Add, Off, *Ctx); | |
570 | else | |
571 | Expr = Add; | |
572 | } else { | |
573 | if (Off != 0) | |
574 | Expr = Off; | |
575 | else | |
576 | Expr = MCConstantExpr::Create(0, *Ctx); | |
577 | } | |
578 | ||
579 | if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_HI16) | |
580 | MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateUpper16(Expr, *Ctx))); | |
581 | else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_ARM_LO16) | |
582 | MI.addOperand(MCOperand::CreateExpr(ARMMCExpr::CreateLower16(Expr, *Ctx))); | |
583 | else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_None) | |
584 | MI.addOperand(MCOperand::CreateExpr(Expr)); | |
585 | else | |
586 | llvm_unreachable("bad SymbolicOp.VariantKind"); | |
587 | ||
588 | return true; | |
589 | } | |
590 | ||
591 | /// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being | |
592 | /// referenced by a load instruction with the base register that is the Pc. | |
593 | /// These can often be values in a literal pool near the Address of the | |
594 | /// instruction. The Address of the instruction and its immediate Value are | |
595 | /// used as a possible literal pool entry. The SymbolLookUp call back will | |
596 | /// return the name of a symbol referenced by the literal pool's entry if | |
597 | /// the referenced address is that of a symbol. Or it will return a pointer to | |
598 | /// a literal 'C' string if the referenced address of the literal pool's entry | |
599 | /// is an address into a section with 'C' string literals. | |
600 | static void tryAddingPcLoadReferenceComment(uint64_t Address, int Value, | |
601 | const void *Decoder) { | |
602 | const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); | |
603 | LLVMSymbolLookupCallback SymbolLookUp = Dis->getLLVMSymbolLookupCallback(); | |
604 | if (SymbolLookUp) { | |
605 | void *DisInfo = Dis->getDisInfoBlock(); | |
606 | uint64_t ReferenceType; | |
607 | ReferenceType = LLVMDisassembler_ReferenceType_In_PCrel_Load; | |
608 | const char *ReferenceName; | |
609 | (void)SymbolLookUp(DisInfo, Value, &ReferenceType, Address, &ReferenceName); | |
610 | if(ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr || | |
611 | ReferenceType == LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr) | |
612 | (*Dis->CommentStream) << "literal pool for: " << ReferenceName; | |
613 | } | |
614 | } | |
615 | ||
616 | // Thumb1 instructions don't have explicit S bits. Rather, they | |
617 | // implicitly set CPSR. Since it's not represented in the encoding, the | |
618 | // auto-generated decoder won't inject the CPSR operand. We need to fix | |
619 | // that as a post-pass. | |
620 | static void AddThumb1SBit(MCInst &MI, bool InITBlock) { | |
621 | const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; | |
622 | unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; | |
623 | MCInst::iterator I = MI.begin(); | |
624 | for (unsigned i = 0; i < NumOps; ++i, ++I) { | |
625 | if (I == MI.end()) break; | |
626 | if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) { | |
627 | if (i > 0 && OpInfo[i-1].isPredicate()) continue; | |
628 | MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR)); | |
629 | return; | |
630 | } | |
631 | } | |
632 | ||
633 | MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR)); | |
634 | } | |
635 | ||
636 | // Most Thumb instructions don't have explicit predicates in the | |
637 | // encoding, but rather get their predicates from IT context. We need | |
638 | // to fix up the predicate operands using this context information as a | |
639 | // post-pass. | |
640 | MCDisassembler::DecodeStatus | |
641 | ThumbDisassembler::AddThumbPredicate(MCInst &MI) const { | |
642 | MCDisassembler::DecodeStatus S = Success; | |
643 | ||
644 | // A few instructions actually have predicates encoded in them. Don't | |
645 | // try to overwrite it if we're seeing one of those. | |
646 | switch (MI.getOpcode()) { | |
647 | case ARM::tBcc: | |
648 | case ARM::t2Bcc: | |
649 | case ARM::tCBZ: | |
650 | case ARM::tCBNZ: | |
651 | case ARM::tCPS: | |
652 | case ARM::t2CPS3p: | |
653 | case ARM::t2CPS2p: | |
654 | case ARM::t2CPS1p: | |
655 | case ARM::tMOVSr: | |
656 | case ARM::tSETEND: | |
657 | // Some instructions (mostly conditional branches) are not | |
658 | // allowed in IT blocks. | |
659 | if (ITBlock.instrInITBlock()) | |
660 | S = SoftFail; | |
661 | else | |
662 | return Success; | |
663 | break; | |
664 | case ARM::tB: | |
665 | case ARM::t2B: | |
666 | case ARM::t2TBB: | |
667 | case ARM::t2TBH: | |
668 | // Some instructions (mostly unconditional branches) can | |
669 | // only appears at the end of, or outside of, an IT. | |
670 | if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock()) | |
671 | S = SoftFail; | |
672 | break; | |
673 | default: | |
674 | break; | |
675 | } | |
676 | ||
677 | // If we're in an IT block, base the predicate on that. Otherwise, | |
678 | // assume a predicate of AL. | |
679 | unsigned CC; | |
680 | CC = ITBlock.getITCC(); | |
681 | if (CC == 0xF) | |
682 | CC = ARMCC::AL; | |
683 | if (ITBlock.instrInITBlock()) | |
684 | ITBlock.advanceITState(); | |
685 | ||
686 | const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; | |
687 | unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; | |
688 | MCInst::iterator I = MI.begin(); | |
689 | for (unsigned i = 0; i < NumOps; ++i, ++I) { | |
690 | if (I == MI.end()) break; | |
691 | if (OpInfo[i].isPredicate()) { | |
692 | I = MI.insert(I, MCOperand::CreateImm(CC)); | |
693 | ++I; | |
694 | if (CC == ARMCC::AL) | |
695 | MI.insert(I, MCOperand::CreateReg(0)); | |
696 | else | |
697 | MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); | |
698 | return S; | |
699 | } | |
700 | } | |
701 | ||
702 | I = MI.insert(I, MCOperand::CreateImm(CC)); | |
703 | ++I; | |
704 | if (CC == ARMCC::AL) | |
705 | MI.insert(I, MCOperand::CreateReg(0)); | |
706 | else | |
707 | MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); | |
708 | ||
709 | return S; | |
710 | } | |
711 | ||
712 | // Thumb VFP instructions are a special case. Because we share their | |
713 | // encodings between ARM and Thumb modes, and they are predicable in ARM | |
714 | // mode, the auto-generated decoder will give them an (incorrect) | |
715 | // predicate operand. We need to rewrite these operands based on the IT | |
716 | // context as a post-pass. | |
717 | void ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const { | |
718 | unsigned CC; | |
719 | CC = ITBlock.getITCC(); | |
720 | if (ITBlock.instrInITBlock()) | |
721 | ITBlock.advanceITState(); | |
722 | ||
723 | const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo; | |
724 | MCInst::iterator I = MI.begin(); | |
725 | unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands; | |
726 | for (unsigned i = 0; i < NumOps; ++i, ++I) { | |
727 | if (OpInfo[i].isPredicate() ) { | |
728 | I->setImm(CC); | |
729 | ++I; | |
730 | if (CC == ARMCC::AL) | |
731 | I->setReg(0); | |
732 | else | |
733 | I->setReg(ARM::CPSR); | |
734 | return; | |
735 | } | |
736 | } | |
737 | } | |
738 | ||
739 | DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, | |
740 | const MemoryObject &Region, | |
741 | uint64_t Address, | |
742 | raw_ostream &os, | |
743 | raw_ostream &cs) const { | |
744 | CommentStream = &cs; | |
745 | ||
746 | uint8_t bytes[4]; | |
747 | ||
748 | assert((STI.getFeatureBits() & ARM::ModeThumb) && | |
749 | "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!"); | |
750 | ||
751 | // We want to read exactly 2 bytes of data. | |
752 | if (Region.readBytes(Address, 2, (uint8_t*)bytes, NULL) == -1) { | |
753 | Size = 0; | |
754 | return MCDisassembler::Fail; | |
755 | } | |
756 | ||
757 | uint16_t insn16 = (bytes[1] << 8) | bytes[0]; | |
758 | DecodeStatus result = decodeInstruction(DecoderTableThumb16, MI, insn16, | |
759 | Address, this, STI); | |
760 | if (result != MCDisassembler::Fail) { | |
761 | Size = 2; | |
762 | Check(result, AddThumbPredicate(MI)); | |
763 | return result; | |
764 | } | |
765 | ||
766 | MI.clear(); | |
767 | result = decodeInstruction(DecoderTableThumbSBit16, MI, insn16, | |
768 | Address, this, STI); | |
769 | if (result) { | |
770 | Size = 2; | |
771 | bool InITBlock = ITBlock.instrInITBlock(); | |
772 | Check(result, AddThumbPredicate(MI)); | |
773 | AddThumb1SBit(MI, InITBlock); | |
774 | return result; | |
775 | } | |
776 | ||
777 | MI.clear(); | |
778 | result = decodeInstruction(DecoderTableThumb216, MI, insn16, | |
779 | Address, this, STI); | |
780 | if (result != MCDisassembler::Fail) { | |
781 | Size = 2; | |
782 | ||
783 | // Nested IT blocks are UNPREDICTABLE. Must be checked before we add | |
784 | // the Thumb predicate. | |
785 | if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock()) | |
786 | result = MCDisassembler::SoftFail; | |
787 | ||
788 | Check(result, AddThumbPredicate(MI)); | |
789 | ||
790 | // If we find an IT instruction, we need to parse its condition | |
791 | // code and mask operands so that we can apply them correctly | |
792 | // to the subsequent instructions. | |
793 | if (MI.getOpcode() == ARM::t2IT) { | |
794 | ||
795 | unsigned Firstcond = MI.getOperand(0).getImm(); | |
796 | unsigned Mask = MI.getOperand(1).getImm(); | |
797 | ITBlock.setITState(Firstcond, Mask); | |
798 | } | |
799 | ||
800 | return result; | |
801 | } | |
802 | ||
803 | // We want to read exactly 4 bytes of data. | |
804 | if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) { | |
805 | Size = 0; | |
806 | return MCDisassembler::Fail; | |
807 | } | |
808 | ||
809 | uint32_t insn32 = (bytes[3] << 8) | | |
810 | (bytes[2] << 0) | | |
811 | (bytes[1] << 24) | | |
812 | (bytes[0] << 16); | |
813 | MI.clear(); | |
814 | result = decodeInstruction(DecoderTableThumb32, MI, insn32, Address, | |
815 | this, STI); | |
816 | if (result != MCDisassembler::Fail) { | |
817 | Size = 4; | |
818 | bool InITBlock = ITBlock.instrInITBlock(); | |
819 | Check(result, AddThumbPredicate(MI)); | |
820 | AddThumb1SBit(MI, InITBlock); | |
821 | return result; | |
822 | } | |
823 | ||
824 | MI.clear(); | |
825 | result = decodeInstruction(DecoderTableThumb232, MI, insn32, Address, | |
826 | this, STI); | |
827 | if (result != MCDisassembler::Fail) { | |
828 | Size = 4; | |
829 | Check(result, AddThumbPredicate(MI)); | |
830 | return result; | |
831 | } | |
832 | ||
833 | MI.clear(); | |
834 | result = decodeInstruction(DecoderTableVFP32, MI, insn32, Address, this, STI); | |
835 | if (result != MCDisassembler::Fail) { | |
836 | Size = 4; | |
837 | UpdateThumbVFPPredicate(MI); | |
838 | return result; | |
839 | } | |
840 | ||
841 | MI.clear(); | |
842 | result = decodeInstruction(DecoderTableNEONDup32, MI, insn32, Address, | |
843 | this, STI); | |
844 | if (result != MCDisassembler::Fail) { | |
845 | Size = 4; | |
846 | Check(result, AddThumbPredicate(MI)); | |
847 | return result; | |
848 | } | |
849 | ||
850 | if (fieldFromInstruction(insn32, 24, 8) == 0xF9) { | |
851 | MI.clear(); | |
852 | uint32_t NEONLdStInsn = insn32; | |
853 | NEONLdStInsn &= 0xF0FFFFFF; | |
854 | NEONLdStInsn |= 0x04000000; | |
855 | result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn, | |
856 | Address, this, STI); | |
857 | if (result != MCDisassembler::Fail) { | |
858 | Size = 4; | |
859 | Check(result, AddThumbPredicate(MI)); | |
860 | return result; | |
861 | } | |
862 | } | |
863 | ||
864 | if (fieldFromInstruction(insn32, 24, 4) == 0xF) { | |
865 | MI.clear(); | |
866 | uint32_t NEONDataInsn = insn32; | |
867 | NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24 | |
868 | NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24 | |
869 | NEONDataInsn |= 0x12000000; // Set bits 28 and 25 | |
870 | result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn, | |
871 | Address, this, STI); | |
872 | if (result != MCDisassembler::Fail) { | |
873 | Size = 4; | |
874 | Check(result, AddThumbPredicate(MI)); | |
875 | return result; | |
876 | } | |
877 | } | |
878 | ||
879 | Size = 0; | |
880 | return MCDisassembler::Fail; | |
881 | } | |
882 | ||
883 | ||
884 | extern "C" void LLVMInitializeARMDisassembler() { | |
885 | TargetRegistry::RegisterMCDisassembler(TheARMTarget, | |
886 | createARMDisassembler); | |
887 | TargetRegistry::RegisterMCDisassembler(TheThumbTarget, | |
888 | createThumbDisassembler); | |
889 | } | |
890 | ||
891 | static const uint16_t GPRDecoderTable[] = { | |
892 | ARM::R0, ARM::R1, ARM::R2, ARM::R3, | |
893 | ARM::R4, ARM::R5, ARM::R6, ARM::R7, | |
894 | ARM::R8, ARM::R9, ARM::R10, ARM::R11, | |
895 | ARM::R12, ARM::SP, ARM::LR, ARM::PC | |
896 | }; | |
897 | ||
898 | static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
899 | uint64_t Address, const void *Decoder) { | |
900 | if (RegNo > 15) | |
901 | return MCDisassembler::Fail; | |
902 | ||
903 | unsigned Register = GPRDecoderTable[RegNo]; | |
904 | Inst.addOperand(MCOperand::CreateReg(Register)); | |
905 | return MCDisassembler::Success; | |
906 | } | |
907 | ||
908 | static DecodeStatus | |
909 | DecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo, | |
910 | uint64_t Address, const void *Decoder) { | |
911 | DecodeStatus S = MCDisassembler::Success; | |
912 | ||
913 | if (RegNo == 15) | |
914 | S = MCDisassembler::SoftFail; | |
915 | ||
916 | Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); | |
917 | ||
918 | return S; | |
919 | } | |
920 | ||
921 | static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
922 | uint64_t Address, const void *Decoder) { | |
923 | if (RegNo > 7) | |
924 | return MCDisassembler::Fail; | |
925 | return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); | |
926 | } | |
927 | ||
928 | static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
929 | uint64_t Address, const void *Decoder) { | |
930 | unsigned Register = 0; | |
931 | switch (RegNo) { | |
932 | case 0: | |
933 | Register = ARM::R0; | |
934 | break; | |
935 | case 1: | |
936 | Register = ARM::R1; | |
937 | break; | |
938 | case 2: | |
939 | Register = ARM::R2; | |
940 | break; | |
941 | case 3: | |
942 | Register = ARM::R3; | |
943 | break; | |
944 | case 9: | |
945 | Register = ARM::R9; | |
946 | break; | |
947 | case 12: | |
948 | Register = ARM::R12; | |
949 | break; | |
950 | default: | |
951 | return MCDisassembler::Fail; | |
952 | } | |
953 | ||
954 | Inst.addOperand(MCOperand::CreateReg(Register)); | |
955 | return MCDisassembler::Success; | |
956 | } | |
957 | ||
958 | static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
959 | uint64_t Address, const void *Decoder) { | |
960 | if (RegNo == 13 || RegNo == 15) return MCDisassembler::Fail; | |
961 | return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); | |
962 | } | |
963 | ||
964 | static const uint16_t SPRDecoderTable[] = { | |
965 | ARM::S0, ARM::S1, ARM::S2, ARM::S3, | |
966 | ARM::S4, ARM::S5, ARM::S6, ARM::S7, | |
967 | ARM::S8, ARM::S9, ARM::S10, ARM::S11, | |
968 | ARM::S12, ARM::S13, ARM::S14, ARM::S15, | |
969 | ARM::S16, ARM::S17, ARM::S18, ARM::S19, | |
970 | ARM::S20, ARM::S21, ARM::S22, ARM::S23, | |
971 | ARM::S24, ARM::S25, ARM::S26, ARM::S27, | |
972 | ARM::S28, ARM::S29, ARM::S30, ARM::S31 | |
973 | }; | |
974 | ||
975 | static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
976 | uint64_t Address, const void *Decoder) { | |
977 | if (RegNo > 31) | |
978 | return MCDisassembler::Fail; | |
979 | ||
980 | unsigned Register = SPRDecoderTable[RegNo]; | |
981 | Inst.addOperand(MCOperand::CreateReg(Register)); | |
982 | return MCDisassembler::Success; | |
983 | } | |
984 | ||
985 | static const uint16_t DPRDecoderTable[] = { | |
986 | ARM::D0, ARM::D1, ARM::D2, ARM::D3, | |
987 | ARM::D4, ARM::D5, ARM::D6, ARM::D7, | |
988 | ARM::D8, ARM::D9, ARM::D10, ARM::D11, | |
989 | ARM::D12, ARM::D13, ARM::D14, ARM::D15, | |
990 | ARM::D16, ARM::D17, ARM::D18, ARM::D19, | |
991 | ARM::D20, ARM::D21, ARM::D22, ARM::D23, | |
992 | ARM::D24, ARM::D25, ARM::D26, ARM::D27, | |
993 | ARM::D28, ARM::D29, ARM::D30, ARM::D31 | |
994 | }; | |
995 | ||
996 | static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
997 | uint64_t Address, const void *Decoder) { | |
998 | if (RegNo > 31) | |
999 | return MCDisassembler::Fail; | |
1000 | ||
1001 | unsigned Register = DPRDecoderTable[RegNo]; | |
1002 | Inst.addOperand(MCOperand::CreateReg(Register)); | |
1003 | return MCDisassembler::Success; | |
1004 | } | |
1005 | ||
1006 | static DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo, | |
1007 | uint64_t Address, const void *Decoder) { | |
1008 | if (RegNo > 7) | |
1009 | return MCDisassembler::Fail; | |
1010 | return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); | |
1011 | } | |
1012 | ||
1013 | static DecodeStatus | |
1014 | DecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo, | |
1015 | uint64_t Address, const void *Decoder) { | |
1016 | if (RegNo > 15) | |
1017 | return MCDisassembler::Fail; | |
1018 | return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder); | |
1019 | } | |
1020 | ||
1021 | static const uint16_t QPRDecoderTable[] = { | |
1022 | ARM::Q0, ARM::Q1, ARM::Q2, ARM::Q3, | |
1023 | ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7, | |
1024 | ARM::Q8, ARM::Q9, ARM::Q10, ARM::Q11, | |
1025 | ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15 | |
1026 | }; | |
1027 | ||
1028 | ||
1029 | static DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo, | |
1030 | uint64_t Address, const void *Decoder) { | |
1031 | if (RegNo > 31) | |
1032 | return MCDisassembler::Fail; | |
1033 | RegNo >>= 1; | |
1034 | ||
1035 | unsigned Register = QPRDecoderTable[RegNo]; | |
1036 | Inst.addOperand(MCOperand::CreateReg(Register)); | |
1037 | return MCDisassembler::Success; | |
1038 | } | |
1039 | ||
1040 | static const uint16_t DPairDecoderTable[] = { | |
1041 | ARM::Q0, ARM::D1_D2, ARM::Q1, ARM::D3_D4, ARM::Q2, ARM::D5_D6, | |
1042 | ARM::Q3, ARM::D7_D8, ARM::Q4, ARM::D9_D10, ARM::Q5, ARM::D11_D12, | |
1043 | ARM::Q6, ARM::D13_D14, ARM::Q7, ARM::D15_D16, ARM::Q8, ARM::D17_D18, | |
1044 | ARM::Q9, ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24, | |
1045 | ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30, | |
1046 | ARM::Q15 | |
1047 | }; | |
1048 | ||
1049 | static DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo, | |
1050 | uint64_t Address, const void *Decoder) { | |
1051 | if (RegNo > 30) | |
1052 | return MCDisassembler::Fail; | |
1053 | ||
1054 | unsigned Register = DPairDecoderTable[RegNo]; | |
1055 | Inst.addOperand(MCOperand::CreateReg(Register)); | |
1056 | return MCDisassembler::Success; | |
1057 | } | |
1058 | ||
1059 | static const uint16_t DPairSpacedDecoderTable[] = { | |
1060 | ARM::D0_D2, ARM::D1_D3, ARM::D2_D4, ARM::D3_D5, | |
1061 | ARM::D4_D6, ARM::D5_D7, ARM::D6_D8, ARM::D7_D9, | |
1062 | ARM::D8_D10, ARM::D9_D11, ARM::D10_D12, ARM::D11_D13, | |
1063 | ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17, | |
1064 | ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21, | |
1065 | ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25, | |
1066 | ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29, | |
1067 | ARM::D28_D30, ARM::D29_D31 | |
1068 | }; | |
1069 | ||
1070 | static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst, | |
1071 | unsigned RegNo, | |
1072 | uint64_t Address, | |
1073 | const void *Decoder) { | |
1074 | if (RegNo > 29) | |
1075 | return MCDisassembler::Fail; | |
1076 | ||
1077 | unsigned Register = DPairSpacedDecoderTable[RegNo]; | |
1078 | Inst.addOperand(MCOperand::CreateReg(Register)); | |
1079 | return MCDisassembler::Success; | |
1080 | } | |
1081 | ||
1082 | static DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val, | |
1083 | uint64_t Address, const void *Decoder) { | |
1084 | if (Val == 0xF) return MCDisassembler::Fail; | |
1085 | // AL predicate is not allowed on Thumb1 branches. | |
1086 | if (Inst.getOpcode() == ARM::tBcc && Val == 0xE) | |
1087 | return MCDisassembler::Fail; | |
1088 | Inst.addOperand(MCOperand::CreateImm(Val)); | |
1089 | if (Val == ARMCC::AL) { | |
1090 | Inst.addOperand(MCOperand::CreateReg(0)); | |
1091 | } else | |
1092 | Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); | |
1093 | return MCDisassembler::Success; | |
1094 | } | |
1095 | ||
1096 | static DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val, | |
1097 | uint64_t Address, const void *Decoder) { | |
1098 | if (Val) | |
1099 | Inst.addOperand(MCOperand::CreateReg(ARM::CPSR)); | |
1100 | else | |
1101 | Inst.addOperand(MCOperand::CreateReg(0)); | |
1102 | return MCDisassembler::Success; | |
1103 | } | |
1104 | ||
1105 | static DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val, | |
1106 | uint64_t Address, const void *Decoder) { | |
1107 | uint32_t imm = Val & 0xFF; | |
1108 | uint32_t rot = (Val & 0xF00) >> 7; | |
1109 | uint32_t rot_imm = (imm >> rot) | (imm << ((32-rot) & 0x1F)); | |
1110 | Inst.addOperand(MCOperand::CreateImm(rot_imm)); | |
1111 | return MCDisassembler::Success; | |
1112 | } | |
1113 | ||
1114 | static DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val, | |
1115 | uint64_t Address, const void *Decoder) { | |
1116 | DecodeStatus S = MCDisassembler::Success; | |
1117 | ||
1118 | unsigned Rm = fieldFromInstruction(Val, 0, 4); | |
1119 | unsigned type = fieldFromInstruction(Val, 5, 2); | |
1120 | unsigned imm = fieldFromInstruction(Val, 7, 5); | |
1121 | ||
1122 | // Register-immediate | |
1123 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
1124 | return MCDisassembler::Fail; | |
1125 | ||
1126 | ARM_AM::ShiftOpc Shift = ARM_AM::lsl; | |
1127 | switch (type) { | |
1128 | case 0: | |
1129 | Shift = ARM_AM::lsl; | |
1130 | break; | |
1131 | case 1: | |
1132 | Shift = ARM_AM::lsr; | |
1133 | break; | |
1134 | case 2: | |
1135 | Shift = ARM_AM::asr; | |
1136 | break; | |
1137 | case 3: | |
1138 | Shift = ARM_AM::ror; | |
1139 | break; | |
1140 | } | |
1141 | ||
1142 | if (Shift == ARM_AM::ror && imm == 0) | |
1143 | Shift = ARM_AM::rrx; | |
1144 | ||
1145 | unsigned Op = Shift | (imm << 3); | |
1146 | Inst.addOperand(MCOperand::CreateImm(Op)); | |
1147 | ||
1148 | return S; | |
1149 | } | |
1150 | ||
1151 | static DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val, | |
1152 | uint64_t Address, const void *Decoder) { | |
1153 | DecodeStatus S = MCDisassembler::Success; | |
1154 | ||
1155 | unsigned Rm = fieldFromInstruction(Val, 0, 4); | |
1156 | unsigned type = fieldFromInstruction(Val, 5, 2); | |
1157 | unsigned Rs = fieldFromInstruction(Val, 8, 4); | |
1158 | ||
1159 | // Register-register | |
1160 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) | |
1161 | return MCDisassembler::Fail; | |
1162 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder))) | |
1163 | return MCDisassembler::Fail; | |
1164 | ||
1165 | ARM_AM::ShiftOpc Shift = ARM_AM::lsl; | |
1166 | switch (type) { | |
1167 | case 0: | |
1168 | Shift = ARM_AM::lsl; | |
1169 | break; | |
1170 | case 1: | |
1171 | Shift = ARM_AM::lsr; | |
1172 | break; | |
1173 | case 2: | |
1174 | Shift = ARM_AM::asr; | |
1175 | break; | |
1176 | case 3: | |
1177 | Shift = ARM_AM::ror; | |
1178 | break; | |
1179 | } | |
1180 | ||
1181 | Inst.addOperand(MCOperand::CreateImm(Shift)); | |
1182 | ||
1183 | return S; | |
1184 | } | |
1185 | ||
1186 | static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val, | |
1187 | uint64_t Address, const void *Decoder) { | |
1188 | DecodeStatus S = MCDisassembler::Success; | |
1189 | ||
1190 | bool writebackLoad = false; | |
1191 | unsigned writebackReg = 0; | |
1192 | switch (Inst.getOpcode()) { | |
1193 | default: | |
1194 | break; | |
1195 | case ARM::LDMIA_UPD: | |
1196 | case ARM::LDMDB_UPD: | |
1197 | case ARM::LDMIB_UPD: | |
1198 | case ARM::LDMDA_UPD: | |
1199 | case ARM::t2LDMIA_UPD: | |
1200 | case ARM::t2LDMDB_UPD: | |
1201 | writebackLoad = true; | |
1202 | writebackReg = Inst.getOperand(0).getReg(); | |
1203 | break; | |
1204 | } | |
1205 | ||
1206 | // Empty register lists are not allowed. | |
1207 | if (CountPopulation_32(Val) == 0) return MCDisassembler::Fail; | |
1208 | for (unsigned i = 0; i < 16; ++i) { | |
1209 | if (Val & (1 << i)) { | |
1210 | if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder))) | |
1211 | return MCDisassembler::Fail; | |
1212 | // Writeback not allowed if Rn is in the target list. | |
1213 | if (writebackLoad && writebackReg == Inst.end()[-1].getReg()) | |
1214 | Check(S, MCDisassembler::SoftFail); | |
1215 | } | |
1216 | } | |
1217 | ||
1218 | return S; | |
1219 | } | |
1220 | ||
1221 | static DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val, | |
1222 | uint64_t Address, const void *Decoder) { | |
1223 | DecodeStatus S = MCDisassembler::Success; | |
1224 | ||
1225 | unsigned Vd = fieldFromInstruction(Val, 8, 5); | |
1226 | unsigned regs = fieldFromInstruction(Val, 0, 8); | |
1227 | ||
1228 | if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder))) | |
1229 | return MCDisassembler::Fail; | |
1230 | for (unsigned i = 0; i < (regs - 1); ++i) { | |
1231 | if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder))) | |
1232 | return MCDisassembler::Fail; | |
1233 | } | |
1234 | ||
1235 | return S; | |
1236 | } | |
1237 | ||
1238 | static DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val, | |
1239 | uint64_t Address, const void *Decoder) { | |
1240 | DecodeStatus S = MCDisassembler::Success; | |
1241 | ||
1242 | unsigned Vd = fieldFromInstruction(Val, 8, 5); | |
1243 | unsigned regs = fieldFromInstruction(Val, 0, 8); | |
1244 | ||
1245 | regs = regs >> 1; | |
1246 | ||
1247 | if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) | |
1248 | return MCDisassembler::Fail; | |
1249 | for (unsigned i = 0; i < (regs - 1); ++i) { | |
1250 | if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder))) | |
1251 | return MCDisassembler::Fail; | |
1252 | } | |
1253 | ||
1254 | return S; | |
1255 | } | |
1256 | ||
1257 | static DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val, | |
1258 | uint64_t Address, const void *Decoder) { | |
1259 | // This operand encodes a mask of contiguous zeros between a specified MSB | |
1260 | // and LSB. To decode it, we create the mask of all bits MSB-and-lower, | |
1261 | // the mask of all bits LSB-and-lower, and then xor them to create | |
1262 | // the mask of that's all ones on [msb, lsb]. Finally we not it to | |
1263 | // create the final mask. | |
1264 | unsigned msb = fieldFromInstruction(Val, 5, 5); | |
1265 | unsigned lsb = fieldFromInstruction(Val, 0, 5); | |
1266 | ||
1267 | DecodeStatus S = MCDisassembler::Success; | |
970d7e83 LB |
1268 | if (lsb > msb) { |
1269 | Check(S, MCDisassembler::SoftFail); | |
1270 | // The check above will cause the warning for the "potentially undefined | |
1271 | // instruction encoding" but we can't build a bad MCOperand value here | |
1272 | // with a lsb > msb or else printing the MCInst will cause a crash. | |
1273 | lsb = msb; | |
1274 | } | |
223e47cc LB |
1275 | |
1276 | uint32_t msb_mask = 0xFFFFFFFF; | |
1277 | if (msb != 31) msb_mask = (1U << (msb+1)) - 1; | |
1278 | uint32_t lsb_mask = (1U << lsb) - 1; | |
1279 | ||
1280 | Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask))); | |
1281 | return S; | |
1282 | } | |
1283 | ||
1284 | static DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn, | |
1285 | uint64_t Address, const void *Decoder) { | |
1286 | DecodeStatus S = MCDisassembler::Success; | |
1287 | ||
1288 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
1289 | unsigned CRd = fieldFromInstruction(Insn, 12, 4); | |
1290 | unsigned coproc = fieldFromInstruction(Insn, 8, 4); | |
1291 | unsigned imm = fieldFromInstruction(Insn, 0, 8); | |
1292 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
1293 | unsigned U = fieldFromInstruction(Insn, 23, 1); | |
1294 | ||
1295 | switch (Inst.getOpcode()) { | |
1296 | case ARM::LDC_OFFSET: | |
1297 | case ARM::LDC_PRE: | |
1298 | case ARM::LDC_POST: | |
1299 | case ARM::LDC_OPTION: | |
1300 | case ARM::LDCL_OFFSET: | |
1301 | case ARM::LDCL_PRE: | |
1302 | case ARM::LDCL_POST: | |
1303 | case ARM::LDCL_OPTION: | |
1304 | case ARM::STC_OFFSET: | |
1305 | case ARM::STC_PRE: | |
1306 | case ARM::STC_POST: | |
1307 | case ARM::STC_OPTION: | |
1308 | case ARM::STCL_OFFSET: | |
1309 | case ARM::STCL_PRE: | |
1310 | case ARM::STCL_POST: | |
1311 | case ARM::STCL_OPTION: | |
1312 | case ARM::t2LDC_OFFSET: | |
1313 | case ARM::t2LDC_PRE: | |
1314 | case ARM::t2LDC_POST: | |
1315 | case ARM::t2LDC_OPTION: | |
1316 | case ARM::t2LDCL_OFFSET: | |
1317 | case ARM::t2LDCL_PRE: | |
1318 | case ARM::t2LDCL_POST: | |
1319 | case ARM::t2LDCL_OPTION: | |
1320 | case ARM::t2STC_OFFSET: | |
1321 | case ARM::t2STC_PRE: | |
1322 | case ARM::t2STC_POST: | |
1323 | case ARM::t2STC_OPTION: | |
1324 | case ARM::t2STCL_OFFSET: | |
1325 | case ARM::t2STCL_PRE: | |
1326 | case ARM::t2STCL_POST: | |
1327 | case ARM::t2STCL_OPTION: | |
1328 | if (coproc == 0xA || coproc == 0xB) | |
1329 | return MCDisassembler::Fail; | |
1330 | break; | |
1331 | default: | |
1332 | break; | |
1333 | } | |
1334 | ||
1335 | Inst.addOperand(MCOperand::CreateImm(coproc)); | |
1336 | Inst.addOperand(MCOperand::CreateImm(CRd)); | |
1337 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1338 | return MCDisassembler::Fail; | |
1339 | ||
1340 | switch (Inst.getOpcode()) { | |
1341 | case ARM::t2LDC2_OFFSET: | |
1342 | case ARM::t2LDC2L_OFFSET: | |
1343 | case ARM::t2LDC2_PRE: | |
1344 | case ARM::t2LDC2L_PRE: | |
1345 | case ARM::t2STC2_OFFSET: | |
1346 | case ARM::t2STC2L_OFFSET: | |
1347 | case ARM::t2STC2_PRE: | |
1348 | case ARM::t2STC2L_PRE: | |
1349 | case ARM::LDC2_OFFSET: | |
1350 | case ARM::LDC2L_OFFSET: | |
1351 | case ARM::LDC2_PRE: | |
1352 | case ARM::LDC2L_PRE: | |
1353 | case ARM::STC2_OFFSET: | |
1354 | case ARM::STC2L_OFFSET: | |
1355 | case ARM::STC2_PRE: | |
1356 | case ARM::STC2L_PRE: | |
1357 | case ARM::t2LDC_OFFSET: | |
1358 | case ARM::t2LDCL_OFFSET: | |
1359 | case ARM::t2LDC_PRE: | |
1360 | case ARM::t2LDCL_PRE: | |
1361 | case ARM::t2STC_OFFSET: | |
1362 | case ARM::t2STCL_OFFSET: | |
1363 | case ARM::t2STC_PRE: | |
1364 | case ARM::t2STCL_PRE: | |
1365 | case ARM::LDC_OFFSET: | |
1366 | case ARM::LDCL_OFFSET: | |
1367 | case ARM::LDC_PRE: | |
1368 | case ARM::LDCL_PRE: | |
1369 | case ARM::STC_OFFSET: | |
1370 | case ARM::STCL_OFFSET: | |
1371 | case ARM::STC_PRE: | |
1372 | case ARM::STCL_PRE: | |
1373 | imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm); | |
1374 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
1375 | break; | |
1376 | case ARM::t2LDC2_POST: | |
1377 | case ARM::t2LDC2L_POST: | |
1378 | case ARM::t2STC2_POST: | |
1379 | case ARM::t2STC2L_POST: | |
1380 | case ARM::LDC2_POST: | |
1381 | case ARM::LDC2L_POST: | |
1382 | case ARM::STC2_POST: | |
1383 | case ARM::STC2L_POST: | |
1384 | case ARM::t2LDC_POST: | |
1385 | case ARM::t2LDCL_POST: | |
1386 | case ARM::t2STC_POST: | |
1387 | case ARM::t2STCL_POST: | |
1388 | case ARM::LDC_POST: | |
1389 | case ARM::LDCL_POST: | |
1390 | case ARM::STC_POST: | |
1391 | case ARM::STCL_POST: | |
1392 | imm |= U << 8; | |
1393 | // fall through. | |
1394 | default: | |
1395 | // The 'option' variant doesn't encode 'U' in the immediate since | |
1396 | // the immediate is unsigned [0,255]. | |
1397 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
1398 | break; | |
1399 | } | |
1400 | ||
1401 | switch (Inst.getOpcode()) { | |
1402 | case ARM::LDC_OFFSET: | |
1403 | case ARM::LDC_PRE: | |
1404 | case ARM::LDC_POST: | |
1405 | case ARM::LDC_OPTION: | |
1406 | case ARM::LDCL_OFFSET: | |
1407 | case ARM::LDCL_PRE: | |
1408 | case ARM::LDCL_POST: | |
1409 | case ARM::LDCL_OPTION: | |
1410 | case ARM::STC_OFFSET: | |
1411 | case ARM::STC_PRE: | |
1412 | case ARM::STC_POST: | |
1413 | case ARM::STC_OPTION: | |
1414 | case ARM::STCL_OFFSET: | |
1415 | case ARM::STCL_PRE: | |
1416 | case ARM::STCL_POST: | |
1417 | case ARM::STCL_OPTION: | |
1418 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
1419 | return MCDisassembler::Fail; | |
1420 | break; | |
1421 | default: | |
1422 | break; | |
1423 | } | |
1424 | ||
1425 | return S; | |
1426 | } | |
1427 | ||
1428 | static DecodeStatus | |
1429 | DecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn, | |
1430 | uint64_t Address, const void *Decoder) { | |
1431 | DecodeStatus S = MCDisassembler::Success; | |
1432 | ||
1433 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
1434 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
1435 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
1436 | unsigned imm = fieldFromInstruction(Insn, 0, 12); | |
1437 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
1438 | unsigned reg = fieldFromInstruction(Insn, 25, 1); | |
1439 | unsigned P = fieldFromInstruction(Insn, 24, 1); | |
1440 | unsigned W = fieldFromInstruction(Insn, 21, 1); | |
1441 | ||
1442 | // On stores, the writeback operand precedes Rt. | |
1443 | switch (Inst.getOpcode()) { | |
1444 | case ARM::STR_POST_IMM: | |
1445 | case ARM::STR_POST_REG: | |
1446 | case ARM::STRB_POST_IMM: | |
1447 | case ARM::STRB_POST_REG: | |
1448 | case ARM::STRT_POST_REG: | |
1449 | case ARM::STRT_POST_IMM: | |
1450 | case ARM::STRBT_POST_REG: | |
1451 | case ARM::STRBT_POST_IMM: | |
1452 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1453 | return MCDisassembler::Fail; | |
1454 | break; | |
1455 | default: | |
1456 | break; | |
1457 | } | |
1458 | ||
1459 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
1460 | return MCDisassembler::Fail; | |
1461 | ||
1462 | // On loads, the writeback operand comes after Rt. | |
1463 | switch (Inst.getOpcode()) { | |
1464 | case ARM::LDR_POST_IMM: | |
1465 | case ARM::LDR_POST_REG: | |
1466 | case ARM::LDRB_POST_IMM: | |
1467 | case ARM::LDRB_POST_REG: | |
1468 | case ARM::LDRBT_POST_REG: | |
1469 | case ARM::LDRBT_POST_IMM: | |
1470 | case ARM::LDRT_POST_REG: | |
1471 | case ARM::LDRT_POST_IMM: | |
1472 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1473 | return MCDisassembler::Fail; | |
1474 | break; | |
1475 | default: | |
1476 | break; | |
1477 | } | |
1478 | ||
1479 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1480 | return MCDisassembler::Fail; | |
1481 | ||
1482 | ARM_AM::AddrOpc Op = ARM_AM::add; | |
1483 | if (!fieldFromInstruction(Insn, 23, 1)) | |
1484 | Op = ARM_AM::sub; | |
1485 | ||
1486 | bool writeback = (P == 0) || (W == 1); | |
1487 | unsigned idx_mode = 0; | |
1488 | if (P && writeback) | |
1489 | idx_mode = ARMII::IndexModePre; | |
1490 | else if (!P && writeback) | |
1491 | idx_mode = ARMII::IndexModePost; | |
1492 | ||
1493 | if (writeback && (Rn == 15 || Rn == Rt)) | |
1494 | S = MCDisassembler::SoftFail; // UNPREDICTABLE | |
1495 | ||
1496 | if (reg) { | |
1497 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) | |
1498 | return MCDisassembler::Fail; | |
1499 | ARM_AM::ShiftOpc Opc = ARM_AM::lsl; | |
1500 | switch( fieldFromInstruction(Insn, 5, 2)) { | |
1501 | case 0: | |
1502 | Opc = ARM_AM::lsl; | |
1503 | break; | |
1504 | case 1: | |
1505 | Opc = ARM_AM::lsr; | |
1506 | break; | |
1507 | case 2: | |
1508 | Opc = ARM_AM::asr; | |
1509 | break; | |
1510 | case 3: | |
1511 | Opc = ARM_AM::ror; | |
1512 | break; | |
1513 | default: | |
1514 | return MCDisassembler::Fail; | |
1515 | } | |
1516 | unsigned amt = fieldFromInstruction(Insn, 7, 5); | |
1517 | if (Opc == ARM_AM::ror && amt == 0) | |
1518 | Opc = ARM_AM::rrx; | |
1519 | unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode); | |
1520 | ||
1521 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
1522 | } else { | |
1523 | Inst.addOperand(MCOperand::CreateReg(0)); | |
1524 | unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode); | |
1525 | Inst.addOperand(MCOperand::CreateImm(tmp)); | |
1526 | } | |
1527 | ||
1528 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
1529 | return MCDisassembler::Fail; | |
1530 | ||
1531 | return S; | |
1532 | } | |
1533 | ||
1534 | static DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val, | |
1535 | uint64_t Address, const void *Decoder) { | |
1536 | DecodeStatus S = MCDisassembler::Success; | |
1537 | ||
1538 | unsigned Rn = fieldFromInstruction(Val, 13, 4); | |
1539 | unsigned Rm = fieldFromInstruction(Val, 0, 4); | |
1540 | unsigned type = fieldFromInstruction(Val, 5, 2); | |
1541 | unsigned imm = fieldFromInstruction(Val, 7, 5); | |
1542 | unsigned U = fieldFromInstruction(Val, 12, 1); | |
1543 | ||
1544 | ARM_AM::ShiftOpc ShOp = ARM_AM::lsl; | |
1545 | switch (type) { | |
1546 | case 0: | |
1547 | ShOp = ARM_AM::lsl; | |
1548 | break; | |
1549 | case 1: | |
1550 | ShOp = ARM_AM::lsr; | |
1551 | break; | |
1552 | case 2: | |
1553 | ShOp = ARM_AM::asr; | |
1554 | break; | |
1555 | case 3: | |
1556 | ShOp = ARM_AM::ror; | |
1557 | break; | |
1558 | } | |
1559 | ||
1560 | if (ShOp == ARM_AM::ror && imm == 0) | |
1561 | ShOp = ARM_AM::rrx; | |
1562 | ||
1563 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1564 | return MCDisassembler::Fail; | |
1565 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
1566 | return MCDisassembler::Fail; | |
1567 | unsigned shift; | |
1568 | if (U) | |
1569 | shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp); | |
1570 | else | |
1571 | shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp); | |
1572 | Inst.addOperand(MCOperand::CreateImm(shift)); | |
1573 | ||
1574 | return S; | |
1575 | } | |
1576 | ||
1577 | static DecodeStatus | |
1578 | DecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn, | |
1579 | uint64_t Address, const void *Decoder) { | |
1580 | DecodeStatus S = MCDisassembler::Success; | |
1581 | ||
1582 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
1583 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
1584 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
1585 | unsigned type = fieldFromInstruction(Insn, 22, 1); | |
1586 | unsigned imm = fieldFromInstruction(Insn, 8, 4); | |
1587 | unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8; | |
1588 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
1589 | unsigned W = fieldFromInstruction(Insn, 21, 1); | |
1590 | unsigned P = fieldFromInstruction(Insn, 24, 1); | |
1591 | unsigned Rt2 = Rt + 1; | |
1592 | ||
1593 | bool writeback = (W == 1) | (P == 0); | |
1594 | ||
1595 | // For {LD,ST}RD, Rt must be even, else undefined. | |
1596 | switch (Inst.getOpcode()) { | |
1597 | case ARM::STRD: | |
1598 | case ARM::STRD_PRE: | |
1599 | case ARM::STRD_POST: | |
1600 | case ARM::LDRD: | |
1601 | case ARM::LDRD_PRE: | |
1602 | case ARM::LDRD_POST: | |
1603 | if (Rt & 0x1) S = MCDisassembler::SoftFail; | |
1604 | break; | |
1605 | default: | |
1606 | break; | |
1607 | } | |
1608 | switch (Inst.getOpcode()) { | |
1609 | case ARM::STRD: | |
1610 | case ARM::STRD_PRE: | |
1611 | case ARM::STRD_POST: | |
1612 | if (P == 0 && W == 1) | |
1613 | S = MCDisassembler::SoftFail; | |
1614 | ||
1615 | if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2)) | |
1616 | S = MCDisassembler::SoftFail; | |
1617 | if (type && Rm == 15) | |
1618 | S = MCDisassembler::SoftFail; | |
1619 | if (Rt2 == 15) | |
1620 | S = MCDisassembler::SoftFail; | |
1621 | if (!type && fieldFromInstruction(Insn, 8, 4)) | |
1622 | S = MCDisassembler::SoftFail; | |
1623 | break; | |
1624 | case ARM::STRH: | |
1625 | case ARM::STRH_PRE: | |
1626 | case ARM::STRH_POST: | |
1627 | if (Rt == 15) | |
1628 | S = MCDisassembler::SoftFail; | |
1629 | if (writeback && (Rn == 15 || Rn == Rt)) | |
1630 | S = MCDisassembler::SoftFail; | |
1631 | if (!type && Rm == 15) | |
1632 | S = MCDisassembler::SoftFail; | |
1633 | break; | |
1634 | case ARM::LDRD: | |
1635 | case ARM::LDRD_PRE: | |
1636 | case ARM::LDRD_POST: | |
1637 | if (type && Rn == 15){ | |
1638 | if (Rt2 == 15) | |
1639 | S = MCDisassembler::SoftFail; | |
1640 | break; | |
1641 | } | |
1642 | if (P == 0 && W == 1) | |
1643 | S = MCDisassembler::SoftFail; | |
1644 | if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2)) | |
1645 | S = MCDisassembler::SoftFail; | |
1646 | if (!type && writeback && Rn == 15) | |
1647 | S = MCDisassembler::SoftFail; | |
1648 | if (writeback && (Rn == Rt || Rn == Rt2)) | |
1649 | S = MCDisassembler::SoftFail; | |
1650 | break; | |
1651 | case ARM::LDRH: | |
1652 | case ARM::LDRH_PRE: | |
1653 | case ARM::LDRH_POST: | |
1654 | if (type && Rn == 15){ | |
1655 | if (Rt == 15) | |
1656 | S = MCDisassembler::SoftFail; | |
1657 | break; | |
1658 | } | |
1659 | if (Rt == 15) | |
1660 | S = MCDisassembler::SoftFail; | |
1661 | if (!type && Rm == 15) | |
1662 | S = MCDisassembler::SoftFail; | |
1663 | if (!type && writeback && (Rn == 15 || Rn == Rt)) | |
1664 | S = MCDisassembler::SoftFail; | |
1665 | break; | |
1666 | case ARM::LDRSH: | |
1667 | case ARM::LDRSH_PRE: | |
1668 | case ARM::LDRSH_POST: | |
1669 | case ARM::LDRSB: | |
1670 | case ARM::LDRSB_PRE: | |
1671 | case ARM::LDRSB_POST: | |
1672 | if (type && Rn == 15){ | |
1673 | if (Rt == 15) | |
1674 | S = MCDisassembler::SoftFail; | |
1675 | break; | |
1676 | } | |
1677 | if (type && (Rt == 15 || (writeback && Rn == Rt))) | |
1678 | S = MCDisassembler::SoftFail; | |
1679 | if (!type && (Rt == 15 || Rm == 15)) | |
1680 | S = MCDisassembler::SoftFail; | |
1681 | if (!type && writeback && (Rn == 15 || Rn == Rt)) | |
1682 | S = MCDisassembler::SoftFail; | |
1683 | break; | |
1684 | default: | |
1685 | break; | |
1686 | } | |
1687 | ||
1688 | if (writeback) { // Writeback | |
1689 | if (P) | |
1690 | U |= ARMII::IndexModePre << 9; | |
1691 | else | |
1692 | U |= ARMII::IndexModePost << 9; | |
1693 | ||
1694 | // On stores, the writeback operand precedes Rt. | |
1695 | switch (Inst.getOpcode()) { | |
1696 | case ARM::STRD: | |
1697 | case ARM::STRD_PRE: | |
1698 | case ARM::STRD_POST: | |
1699 | case ARM::STRH: | |
1700 | case ARM::STRH_PRE: | |
1701 | case ARM::STRH_POST: | |
1702 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1703 | return MCDisassembler::Fail; | |
1704 | break; | |
1705 | default: | |
1706 | break; | |
1707 | } | |
1708 | } | |
1709 | ||
1710 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
1711 | return MCDisassembler::Fail; | |
1712 | switch (Inst.getOpcode()) { | |
1713 | case ARM::STRD: | |
1714 | case ARM::STRD_PRE: | |
1715 | case ARM::STRD_POST: | |
1716 | case ARM::LDRD: | |
1717 | case ARM::LDRD_PRE: | |
1718 | case ARM::LDRD_POST: | |
1719 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) | |
1720 | return MCDisassembler::Fail; | |
1721 | break; | |
1722 | default: | |
1723 | break; | |
1724 | } | |
1725 | ||
1726 | if (writeback) { | |
1727 | // On loads, the writeback operand comes after Rt. | |
1728 | switch (Inst.getOpcode()) { | |
1729 | case ARM::LDRD: | |
1730 | case ARM::LDRD_PRE: | |
1731 | case ARM::LDRD_POST: | |
1732 | case ARM::LDRH: | |
1733 | case ARM::LDRH_PRE: | |
1734 | case ARM::LDRH_POST: | |
1735 | case ARM::LDRSH: | |
1736 | case ARM::LDRSH_PRE: | |
1737 | case ARM::LDRSH_POST: | |
1738 | case ARM::LDRSB: | |
1739 | case ARM::LDRSB_PRE: | |
1740 | case ARM::LDRSB_POST: | |
1741 | case ARM::LDRHTr: | |
1742 | case ARM::LDRSBTr: | |
1743 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1744 | return MCDisassembler::Fail; | |
1745 | break; | |
1746 | default: | |
1747 | break; | |
1748 | } | |
1749 | } | |
1750 | ||
1751 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1752 | return MCDisassembler::Fail; | |
1753 | ||
1754 | if (type) { | |
1755 | Inst.addOperand(MCOperand::CreateReg(0)); | |
1756 | Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm)); | |
1757 | } else { | |
1758 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
1759 | return MCDisassembler::Fail; | |
1760 | Inst.addOperand(MCOperand::CreateImm(U)); | |
1761 | } | |
1762 | ||
1763 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
1764 | return MCDisassembler::Fail; | |
1765 | ||
1766 | return S; | |
1767 | } | |
1768 | ||
1769 | static DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn, | |
1770 | uint64_t Address, const void *Decoder) { | |
1771 | DecodeStatus S = MCDisassembler::Success; | |
1772 | ||
1773 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
1774 | unsigned mode = fieldFromInstruction(Insn, 23, 2); | |
1775 | ||
1776 | switch (mode) { | |
1777 | case 0: | |
1778 | mode = ARM_AM::da; | |
1779 | break; | |
1780 | case 1: | |
1781 | mode = ARM_AM::ia; | |
1782 | break; | |
1783 | case 2: | |
1784 | mode = ARM_AM::db; | |
1785 | break; | |
1786 | case 3: | |
1787 | mode = ARM_AM::ib; | |
1788 | break; | |
1789 | } | |
1790 | ||
1791 | Inst.addOperand(MCOperand::CreateImm(mode)); | |
1792 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1793 | return MCDisassembler::Fail; | |
1794 | ||
1795 | return S; | |
1796 | } | |
1797 | ||
1798 | static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst, | |
1799 | unsigned Insn, | |
1800 | uint64_t Address, const void *Decoder) { | |
1801 | DecodeStatus S = MCDisassembler::Success; | |
1802 | ||
1803 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
1804 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
1805 | unsigned reglist = fieldFromInstruction(Insn, 0, 16); | |
1806 | ||
1807 | if (pred == 0xF) { | |
1808 | switch (Inst.getOpcode()) { | |
1809 | case ARM::LDMDA: | |
1810 | Inst.setOpcode(ARM::RFEDA); | |
1811 | break; | |
1812 | case ARM::LDMDA_UPD: | |
1813 | Inst.setOpcode(ARM::RFEDA_UPD); | |
1814 | break; | |
1815 | case ARM::LDMDB: | |
1816 | Inst.setOpcode(ARM::RFEDB); | |
1817 | break; | |
1818 | case ARM::LDMDB_UPD: | |
1819 | Inst.setOpcode(ARM::RFEDB_UPD); | |
1820 | break; | |
1821 | case ARM::LDMIA: | |
1822 | Inst.setOpcode(ARM::RFEIA); | |
1823 | break; | |
1824 | case ARM::LDMIA_UPD: | |
1825 | Inst.setOpcode(ARM::RFEIA_UPD); | |
1826 | break; | |
1827 | case ARM::LDMIB: | |
1828 | Inst.setOpcode(ARM::RFEIB); | |
1829 | break; | |
1830 | case ARM::LDMIB_UPD: | |
1831 | Inst.setOpcode(ARM::RFEIB_UPD); | |
1832 | break; | |
1833 | case ARM::STMDA: | |
1834 | Inst.setOpcode(ARM::SRSDA); | |
1835 | break; | |
1836 | case ARM::STMDA_UPD: | |
1837 | Inst.setOpcode(ARM::SRSDA_UPD); | |
1838 | break; | |
1839 | case ARM::STMDB: | |
1840 | Inst.setOpcode(ARM::SRSDB); | |
1841 | break; | |
1842 | case ARM::STMDB_UPD: | |
1843 | Inst.setOpcode(ARM::SRSDB_UPD); | |
1844 | break; | |
1845 | case ARM::STMIA: | |
1846 | Inst.setOpcode(ARM::SRSIA); | |
1847 | break; | |
1848 | case ARM::STMIA_UPD: | |
1849 | Inst.setOpcode(ARM::SRSIA_UPD); | |
1850 | break; | |
1851 | case ARM::STMIB: | |
1852 | Inst.setOpcode(ARM::SRSIB); | |
1853 | break; | |
1854 | case ARM::STMIB_UPD: | |
1855 | Inst.setOpcode(ARM::SRSIB_UPD); | |
1856 | break; | |
1857 | default: | |
1858 | if (!Check(S, MCDisassembler::Fail)) return MCDisassembler::Fail; | |
1859 | } | |
1860 | ||
1861 | // For stores (which become SRS's, the only operand is the mode. | |
1862 | if (fieldFromInstruction(Insn, 20, 1) == 0) { | |
1863 | Inst.addOperand( | |
1864 | MCOperand::CreateImm(fieldFromInstruction(Insn, 0, 4))); | |
1865 | return S; | |
1866 | } | |
1867 | ||
1868 | return DecodeRFEInstruction(Inst, Insn, Address, Decoder); | |
1869 | } | |
1870 | ||
1871 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1872 | return MCDisassembler::Fail; | |
1873 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
1874 | return MCDisassembler::Fail; // Tied | |
1875 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
1876 | return MCDisassembler::Fail; | |
1877 | if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder))) | |
1878 | return MCDisassembler::Fail; | |
1879 | ||
1880 | return S; | |
1881 | } | |
1882 | ||
1883 | static DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn, | |
1884 | uint64_t Address, const void *Decoder) { | |
1885 | unsigned imod = fieldFromInstruction(Insn, 18, 2); | |
1886 | unsigned M = fieldFromInstruction(Insn, 17, 1); | |
1887 | unsigned iflags = fieldFromInstruction(Insn, 6, 3); | |
1888 | unsigned mode = fieldFromInstruction(Insn, 0, 5); | |
1889 | ||
1890 | DecodeStatus S = MCDisassembler::Success; | |
1891 | ||
1892 | // imod == '01' --> UNPREDICTABLE | |
1893 | // NOTE: Even though this is technically UNPREDICTABLE, we choose to | |
1894 | // return failure here. The '01' imod value is unprintable, so there's | |
1895 | // nothing useful we could do even if we returned UNPREDICTABLE. | |
1896 | ||
1897 | if (imod == 1) return MCDisassembler::Fail; | |
1898 | ||
1899 | if (imod && M) { | |
1900 | Inst.setOpcode(ARM::CPS3p); | |
1901 | Inst.addOperand(MCOperand::CreateImm(imod)); | |
1902 | Inst.addOperand(MCOperand::CreateImm(iflags)); | |
1903 | Inst.addOperand(MCOperand::CreateImm(mode)); | |
1904 | } else if (imod && !M) { | |
1905 | Inst.setOpcode(ARM::CPS2p); | |
1906 | Inst.addOperand(MCOperand::CreateImm(imod)); | |
1907 | Inst.addOperand(MCOperand::CreateImm(iflags)); | |
1908 | if (mode) S = MCDisassembler::SoftFail; | |
1909 | } else if (!imod && M) { | |
1910 | Inst.setOpcode(ARM::CPS1p); | |
1911 | Inst.addOperand(MCOperand::CreateImm(mode)); | |
1912 | if (iflags) S = MCDisassembler::SoftFail; | |
1913 | } else { | |
1914 | // imod == '00' && M == '0' --> UNPREDICTABLE | |
1915 | Inst.setOpcode(ARM::CPS1p); | |
1916 | Inst.addOperand(MCOperand::CreateImm(mode)); | |
1917 | S = MCDisassembler::SoftFail; | |
1918 | } | |
1919 | ||
1920 | return S; | |
1921 | } | |
1922 | ||
1923 | static DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn, | |
1924 | uint64_t Address, const void *Decoder) { | |
1925 | unsigned imod = fieldFromInstruction(Insn, 9, 2); | |
1926 | unsigned M = fieldFromInstruction(Insn, 8, 1); | |
1927 | unsigned iflags = fieldFromInstruction(Insn, 5, 3); | |
1928 | unsigned mode = fieldFromInstruction(Insn, 0, 5); | |
1929 | ||
1930 | DecodeStatus S = MCDisassembler::Success; | |
1931 | ||
1932 | // imod == '01' --> UNPREDICTABLE | |
1933 | // NOTE: Even though this is technically UNPREDICTABLE, we choose to | |
1934 | // return failure here. The '01' imod value is unprintable, so there's | |
1935 | // nothing useful we could do even if we returned UNPREDICTABLE. | |
1936 | ||
1937 | if (imod == 1) return MCDisassembler::Fail; | |
1938 | ||
1939 | if (imod && M) { | |
1940 | Inst.setOpcode(ARM::t2CPS3p); | |
1941 | Inst.addOperand(MCOperand::CreateImm(imod)); | |
1942 | Inst.addOperand(MCOperand::CreateImm(iflags)); | |
1943 | Inst.addOperand(MCOperand::CreateImm(mode)); | |
1944 | } else if (imod && !M) { | |
1945 | Inst.setOpcode(ARM::t2CPS2p); | |
1946 | Inst.addOperand(MCOperand::CreateImm(imod)); | |
1947 | Inst.addOperand(MCOperand::CreateImm(iflags)); | |
1948 | if (mode) S = MCDisassembler::SoftFail; | |
1949 | } else if (!imod && M) { | |
1950 | Inst.setOpcode(ARM::t2CPS1p); | |
1951 | Inst.addOperand(MCOperand::CreateImm(mode)); | |
1952 | if (iflags) S = MCDisassembler::SoftFail; | |
1953 | } else { | |
1954 | // imod == '00' && M == '0' --> UNPREDICTABLE | |
1955 | Inst.setOpcode(ARM::t2CPS1p); | |
1956 | Inst.addOperand(MCOperand::CreateImm(mode)); | |
1957 | S = MCDisassembler::SoftFail; | |
1958 | } | |
1959 | ||
1960 | return S; | |
1961 | } | |
1962 | ||
1963 | static DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn, | |
1964 | uint64_t Address, const void *Decoder) { | |
1965 | DecodeStatus S = MCDisassembler::Success; | |
1966 | ||
1967 | unsigned Rd = fieldFromInstruction(Insn, 8, 4); | |
1968 | unsigned imm = 0; | |
1969 | ||
1970 | imm |= (fieldFromInstruction(Insn, 0, 8) << 0); | |
1971 | imm |= (fieldFromInstruction(Insn, 12, 3) << 8); | |
1972 | imm |= (fieldFromInstruction(Insn, 16, 4) << 12); | |
1973 | imm |= (fieldFromInstruction(Insn, 26, 1) << 11); | |
1974 | ||
1975 | if (Inst.getOpcode() == ARM::t2MOVTi16) | |
1976 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) | |
1977 | return MCDisassembler::Fail; | |
1978 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) | |
1979 | return MCDisassembler::Fail; | |
1980 | ||
1981 | if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) | |
1982 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
1983 | ||
1984 | return S; | |
1985 | } | |
1986 | ||
1987 | static DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn, | |
1988 | uint64_t Address, const void *Decoder) { | |
1989 | DecodeStatus S = MCDisassembler::Success; | |
1990 | ||
1991 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
1992 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
1993 | unsigned imm = 0; | |
1994 | ||
1995 | imm |= (fieldFromInstruction(Insn, 0, 12) << 0); | |
1996 | imm |= (fieldFromInstruction(Insn, 16, 4) << 12); | |
1997 | ||
1998 | if (Inst.getOpcode() == ARM::MOVTi16) | |
1999 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2000 | return MCDisassembler::Fail; | |
2001 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2002 | return MCDisassembler::Fail; | |
2003 | ||
2004 | if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder)) | |
2005 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
2006 | ||
2007 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
2008 | return MCDisassembler::Fail; | |
2009 | ||
2010 | return S; | |
2011 | } | |
2012 | ||
2013 | static DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn, | |
2014 | uint64_t Address, const void *Decoder) { | |
2015 | DecodeStatus S = MCDisassembler::Success; | |
2016 | ||
2017 | unsigned Rd = fieldFromInstruction(Insn, 16, 4); | |
2018 | unsigned Rn = fieldFromInstruction(Insn, 0, 4); | |
2019 | unsigned Rm = fieldFromInstruction(Insn, 8, 4); | |
2020 | unsigned Ra = fieldFromInstruction(Insn, 12, 4); | |
2021 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
2022 | ||
2023 | if (pred == 0xF) | |
2024 | return DecodeCPSInstruction(Inst, Insn, Address, Decoder); | |
2025 | ||
2026 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) | |
2027 | return MCDisassembler::Fail; | |
2028 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) | |
2029 | return MCDisassembler::Fail; | |
2030 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) | |
2031 | return MCDisassembler::Fail; | |
2032 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder))) | |
2033 | return MCDisassembler::Fail; | |
2034 | ||
2035 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
2036 | return MCDisassembler::Fail; | |
2037 | ||
2038 | return S; | |
2039 | } | |
2040 | ||
2041 | static DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val, | |
2042 | uint64_t Address, const void *Decoder) { | |
2043 | DecodeStatus S = MCDisassembler::Success; | |
2044 | ||
2045 | unsigned add = fieldFromInstruction(Val, 12, 1); | |
2046 | unsigned imm = fieldFromInstruction(Val, 0, 12); | |
2047 | unsigned Rn = fieldFromInstruction(Val, 13, 4); | |
2048 | ||
2049 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
2050 | return MCDisassembler::Fail; | |
2051 | ||
2052 | if (!add) imm *= -1; | |
2053 | if (imm == 0 && !add) imm = INT32_MIN; | |
2054 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
2055 | if (Rn == 15) | |
2056 | tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder); | |
2057 | ||
2058 | return S; | |
2059 | } | |
2060 | ||
2061 | static DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val, | |
2062 | uint64_t Address, const void *Decoder) { | |
2063 | DecodeStatus S = MCDisassembler::Success; | |
2064 | ||
2065 | unsigned Rn = fieldFromInstruction(Val, 9, 4); | |
2066 | unsigned U = fieldFromInstruction(Val, 8, 1); | |
2067 | unsigned imm = fieldFromInstruction(Val, 0, 8); | |
2068 | ||
2069 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
2070 | return MCDisassembler::Fail; | |
2071 | ||
2072 | if (U) | |
2073 | Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm))); | |
2074 | else | |
2075 | Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm))); | |
2076 | ||
2077 | return S; | |
2078 | } | |
2079 | ||
2080 | static DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val, | |
2081 | uint64_t Address, const void *Decoder) { | |
2082 | return DecodeGPRRegisterClass(Inst, Val, Address, Decoder); | |
2083 | } | |
2084 | ||
2085 | static DecodeStatus | |
2086 | DecodeT2BInstruction(MCInst &Inst, unsigned Insn, | |
2087 | uint64_t Address, const void *Decoder) { | |
970d7e83 LB |
2088 | DecodeStatus Status = MCDisassembler::Success; |
2089 | ||
2090 | // Note the J1 and J2 values are from the encoded instruction. So here | |
2091 | // change them to I1 and I2 values via as documented: | |
2092 | // I1 = NOT(J1 EOR S); | |
2093 | // I2 = NOT(J2 EOR S); | |
2094 | // and build the imm32 with one trailing zero as documented: | |
2095 | // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); | |
2096 | unsigned S = fieldFromInstruction(Insn, 26, 1); | |
2097 | unsigned J1 = fieldFromInstruction(Insn, 13, 1); | |
2098 | unsigned J2 = fieldFromInstruction(Insn, 11, 1); | |
2099 | unsigned I1 = !(J1 ^ S); | |
2100 | unsigned I2 = !(J2 ^ S); | |
2101 | unsigned imm10 = fieldFromInstruction(Insn, 16, 10); | |
2102 | unsigned imm11 = fieldFromInstruction(Insn, 0, 11); | |
2103 | unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11; | |
2104 | int imm32 = SignExtend32<24>(tmp << 1); | |
2105 | if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4, | |
223e47cc | 2106 | true, 4, Inst, Decoder)) |
970d7e83 LB |
2107 | Inst.addOperand(MCOperand::CreateImm(imm32)); |
2108 | ||
2109 | return Status; | |
223e47cc LB |
2110 | } |
2111 | ||
2112 | static DecodeStatus | |
2113 | DecodeBranchImmInstruction(MCInst &Inst, unsigned Insn, | |
2114 | uint64_t Address, const void *Decoder) { | |
2115 | DecodeStatus S = MCDisassembler::Success; | |
2116 | ||
2117 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
2118 | unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2; | |
2119 | ||
2120 | if (pred == 0xF) { | |
2121 | Inst.setOpcode(ARM::BLXi); | |
2122 | imm |= fieldFromInstruction(Insn, 24, 1) << 1; | |
2123 | if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, | |
2124 | true, 4, Inst, Decoder)) | |
2125 | Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm))); | |
2126 | return S; | |
2127 | } | |
2128 | ||
2129 | if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8, | |
2130 | true, 4, Inst, Decoder)) | |
2131 | Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm))); | |
2132 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
2133 | return MCDisassembler::Fail; | |
2134 | ||
2135 | return S; | |
2136 | } | |
2137 | ||
2138 | ||
2139 | static DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val, | |
2140 | uint64_t Address, const void *Decoder) { | |
2141 | DecodeStatus S = MCDisassembler::Success; | |
2142 | ||
2143 | unsigned Rm = fieldFromInstruction(Val, 0, 4); | |
2144 | unsigned align = fieldFromInstruction(Val, 4, 2); | |
2145 | ||
2146 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
2147 | return MCDisassembler::Fail; | |
2148 | if (!align) | |
2149 | Inst.addOperand(MCOperand::CreateImm(0)); | |
2150 | else | |
2151 | Inst.addOperand(MCOperand::CreateImm(4 << align)); | |
2152 | ||
2153 | return S; | |
2154 | } | |
2155 | ||
2156 | static DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn, | |
2157 | uint64_t Address, const void *Decoder) { | |
2158 | DecodeStatus S = MCDisassembler::Success; | |
2159 | ||
2160 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
2161 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
2162 | unsigned wb = fieldFromInstruction(Insn, 16, 4); | |
2163 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
2164 | Rn |= fieldFromInstruction(Insn, 4, 2) << 4; | |
2165 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
2166 | ||
2167 | // First output register | |
2168 | switch (Inst.getOpcode()) { | |
2169 | case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8: | |
2170 | case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register: | |
2171 | case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register: | |
2172 | case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register: | |
2173 | case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register: | |
2174 | case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8: | |
2175 | case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register: | |
2176 | case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register: | |
2177 | case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register: | |
2178 | if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) | |
2179 | return MCDisassembler::Fail; | |
2180 | break; | |
2181 | case ARM::VLD2b16: | |
2182 | case ARM::VLD2b32: | |
2183 | case ARM::VLD2b8: | |
2184 | case ARM::VLD2b16wb_fixed: | |
2185 | case ARM::VLD2b16wb_register: | |
2186 | case ARM::VLD2b32wb_fixed: | |
2187 | case ARM::VLD2b32wb_register: | |
2188 | case ARM::VLD2b8wb_fixed: | |
2189 | case ARM::VLD2b8wb_register: | |
2190 | if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) | |
2191 | return MCDisassembler::Fail; | |
2192 | break; | |
2193 | default: | |
2194 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2195 | return MCDisassembler::Fail; | |
2196 | } | |
2197 | ||
2198 | // Second output register | |
2199 | switch (Inst.getOpcode()) { | |
2200 | case ARM::VLD3d8: | |
2201 | case ARM::VLD3d16: | |
2202 | case ARM::VLD3d32: | |
2203 | case ARM::VLD3d8_UPD: | |
2204 | case ARM::VLD3d16_UPD: | |
2205 | case ARM::VLD3d32_UPD: | |
2206 | case ARM::VLD4d8: | |
2207 | case ARM::VLD4d16: | |
2208 | case ARM::VLD4d32: | |
2209 | case ARM::VLD4d8_UPD: | |
2210 | case ARM::VLD4d16_UPD: | |
2211 | case ARM::VLD4d32_UPD: | |
2212 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) | |
2213 | return MCDisassembler::Fail; | |
2214 | break; | |
2215 | case ARM::VLD3q8: | |
2216 | case ARM::VLD3q16: | |
2217 | case ARM::VLD3q32: | |
2218 | case ARM::VLD3q8_UPD: | |
2219 | case ARM::VLD3q16_UPD: | |
2220 | case ARM::VLD3q32_UPD: | |
2221 | case ARM::VLD4q8: | |
2222 | case ARM::VLD4q16: | |
2223 | case ARM::VLD4q32: | |
2224 | case ARM::VLD4q8_UPD: | |
2225 | case ARM::VLD4q16_UPD: | |
2226 | case ARM::VLD4q32_UPD: | |
2227 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) | |
2228 | return MCDisassembler::Fail; | |
2229 | default: | |
2230 | break; | |
2231 | } | |
2232 | ||
2233 | // Third output register | |
2234 | switch(Inst.getOpcode()) { | |
2235 | case ARM::VLD3d8: | |
2236 | case ARM::VLD3d16: | |
2237 | case ARM::VLD3d32: | |
2238 | case ARM::VLD3d8_UPD: | |
2239 | case ARM::VLD3d16_UPD: | |
2240 | case ARM::VLD3d32_UPD: | |
2241 | case ARM::VLD4d8: | |
2242 | case ARM::VLD4d16: | |
2243 | case ARM::VLD4d32: | |
2244 | case ARM::VLD4d8_UPD: | |
2245 | case ARM::VLD4d16_UPD: | |
2246 | case ARM::VLD4d32_UPD: | |
2247 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) | |
2248 | return MCDisassembler::Fail; | |
2249 | break; | |
2250 | case ARM::VLD3q8: | |
2251 | case ARM::VLD3q16: | |
2252 | case ARM::VLD3q32: | |
2253 | case ARM::VLD3q8_UPD: | |
2254 | case ARM::VLD3q16_UPD: | |
2255 | case ARM::VLD3q32_UPD: | |
2256 | case ARM::VLD4q8: | |
2257 | case ARM::VLD4q16: | |
2258 | case ARM::VLD4q32: | |
2259 | case ARM::VLD4q8_UPD: | |
2260 | case ARM::VLD4q16_UPD: | |
2261 | case ARM::VLD4q32_UPD: | |
2262 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) | |
2263 | return MCDisassembler::Fail; | |
2264 | break; | |
2265 | default: | |
2266 | break; | |
2267 | } | |
2268 | ||
2269 | // Fourth output register | |
2270 | switch (Inst.getOpcode()) { | |
2271 | case ARM::VLD4d8: | |
2272 | case ARM::VLD4d16: | |
2273 | case ARM::VLD4d32: | |
2274 | case ARM::VLD4d8_UPD: | |
2275 | case ARM::VLD4d16_UPD: | |
2276 | case ARM::VLD4d32_UPD: | |
2277 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder))) | |
2278 | return MCDisassembler::Fail; | |
2279 | break; | |
2280 | case ARM::VLD4q8: | |
2281 | case ARM::VLD4q16: | |
2282 | case ARM::VLD4q32: | |
2283 | case ARM::VLD4q8_UPD: | |
2284 | case ARM::VLD4q16_UPD: | |
2285 | case ARM::VLD4q32_UPD: | |
2286 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) | |
2287 | return MCDisassembler::Fail; | |
2288 | break; | |
2289 | default: | |
2290 | break; | |
2291 | } | |
2292 | ||
2293 | // Writeback operand | |
2294 | switch (Inst.getOpcode()) { | |
2295 | case ARM::VLD1d8wb_fixed: | |
2296 | case ARM::VLD1d16wb_fixed: | |
2297 | case ARM::VLD1d32wb_fixed: | |
2298 | case ARM::VLD1d64wb_fixed: | |
2299 | case ARM::VLD1d8wb_register: | |
2300 | case ARM::VLD1d16wb_register: | |
2301 | case ARM::VLD1d32wb_register: | |
2302 | case ARM::VLD1d64wb_register: | |
2303 | case ARM::VLD1q8wb_fixed: | |
2304 | case ARM::VLD1q16wb_fixed: | |
2305 | case ARM::VLD1q32wb_fixed: | |
2306 | case ARM::VLD1q64wb_fixed: | |
2307 | case ARM::VLD1q8wb_register: | |
2308 | case ARM::VLD1q16wb_register: | |
2309 | case ARM::VLD1q32wb_register: | |
2310 | case ARM::VLD1q64wb_register: | |
2311 | case ARM::VLD1d8Twb_fixed: | |
2312 | case ARM::VLD1d8Twb_register: | |
2313 | case ARM::VLD1d16Twb_fixed: | |
2314 | case ARM::VLD1d16Twb_register: | |
2315 | case ARM::VLD1d32Twb_fixed: | |
2316 | case ARM::VLD1d32Twb_register: | |
2317 | case ARM::VLD1d64Twb_fixed: | |
2318 | case ARM::VLD1d64Twb_register: | |
2319 | case ARM::VLD1d8Qwb_fixed: | |
2320 | case ARM::VLD1d8Qwb_register: | |
2321 | case ARM::VLD1d16Qwb_fixed: | |
2322 | case ARM::VLD1d16Qwb_register: | |
2323 | case ARM::VLD1d32Qwb_fixed: | |
2324 | case ARM::VLD1d32Qwb_register: | |
2325 | case ARM::VLD1d64Qwb_fixed: | |
2326 | case ARM::VLD1d64Qwb_register: | |
2327 | case ARM::VLD2d8wb_fixed: | |
2328 | case ARM::VLD2d16wb_fixed: | |
2329 | case ARM::VLD2d32wb_fixed: | |
2330 | case ARM::VLD2q8wb_fixed: | |
2331 | case ARM::VLD2q16wb_fixed: | |
2332 | case ARM::VLD2q32wb_fixed: | |
2333 | case ARM::VLD2d8wb_register: | |
2334 | case ARM::VLD2d16wb_register: | |
2335 | case ARM::VLD2d32wb_register: | |
2336 | case ARM::VLD2q8wb_register: | |
2337 | case ARM::VLD2q16wb_register: | |
2338 | case ARM::VLD2q32wb_register: | |
2339 | case ARM::VLD2b8wb_fixed: | |
2340 | case ARM::VLD2b16wb_fixed: | |
2341 | case ARM::VLD2b32wb_fixed: | |
2342 | case ARM::VLD2b8wb_register: | |
2343 | case ARM::VLD2b16wb_register: | |
2344 | case ARM::VLD2b32wb_register: | |
2345 | Inst.addOperand(MCOperand::CreateImm(0)); | |
2346 | break; | |
2347 | case ARM::VLD3d8_UPD: | |
2348 | case ARM::VLD3d16_UPD: | |
2349 | case ARM::VLD3d32_UPD: | |
2350 | case ARM::VLD3q8_UPD: | |
2351 | case ARM::VLD3q16_UPD: | |
2352 | case ARM::VLD3q32_UPD: | |
2353 | case ARM::VLD4d8_UPD: | |
2354 | case ARM::VLD4d16_UPD: | |
2355 | case ARM::VLD4d32_UPD: | |
2356 | case ARM::VLD4q8_UPD: | |
2357 | case ARM::VLD4q16_UPD: | |
2358 | case ARM::VLD4q32_UPD: | |
2359 | if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) | |
2360 | return MCDisassembler::Fail; | |
2361 | break; | |
2362 | default: | |
2363 | break; | |
2364 | } | |
2365 | ||
2366 | // AddrMode6 Base (register+alignment) | |
2367 | if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) | |
2368 | return MCDisassembler::Fail; | |
2369 | ||
2370 | // AddrMode6 Offset (register) | |
2371 | switch (Inst.getOpcode()) { | |
2372 | default: | |
2373 | // The below have been updated to have explicit am6offset split | |
2374 | // between fixed and register offset. For those instructions not | |
2375 | // yet updated, we need to add an additional reg0 operand for the | |
2376 | // fixed variant. | |
2377 | // | |
2378 | // The fixed offset encodes as Rm == 0xd, so we check for that. | |
2379 | if (Rm == 0xd) { | |
2380 | Inst.addOperand(MCOperand::CreateReg(0)); | |
2381 | break; | |
2382 | } | |
2383 | // Fall through to handle the register offset variant. | |
2384 | case ARM::VLD1d8wb_fixed: | |
2385 | case ARM::VLD1d16wb_fixed: | |
2386 | case ARM::VLD1d32wb_fixed: | |
2387 | case ARM::VLD1d64wb_fixed: | |
2388 | case ARM::VLD1d8Twb_fixed: | |
2389 | case ARM::VLD1d16Twb_fixed: | |
2390 | case ARM::VLD1d32Twb_fixed: | |
2391 | case ARM::VLD1d64Twb_fixed: | |
2392 | case ARM::VLD1d8Qwb_fixed: | |
2393 | case ARM::VLD1d16Qwb_fixed: | |
2394 | case ARM::VLD1d32Qwb_fixed: | |
2395 | case ARM::VLD1d64Qwb_fixed: | |
2396 | case ARM::VLD1d8wb_register: | |
2397 | case ARM::VLD1d16wb_register: | |
2398 | case ARM::VLD1d32wb_register: | |
2399 | case ARM::VLD1d64wb_register: | |
2400 | case ARM::VLD1q8wb_fixed: | |
2401 | case ARM::VLD1q16wb_fixed: | |
2402 | case ARM::VLD1q32wb_fixed: | |
2403 | case ARM::VLD1q64wb_fixed: | |
2404 | case ARM::VLD1q8wb_register: | |
2405 | case ARM::VLD1q16wb_register: | |
2406 | case ARM::VLD1q32wb_register: | |
2407 | case ARM::VLD1q64wb_register: | |
2408 | // The fixed offset post-increment encodes Rm == 0xd. The no-writeback | |
2409 | // variant encodes Rm == 0xf. Anything else is a register offset post- | |
2410 | // increment and we need to add the register operand to the instruction. | |
2411 | if (Rm != 0xD && Rm != 0xF && | |
2412 | !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
2413 | return MCDisassembler::Fail; | |
2414 | break; | |
2415 | case ARM::VLD2d8wb_fixed: | |
2416 | case ARM::VLD2d16wb_fixed: | |
2417 | case ARM::VLD2d32wb_fixed: | |
2418 | case ARM::VLD2b8wb_fixed: | |
2419 | case ARM::VLD2b16wb_fixed: | |
2420 | case ARM::VLD2b32wb_fixed: | |
2421 | case ARM::VLD2q8wb_fixed: | |
2422 | case ARM::VLD2q16wb_fixed: | |
2423 | case ARM::VLD2q32wb_fixed: | |
2424 | break; | |
2425 | } | |
2426 | ||
2427 | return S; | |
2428 | } | |
2429 | ||
2430 | static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn, | |
2431 | uint64_t Address, const void *Decoder) { | |
2432 | DecodeStatus S = MCDisassembler::Success; | |
2433 | ||
2434 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
2435 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
2436 | unsigned wb = fieldFromInstruction(Insn, 16, 4); | |
2437 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
2438 | Rn |= fieldFromInstruction(Insn, 4, 2) << 4; | |
2439 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
2440 | ||
2441 | // Writeback Operand | |
2442 | switch (Inst.getOpcode()) { | |
2443 | case ARM::VST1d8wb_fixed: | |
2444 | case ARM::VST1d16wb_fixed: | |
2445 | case ARM::VST1d32wb_fixed: | |
2446 | case ARM::VST1d64wb_fixed: | |
2447 | case ARM::VST1d8wb_register: | |
2448 | case ARM::VST1d16wb_register: | |
2449 | case ARM::VST1d32wb_register: | |
2450 | case ARM::VST1d64wb_register: | |
2451 | case ARM::VST1q8wb_fixed: | |
2452 | case ARM::VST1q16wb_fixed: | |
2453 | case ARM::VST1q32wb_fixed: | |
2454 | case ARM::VST1q64wb_fixed: | |
2455 | case ARM::VST1q8wb_register: | |
2456 | case ARM::VST1q16wb_register: | |
2457 | case ARM::VST1q32wb_register: | |
2458 | case ARM::VST1q64wb_register: | |
2459 | case ARM::VST1d8Twb_fixed: | |
2460 | case ARM::VST1d16Twb_fixed: | |
2461 | case ARM::VST1d32Twb_fixed: | |
2462 | case ARM::VST1d64Twb_fixed: | |
2463 | case ARM::VST1d8Twb_register: | |
2464 | case ARM::VST1d16Twb_register: | |
2465 | case ARM::VST1d32Twb_register: | |
2466 | case ARM::VST1d64Twb_register: | |
2467 | case ARM::VST1d8Qwb_fixed: | |
2468 | case ARM::VST1d16Qwb_fixed: | |
2469 | case ARM::VST1d32Qwb_fixed: | |
2470 | case ARM::VST1d64Qwb_fixed: | |
2471 | case ARM::VST1d8Qwb_register: | |
2472 | case ARM::VST1d16Qwb_register: | |
2473 | case ARM::VST1d32Qwb_register: | |
2474 | case ARM::VST1d64Qwb_register: | |
2475 | case ARM::VST2d8wb_fixed: | |
2476 | case ARM::VST2d16wb_fixed: | |
2477 | case ARM::VST2d32wb_fixed: | |
2478 | case ARM::VST2d8wb_register: | |
2479 | case ARM::VST2d16wb_register: | |
2480 | case ARM::VST2d32wb_register: | |
2481 | case ARM::VST2q8wb_fixed: | |
2482 | case ARM::VST2q16wb_fixed: | |
2483 | case ARM::VST2q32wb_fixed: | |
2484 | case ARM::VST2q8wb_register: | |
2485 | case ARM::VST2q16wb_register: | |
2486 | case ARM::VST2q32wb_register: | |
2487 | case ARM::VST2b8wb_fixed: | |
2488 | case ARM::VST2b16wb_fixed: | |
2489 | case ARM::VST2b32wb_fixed: | |
2490 | case ARM::VST2b8wb_register: | |
2491 | case ARM::VST2b16wb_register: | |
2492 | case ARM::VST2b32wb_register: | |
2493 | if (Rm == 0xF) | |
2494 | return MCDisassembler::Fail; | |
2495 | Inst.addOperand(MCOperand::CreateImm(0)); | |
2496 | break; | |
2497 | case ARM::VST3d8_UPD: | |
2498 | case ARM::VST3d16_UPD: | |
2499 | case ARM::VST3d32_UPD: | |
2500 | case ARM::VST3q8_UPD: | |
2501 | case ARM::VST3q16_UPD: | |
2502 | case ARM::VST3q32_UPD: | |
2503 | case ARM::VST4d8_UPD: | |
2504 | case ARM::VST4d16_UPD: | |
2505 | case ARM::VST4d32_UPD: | |
2506 | case ARM::VST4q8_UPD: | |
2507 | case ARM::VST4q16_UPD: | |
2508 | case ARM::VST4q32_UPD: | |
2509 | if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder))) | |
2510 | return MCDisassembler::Fail; | |
2511 | break; | |
2512 | default: | |
2513 | break; | |
2514 | } | |
2515 | ||
2516 | // AddrMode6 Base (register+alignment) | |
2517 | if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder))) | |
2518 | return MCDisassembler::Fail; | |
2519 | ||
2520 | // AddrMode6 Offset (register) | |
2521 | switch (Inst.getOpcode()) { | |
2522 | default: | |
2523 | if (Rm == 0xD) | |
2524 | Inst.addOperand(MCOperand::CreateReg(0)); | |
2525 | else if (Rm != 0xF) { | |
2526 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
2527 | return MCDisassembler::Fail; | |
2528 | } | |
2529 | break; | |
2530 | case ARM::VST1d8wb_fixed: | |
2531 | case ARM::VST1d16wb_fixed: | |
2532 | case ARM::VST1d32wb_fixed: | |
2533 | case ARM::VST1d64wb_fixed: | |
2534 | case ARM::VST1q8wb_fixed: | |
2535 | case ARM::VST1q16wb_fixed: | |
2536 | case ARM::VST1q32wb_fixed: | |
2537 | case ARM::VST1q64wb_fixed: | |
2538 | case ARM::VST1d8Twb_fixed: | |
2539 | case ARM::VST1d16Twb_fixed: | |
2540 | case ARM::VST1d32Twb_fixed: | |
2541 | case ARM::VST1d64Twb_fixed: | |
2542 | case ARM::VST1d8Qwb_fixed: | |
2543 | case ARM::VST1d16Qwb_fixed: | |
2544 | case ARM::VST1d32Qwb_fixed: | |
2545 | case ARM::VST1d64Qwb_fixed: | |
2546 | case ARM::VST2d8wb_fixed: | |
2547 | case ARM::VST2d16wb_fixed: | |
2548 | case ARM::VST2d32wb_fixed: | |
2549 | case ARM::VST2q8wb_fixed: | |
2550 | case ARM::VST2q16wb_fixed: | |
2551 | case ARM::VST2q32wb_fixed: | |
2552 | case ARM::VST2b8wb_fixed: | |
2553 | case ARM::VST2b16wb_fixed: | |
2554 | case ARM::VST2b32wb_fixed: | |
2555 | break; | |
2556 | } | |
2557 | ||
2558 | ||
2559 | // First input register | |
2560 | switch (Inst.getOpcode()) { | |
2561 | case ARM::VST1q16: | |
2562 | case ARM::VST1q32: | |
2563 | case ARM::VST1q64: | |
2564 | case ARM::VST1q8: | |
2565 | case ARM::VST1q16wb_fixed: | |
2566 | case ARM::VST1q16wb_register: | |
2567 | case ARM::VST1q32wb_fixed: | |
2568 | case ARM::VST1q32wb_register: | |
2569 | case ARM::VST1q64wb_fixed: | |
2570 | case ARM::VST1q64wb_register: | |
2571 | case ARM::VST1q8wb_fixed: | |
2572 | case ARM::VST1q8wb_register: | |
2573 | case ARM::VST2d16: | |
2574 | case ARM::VST2d32: | |
2575 | case ARM::VST2d8: | |
2576 | case ARM::VST2d16wb_fixed: | |
2577 | case ARM::VST2d16wb_register: | |
2578 | case ARM::VST2d32wb_fixed: | |
2579 | case ARM::VST2d32wb_register: | |
2580 | case ARM::VST2d8wb_fixed: | |
2581 | case ARM::VST2d8wb_register: | |
2582 | if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) | |
2583 | return MCDisassembler::Fail; | |
2584 | break; | |
2585 | case ARM::VST2b16: | |
2586 | case ARM::VST2b32: | |
2587 | case ARM::VST2b8: | |
2588 | case ARM::VST2b16wb_fixed: | |
2589 | case ARM::VST2b16wb_register: | |
2590 | case ARM::VST2b32wb_fixed: | |
2591 | case ARM::VST2b32wb_register: | |
2592 | case ARM::VST2b8wb_fixed: | |
2593 | case ARM::VST2b8wb_register: | |
2594 | if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) | |
2595 | return MCDisassembler::Fail; | |
2596 | break; | |
2597 | default: | |
2598 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2599 | return MCDisassembler::Fail; | |
2600 | } | |
2601 | ||
2602 | // Second input register | |
2603 | switch (Inst.getOpcode()) { | |
2604 | case ARM::VST3d8: | |
2605 | case ARM::VST3d16: | |
2606 | case ARM::VST3d32: | |
2607 | case ARM::VST3d8_UPD: | |
2608 | case ARM::VST3d16_UPD: | |
2609 | case ARM::VST3d32_UPD: | |
2610 | case ARM::VST4d8: | |
2611 | case ARM::VST4d16: | |
2612 | case ARM::VST4d32: | |
2613 | case ARM::VST4d8_UPD: | |
2614 | case ARM::VST4d16_UPD: | |
2615 | case ARM::VST4d32_UPD: | |
2616 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder))) | |
2617 | return MCDisassembler::Fail; | |
2618 | break; | |
2619 | case ARM::VST3q8: | |
2620 | case ARM::VST3q16: | |
2621 | case ARM::VST3q32: | |
2622 | case ARM::VST3q8_UPD: | |
2623 | case ARM::VST3q16_UPD: | |
2624 | case ARM::VST3q32_UPD: | |
2625 | case ARM::VST4q8: | |
2626 | case ARM::VST4q16: | |
2627 | case ARM::VST4q32: | |
2628 | case ARM::VST4q8_UPD: | |
2629 | case ARM::VST4q16_UPD: | |
2630 | case ARM::VST4q32_UPD: | |
2631 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) | |
2632 | return MCDisassembler::Fail; | |
2633 | break; | |
2634 | default: | |
2635 | break; | |
2636 | } | |
2637 | ||
2638 | // Third input register | |
2639 | switch (Inst.getOpcode()) { | |
2640 | case ARM::VST3d8: | |
2641 | case ARM::VST3d16: | |
2642 | case ARM::VST3d32: | |
2643 | case ARM::VST3d8_UPD: | |
2644 | case ARM::VST3d16_UPD: | |
2645 | case ARM::VST3d32_UPD: | |
2646 | case ARM::VST4d8: | |
2647 | case ARM::VST4d16: | |
2648 | case ARM::VST4d32: | |
2649 | case ARM::VST4d8_UPD: | |
2650 | case ARM::VST4d16_UPD: | |
2651 | case ARM::VST4d32_UPD: | |
2652 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder))) | |
2653 | return MCDisassembler::Fail; | |
2654 | break; | |
2655 | case ARM::VST3q8: | |
2656 | case ARM::VST3q16: | |
2657 | case ARM::VST3q32: | |
2658 | case ARM::VST3q8_UPD: | |
2659 | case ARM::VST3q16_UPD: | |
2660 | case ARM::VST3q32_UPD: | |
2661 | case ARM::VST4q8: | |
2662 | case ARM::VST4q16: | |
2663 | case ARM::VST4q32: | |
2664 | case ARM::VST4q8_UPD: | |
2665 | case ARM::VST4q16_UPD: | |
2666 | case ARM::VST4q32_UPD: | |
2667 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder))) | |
2668 | return MCDisassembler::Fail; | |
2669 | break; | |
2670 | default: | |
2671 | break; | |
2672 | } | |
2673 | ||
2674 | // Fourth input register | |
2675 | switch (Inst.getOpcode()) { | |
2676 | case ARM::VST4d8: | |
2677 | case ARM::VST4d16: | |
2678 | case ARM::VST4d32: | |
2679 | case ARM::VST4d8_UPD: | |
2680 | case ARM::VST4d16_UPD: | |
2681 | case ARM::VST4d32_UPD: | |
2682 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder))) | |
2683 | return MCDisassembler::Fail; | |
2684 | break; | |
2685 | case ARM::VST4q8: | |
2686 | case ARM::VST4q16: | |
2687 | case ARM::VST4q32: | |
2688 | case ARM::VST4q8_UPD: | |
2689 | case ARM::VST4q16_UPD: | |
2690 | case ARM::VST4q32_UPD: | |
2691 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder))) | |
2692 | return MCDisassembler::Fail; | |
2693 | break; | |
2694 | default: | |
2695 | break; | |
2696 | } | |
2697 | ||
2698 | return S; | |
2699 | } | |
2700 | ||
2701 | static DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn, | |
2702 | uint64_t Address, const void *Decoder) { | |
2703 | DecodeStatus S = MCDisassembler::Success; | |
2704 | ||
2705 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
2706 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
2707 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
2708 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
2709 | unsigned align = fieldFromInstruction(Insn, 4, 1); | |
2710 | unsigned size = fieldFromInstruction(Insn, 6, 2); | |
2711 | ||
2712 | if (size == 0 && align == 1) | |
2713 | return MCDisassembler::Fail; | |
2714 | align *= (1 << size); | |
2715 | ||
2716 | switch (Inst.getOpcode()) { | |
2717 | case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8: | |
2718 | case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register: | |
2719 | case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register: | |
2720 | case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register: | |
2721 | if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) | |
2722 | return MCDisassembler::Fail; | |
2723 | break; | |
2724 | default: | |
2725 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2726 | return MCDisassembler::Fail; | |
2727 | break; | |
2728 | } | |
2729 | if (Rm != 0xF) { | |
2730 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
2731 | return MCDisassembler::Fail; | |
2732 | } | |
2733 | ||
2734 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
2735 | return MCDisassembler::Fail; | |
2736 | Inst.addOperand(MCOperand::CreateImm(align)); | |
2737 | ||
2738 | // The fixed offset post-increment encodes Rm == 0xd. The no-writeback | |
2739 | // variant encodes Rm == 0xf. Anything else is a register offset post- | |
2740 | // increment and we need to add the register operand to the instruction. | |
2741 | if (Rm != 0xD && Rm != 0xF && | |
2742 | !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
2743 | return MCDisassembler::Fail; | |
2744 | ||
2745 | return S; | |
2746 | } | |
2747 | ||
2748 | static DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn, | |
2749 | uint64_t Address, const void *Decoder) { | |
2750 | DecodeStatus S = MCDisassembler::Success; | |
2751 | ||
2752 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
2753 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
2754 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
2755 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
2756 | unsigned align = fieldFromInstruction(Insn, 4, 1); | |
2757 | unsigned size = 1 << fieldFromInstruction(Insn, 6, 2); | |
2758 | align *= 2*size; | |
2759 | ||
2760 | switch (Inst.getOpcode()) { | |
2761 | case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8: | |
2762 | case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register: | |
2763 | case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register: | |
2764 | case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register: | |
2765 | if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder))) | |
2766 | return MCDisassembler::Fail; | |
2767 | break; | |
2768 | case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2: | |
2769 | case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register: | |
2770 | case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register: | |
2771 | case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register: | |
2772 | if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder))) | |
2773 | return MCDisassembler::Fail; | |
2774 | break; | |
2775 | default: | |
2776 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2777 | return MCDisassembler::Fail; | |
2778 | break; | |
2779 | } | |
2780 | ||
2781 | if (Rm != 0xF) | |
2782 | Inst.addOperand(MCOperand::CreateImm(0)); | |
2783 | ||
2784 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
2785 | return MCDisassembler::Fail; | |
2786 | Inst.addOperand(MCOperand::CreateImm(align)); | |
2787 | ||
2788 | if (Rm != 0xD && Rm != 0xF) { | |
2789 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
2790 | return MCDisassembler::Fail; | |
2791 | } | |
2792 | ||
2793 | return S; | |
2794 | } | |
2795 | ||
2796 | static DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn, | |
2797 | uint64_t Address, const void *Decoder) { | |
2798 | DecodeStatus S = MCDisassembler::Success; | |
2799 | ||
2800 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
2801 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
2802 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
2803 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
2804 | unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1; | |
2805 | ||
2806 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2807 | return MCDisassembler::Fail; | |
2808 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) | |
2809 | return MCDisassembler::Fail; | |
2810 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) | |
2811 | return MCDisassembler::Fail; | |
2812 | if (Rm != 0xF) { | |
2813 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
2814 | return MCDisassembler::Fail; | |
2815 | } | |
2816 | ||
2817 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
2818 | return MCDisassembler::Fail; | |
2819 | Inst.addOperand(MCOperand::CreateImm(0)); | |
2820 | ||
2821 | if (Rm == 0xD) | |
2822 | Inst.addOperand(MCOperand::CreateReg(0)); | |
2823 | else if (Rm != 0xF) { | |
2824 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
2825 | return MCDisassembler::Fail; | |
2826 | } | |
2827 | ||
2828 | return S; | |
2829 | } | |
2830 | ||
2831 | static DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn, | |
2832 | uint64_t Address, const void *Decoder) { | |
2833 | DecodeStatus S = MCDisassembler::Success; | |
2834 | ||
2835 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
2836 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
2837 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
2838 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
2839 | unsigned size = fieldFromInstruction(Insn, 6, 2); | |
2840 | unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1; | |
2841 | unsigned align = fieldFromInstruction(Insn, 4, 1); | |
2842 | ||
2843 | if (size == 0x3) { | |
2844 | if (align == 0) | |
2845 | return MCDisassembler::Fail; | |
2846 | size = 4; | |
2847 | align = 16; | |
2848 | } else { | |
2849 | if (size == 2) { | |
2850 | size = 1 << size; | |
2851 | align *= 8; | |
2852 | } else { | |
2853 | size = 1 << size; | |
2854 | align *= 4*size; | |
2855 | } | |
2856 | } | |
2857 | ||
2858 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2859 | return MCDisassembler::Fail; | |
2860 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder))) | |
2861 | return MCDisassembler::Fail; | |
2862 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))) | |
2863 | return MCDisassembler::Fail; | |
2864 | if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder))) | |
2865 | return MCDisassembler::Fail; | |
2866 | if (Rm != 0xF) { | |
2867 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
2868 | return MCDisassembler::Fail; | |
2869 | } | |
2870 | ||
2871 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
2872 | return MCDisassembler::Fail; | |
2873 | Inst.addOperand(MCOperand::CreateImm(align)); | |
2874 | ||
2875 | if (Rm == 0xD) | |
2876 | Inst.addOperand(MCOperand::CreateReg(0)); | |
2877 | else if (Rm != 0xF) { | |
2878 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
2879 | return MCDisassembler::Fail; | |
2880 | } | |
2881 | ||
2882 | return S; | |
2883 | } | |
2884 | ||
2885 | static DecodeStatus | |
2886 | DecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn, | |
2887 | uint64_t Address, const void *Decoder) { | |
2888 | DecodeStatus S = MCDisassembler::Success; | |
2889 | ||
2890 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
2891 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
2892 | unsigned imm = fieldFromInstruction(Insn, 0, 4); | |
2893 | imm |= fieldFromInstruction(Insn, 16, 3) << 4; | |
2894 | imm |= fieldFromInstruction(Insn, 24, 1) << 7; | |
2895 | imm |= fieldFromInstruction(Insn, 8, 4) << 8; | |
2896 | imm |= fieldFromInstruction(Insn, 5, 1) << 12; | |
2897 | unsigned Q = fieldFromInstruction(Insn, 6, 1); | |
2898 | ||
2899 | if (Q) { | |
2900 | if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2901 | return MCDisassembler::Fail; | |
2902 | } else { | |
2903 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2904 | return MCDisassembler::Fail; | |
2905 | } | |
2906 | ||
2907 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
2908 | ||
2909 | switch (Inst.getOpcode()) { | |
2910 | case ARM::VORRiv4i16: | |
2911 | case ARM::VORRiv2i32: | |
2912 | case ARM::VBICiv4i16: | |
2913 | case ARM::VBICiv2i32: | |
2914 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2915 | return MCDisassembler::Fail; | |
2916 | break; | |
2917 | case ARM::VORRiv8i16: | |
2918 | case ARM::VORRiv4i32: | |
2919 | case ARM::VBICiv8i16: | |
2920 | case ARM::VBICiv4i32: | |
2921 | if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2922 | return MCDisassembler::Fail; | |
2923 | break; | |
2924 | default: | |
2925 | break; | |
2926 | } | |
2927 | ||
2928 | return S; | |
2929 | } | |
2930 | ||
2931 | static DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn, | |
2932 | uint64_t Address, const void *Decoder) { | |
2933 | DecodeStatus S = MCDisassembler::Success; | |
2934 | ||
2935 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
2936 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
2937 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
2938 | Rm |= fieldFromInstruction(Insn, 5, 1) << 4; | |
2939 | unsigned size = fieldFromInstruction(Insn, 18, 2); | |
2940 | ||
2941 | if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2942 | return MCDisassembler::Fail; | |
2943 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) | |
2944 | return MCDisassembler::Fail; | |
2945 | Inst.addOperand(MCOperand::CreateImm(8 << size)); | |
2946 | ||
2947 | return S; | |
2948 | } | |
2949 | ||
2950 | static DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val, | |
2951 | uint64_t Address, const void *Decoder) { | |
2952 | Inst.addOperand(MCOperand::CreateImm(8 - Val)); | |
2953 | return MCDisassembler::Success; | |
2954 | } | |
2955 | ||
2956 | static DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val, | |
2957 | uint64_t Address, const void *Decoder) { | |
2958 | Inst.addOperand(MCOperand::CreateImm(16 - Val)); | |
2959 | return MCDisassembler::Success; | |
2960 | } | |
2961 | ||
2962 | static DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val, | |
2963 | uint64_t Address, const void *Decoder) { | |
2964 | Inst.addOperand(MCOperand::CreateImm(32 - Val)); | |
2965 | return MCDisassembler::Success; | |
2966 | } | |
2967 | ||
2968 | static DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val, | |
2969 | uint64_t Address, const void *Decoder) { | |
2970 | Inst.addOperand(MCOperand::CreateImm(64 - Val)); | |
2971 | return MCDisassembler::Success; | |
2972 | } | |
2973 | ||
2974 | static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, | |
2975 | uint64_t Address, const void *Decoder) { | |
2976 | DecodeStatus S = MCDisassembler::Success; | |
2977 | ||
2978 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
2979 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
2980 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
2981 | Rn |= fieldFromInstruction(Insn, 7, 1) << 4; | |
2982 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
2983 | Rm |= fieldFromInstruction(Insn, 5, 1) << 4; | |
2984 | unsigned op = fieldFromInstruction(Insn, 6, 1); | |
2985 | ||
2986 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2987 | return MCDisassembler::Fail; | |
2988 | if (op) { | |
2989 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
2990 | return MCDisassembler::Fail; // Writeback | |
2991 | } | |
2992 | ||
2993 | switch (Inst.getOpcode()) { | |
2994 | case ARM::VTBL2: | |
2995 | case ARM::VTBX2: | |
2996 | if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder))) | |
2997 | return MCDisassembler::Fail; | |
2998 | break; | |
2999 | default: | |
3000 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3001 | return MCDisassembler::Fail; | |
3002 | } | |
3003 | ||
3004 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder))) | |
3005 | return MCDisassembler::Fail; | |
3006 | ||
3007 | return S; | |
3008 | } | |
3009 | ||
3010 | static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn, | |
3011 | uint64_t Address, const void *Decoder) { | |
3012 | DecodeStatus S = MCDisassembler::Success; | |
3013 | ||
3014 | unsigned dst = fieldFromInstruction(Insn, 8, 3); | |
3015 | unsigned imm = fieldFromInstruction(Insn, 0, 8); | |
3016 | ||
3017 | if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder))) | |
3018 | return MCDisassembler::Fail; | |
3019 | ||
3020 | switch(Inst.getOpcode()) { | |
3021 | default: | |
3022 | return MCDisassembler::Fail; | |
3023 | case ARM::tADR: | |
3024 | break; // tADR does not explicitly represent the PC as an operand. | |
3025 | case ARM::tADDrSPi: | |
3026 | Inst.addOperand(MCOperand::CreateReg(ARM::SP)); | |
3027 | break; | |
3028 | } | |
3029 | ||
3030 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3031 | return S; | |
3032 | } | |
3033 | ||
3034 | static DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val, | |
3035 | uint64_t Address, const void *Decoder) { | |
3036 | if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4, | |
3037 | true, 2, Inst, Decoder)) | |
3038 | Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1))); | |
3039 | return MCDisassembler::Success; | |
3040 | } | |
3041 | ||
3042 | static DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val, | |
3043 | uint64_t Address, const void *Decoder) { | |
3044 | if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4, | |
3045 | true, 4, Inst, Decoder)) | |
3046 | Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val))); | |
3047 | return MCDisassembler::Success; | |
3048 | } | |
3049 | ||
3050 | static DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val, | |
3051 | uint64_t Address, const void *Decoder) { | |
3052 | if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<7>(Val<<1) + 4, | |
3053 | true, 2, Inst, Decoder)) | |
3054 | Inst.addOperand(MCOperand::CreateImm(SignExtend32<7>(Val << 1))); | |
3055 | return MCDisassembler::Success; | |
3056 | } | |
3057 | ||
3058 | static DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val, | |
3059 | uint64_t Address, const void *Decoder) { | |
3060 | DecodeStatus S = MCDisassembler::Success; | |
3061 | ||
3062 | unsigned Rn = fieldFromInstruction(Val, 0, 3); | |
3063 | unsigned Rm = fieldFromInstruction(Val, 3, 3); | |
3064 | ||
3065 | if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3066 | return MCDisassembler::Fail; | |
3067 | if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
3068 | return MCDisassembler::Fail; | |
3069 | ||
3070 | return S; | |
3071 | } | |
3072 | ||
3073 | static DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val, | |
3074 | uint64_t Address, const void *Decoder) { | |
3075 | DecodeStatus S = MCDisassembler::Success; | |
3076 | ||
3077 | unsigned Rn = fieldFromInstruction(Val, 0, 3); | |
3078 | unsigned imm = fieldFromInstruction(Val, 3, 5); | |
3079 | ||
3080 | if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3081 | return MCDisassembler::Fail; | |
3082 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3083 | ||
3084 | return S; | |
3085 | } | |
3086 | ||
3087 | static DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val, | |
3088 | uint64_t Address, const void *Decoder) { | |
3089 | unsigned imm = Val << 2; | |
3090 | ||
3091 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3092 | tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder); | |
3093 | ||
3094 | return MCDisassembler::Success; | |
3095 | } | |
3096 | ||
3097 | static DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val, | |
3098 | uint64_t Address, const void *Decoder) { | |
3099 | Inst.addOperand(MCOperand::CreateReg(ARM::SP)); | |
3100 | Inst.addOperand(MCOperand::CreateImm(Val)); | |
3101 | ||
3102 | return MCDisassembler::Success; | |
3103 | } | |
3104 | ||
3105 | static DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val, | |
3106 | uint64_t Address, const void *Decoder) { | |
3107 | DecodeStatus S = MCDisassembler::Success; | |
3108 | ||
3109 | unsigned Rn = fieldFromInstruction(Val, 6, 4); | |
3110 | unsigned Rm = fieldFromInstruction(Val, 2, 4); | |
3111 | unsigned imm = fieldFromInstruction(Val, 0, 2); | |
3112 | ||
3113 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3114 | return MCDisassembler::Fail; | |
3115 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
3116 | return MCDisassembler::Fail; | |
3117 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3118 | ||
3119 | return S; | |
3120 | } | |
3121 | ||
3122 | static DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn, | |
3123 | uint64_t Address, const void *Decoder) { | |
3124 | DecodeStatus S = MCDisassembler::Success; | |
3125 | ||
3126 | switch (Inst.getOpcode()) { | |
3127 | case ARM::t2PLDs: | |
3128 | case ARM::t2PLDWs: | |
3129 | case ARM::t2PLIs: | |
3130 | break; | |
3131 | default: { | |
3132 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
3133 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
3134 | return MCDisassembler::Fail; | |
3135 | } | |
3136 | } | |
3137 | ||
3138 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3139 | if (Rn == 0xF) { | |
3140 | switch (Inst.getOpcode()) { | |
3141 | case ARM::t2LDRBs: | |
3142 | Inst.setOpcode(ARM::t2LDRBpci); | |
3143 | break; | |
3144 | case ARM::t2LDRHs: | |
3145 | Inst.setOpcode(ARM::t2LDRHpci); | |
3146 | break; | |
3147 | case ARM::t2LDRSHs: | |
3148 | Inst.setOpcode(ARM::t2LDRSHpci); | |
3149 | break; | |
3150 | case ARM::t2LDRSBs: | |
3151 | Inst.setOpcode(ARM::t2LDRSBpci); | |
3152 | break; | |
3153 | case ARM::t2PLDs: | |
3154 | Inst.setOpcode(ARM::t2PLDi12); | |
3155 | Inst.addOperand(MCOperand::CreateReg(ARM::PC)); | |
3156 | break; | |
3157 | default: | |
3158 | return MCDisassembler::Fail; | |
3159 | } | |
3160 | ||
3161 | int imm = fieldFromInstruction(Insn, 0, 12); | |
3162 | if (!fieldFromInstruction(Insn, 23, 1)) imm *= -1; | |
3163 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3164 | ||
3165 | return S; | |
3166 | } | |
3167 | ||
3168 | unsigned addrmode = fieldFromInstruction(Insn, 4, 2); | |
3169 | addrmode |= fieldFromInstruction(Insn, 0, 4) << 2; | |
3170 | addrmode |= fieldFromInstruction(Insn, 16, 4) << 6; | |
3171 | if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder))) | |
3172 | return MCDisassembler::Fail; | |
3173 | ||
3174 | return S; | |
3175 | } | |
3176 | ||
3177 | static DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val, | |
3178 | uint64_t Address, const void *Decoder) { | |
3179 | if (Val == 0) | |
3180 | Inst.addOperand(MCOperand::CreateImm(INT32_MIN)); | |
3181 | else { | |
3182 | int imm = Val & 0xFF; | |
3183 | ||
3184 | if (!(Val & 0x100)) imm *= -1; | |
3185 | Inst.addOperand(MCOperand::CreateImm(imm * 4)); | |
3186 | } | |
3187 | ||
3188 | return MCDisassembler::Success; | |
3189 | } | |
3190 | ||
3191 | static DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val, | |
3192 | uint64_t Address, const void *Decoder) { | |
3193 | DecodeStatus S = MCDisassembler::Success; | |
3194 | ||
3195 | unsigned Rn = fieldFromInstruction(Val, 9, 4); | |
3196 | unsigned imm = fieldFromInstruction(Val, 0, 9); | |
3197 | ||
3198 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3199 | return MCDisassembler::Fail; | |
3200 | if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder))) | |
3201 | return MCDisassembler::Fail; | |
3202 | ||
3203 | return S; | |
3204 | } | |
3205 | ||
3206 | static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, | |
3207 | uint64_t Address, const void *Decoder) { | |
3208 | DecodeStatus S = MCDisassembler::Success; | |
3209 | ||
3210 | unsigned Rn = fieldFromInstruction(Val, 8, 4); | |
3211 | unsigned imm = fieldFromInstruction(Val, 0, 8); | |
3212 | ||
3213 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) | |
3214 | return MCDisassembler::Fail; | |
3215 | ||
3216 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3217 | ||
3218 | return S; | |
3219 | } | |
3220 | ||
3221 | static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, | |
3222 | uint64_t Address, const void *Decoder) { | |
3223 | int imm = Val & 0xFF; | |
3224 | if (Val == 0) | |
3225 | imm = INT32_MIN; | |
3226 | else if (!(Val & 0x100)) | |
3227 | imm *= -1; | |
3228 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3229 | ||
3230 | return MCDisassembler::Success; | |
3231 | } | |
3232 | ||
3233 | ||
3234 | static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, | |
3235 | uint64_t Address, const void *Decoder) { | |
3236 | DecodeStatus S = MCDisassembler::Success; | |
3237 | ||
3238 | unsigned Rn = fieldFromInstruction(Val, 9, 4); | |
3239 | unsigned imm = fieldFromInstruction(Val, 0, 9); | |
3240 | ||
3241 | // Some instructions always use an additive offset. | |
3242 | switch (Inst.getOpcode()) { | |
3243 | case ARM::t2LDRT: | |
3244 | case ARM::t2LDRBT: | |
3245 | case ARM::t2LDRHT: | |
3246 | case ARM::t2LDRSBT: | |
3247 | case ARM::t2LDRSHT: | |
3248 | case ARM::t2STRT: | |
3249 | case ARM::t2STRBT: | |
3250 | case ARM::t2STRHT: | |
3251 | imm |= 0x100; | |
3252 | break; | |
3253 | default: | |
3254 | break; | |
3255 | } | |
3256 | ||
3257 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3258 | return MCDisassembler::Fail; | |
3259 | if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder))) | |
3260 | return MCDisassembler::Fail; | |
3261 | ||
3262 | return S; | |
3263 | } | |
3264 | ||
3265 | static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn, | |
3266 | uint64_t Address, const void *Decoder) { | |
3267 | DecodeStatus S = MCDisassembler::Success; | |
3268 | ||
3269 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
3270 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3271 | unsigned addr = fieldFromInstruction(Insn, 0, 8); | |
3272 | addr |= fieldFromInstruction(Insn, 9, 1) << 8; | |
3273 | addr |= Rn << 9; | |
3274 | unsigned load = fieldFromInstruction(Insn, 20, 1); | |
3275 | ||
3276 | if (!load) { | |
3277 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3278 | return MCDisassembler::Fail; | |
3279 | } | |
3280 | ||
3281 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
3282 | return MCDisassembler::Fail; | |
3283 | ||
3284 | if (load) { | |
3285 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3286 | return MCDisassembler::Fail; | |
3287 | } | |
3288 | ||
3289 | if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder))) | |
3290 | return MCDisassembler::Fail; | |
3291 | ||
3292 | return S; | |
3293 | } | |
3294 | ||
3295 | static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val, | |
3296 | uint64_t Address, const void *Decoder) { | |
3297 | DecodeStatus S = MCDisassembler::Success; | |
3298 | ||
3299 | unsigned Rn = fieldFromInstruction(Val, 13, 4); | |
3300 | unsigned imm = fieldFromInstruction(Val, 0, 12); | |
3301 | ||
3302 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3303 | return MCDisassembler::Fail; | |
3304 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3305 | ||
3306 | return S; | |
3307 | } | |
3308 | ||
3309 | ||
3310 | static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn, | |
3311 | uint64_t Address, const void *Decoder) { | |
3312 | unsigned imm = fieldFromInstruction(Insn, 0, 7); | |
3313 | ||
3314 | Inst.addOperand(MCOperand::CreateReg(ARM::SP)); | |
3315 | Inst.addOperand(MCOperand::CreateReg(ARM::SP)); | |
3316 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3317 | ||
3318 | return MCDisassembler::Success; | |
3319 | } | |
3320 | ||
3321 | static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, | |
3322 | uint64_t Address, const void *Decoder) { | |
3323 | DecodeStatus S = MCDisassembler::Success; | |
3324 | ||
3325 | if (Inst.getOpcode() == ARM::tADDrSP) { | |
3326 | unsigned Rdm = fieldFromInstruction(Insn, 0, 3); | |
3327 | Rdm |= fieldFromInstruction(Insn, 7, 1) << 3; | |
3328 | ||
3329 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) | |
3330 | return MCDisassembler::Fail; | |
3331 | Inst.addOperand(MCOperand::CreateReg(ARM::SP)); | |
3332 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder))) | |
3333 | return MCDisassembler::Fail; | |
3334 | } else if (Inst.getOpcode() == ARM::tADDspr) { | |
3335 | unsigned Rm = fieldFromInstruction(Insn, 3, 4); | |
3336 | ||
3337 | Inst.addOperand(MCOperand::CreateReg(ARM::SP)); | |
3338 | Inst.addOperand(MCOperand::CreateReg(ARM::SP)); | |
3339 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
3340 | return MCDisassembler::Fail; | |
3341 | } | |
3342 | ||
3343 | return S; | |
3344 | } | |
3345 | ||
3346 | static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn, | |
3347 | uint64_t Address, const void *Decoder) { | |
3348 | unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2; | |
3349 | unsigned flags = fieldFromInstruction(Insn, 0, 3); | |
3350 | ||
3351 | Inst.addOperand(MCOperand::CreateImm(imod)); | |
3352 | Inst.addOperand(MCOperand::CreateImm(flags)); | |
3353 | ||
3354 | return MCDisassembler::Success; | |
3355 | } | |
3356 | ||
3357 | static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, | |
3358 | uint64_t Address, const void *Decoder) { | |
3359 | DecodeStatus S = MCDisassembler::Success; | |
3360 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
3361 | unsigned add = fieldFromInstruction(Insn, 4, 1); | |
3362 | ||
3363 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder))) | |
3364 | return MCDisassembler::Fail; | |
3365 | Inst.addOperand(MCOperand::CreateImm(add)); | |
3366 | ||
3367 | return S; | |
3368 | } | |
3369 | ||
3370 | static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val, | |
3371 | uint64_t Address, const void *Decoder) { | |
3372 | // Val is passed in as S:J1:J2:imm10H:imm10L:'0' | |
3373 | // Note only one trailing zero not two. Also the J1 and J2 values are from | |
3374 | // the encoded instruction. So here change to I1 and I2 values via: | |
3375 | // I1 = NOT(J1 EOR S); | |
3376 | // I2 = NOT(J2 EOR S); | |
3377 | // and build the imm32 with two trailing zeros as documented: | |
3378 | // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32); | |
3379 | unsigned S = (Val >> 23) & 1; | |
3380 | unsigned J1 = (Val >> 22) & 1; | |
3381 | unsigned J2 = (Val >> 21) & 1; | |
3382 | unsigned I1 = !(J1 ^ S); | |
3383 | unsigned I2 = !(J2 ^ S); | |
3384 | unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21); | |
3385 | int imm32 = SignExtend32<25>(tmp << 1); | |
3386 | ||
3387 | if (!tryAddingSymbolicOperand(Address, | |
3388 | (Address & ~2u) + imm32 + 4, | |
3389 | true, 4, Inst, Decoder)) | |
3390 | Inst.addOperand(MCOperand::CreateImm(imm32)); | |
3391 | return MCDisassembler::Success; | |
3392 | } | |
3393 | ||
3394 | static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val, | |
3395 | uint64_t Address, const void *Decoder) { | |
3396 | if (Val == 0xA || Val == 0xB) | |
3397 | return MCDisassembler::Fail; | |
3398 | ||
3399 | Inst.addOperand(MCOperand::CreateImm(Val)); | |
3400 | return MCDisassembler::Success; | |
3401 | } | |
3402 | ||
3403 | static DecodeStatus | |
3404 | DecodeThumbTableBranch(MCInst &Inst, unsigned Insn, | |
3405 | uint64_t Address, const void *Decoder) { | |
3406 | DecodeStatus S = MCDisassembler::Success; | |
3407 | ||
3408 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3409 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
3410 | ||
3411 | if (Rn == ARM::SP) S = MCDisassembler::SoftFail; | |
3412 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3413 | return MCDisassembler::Fail; | |
3414 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
3415 | return MCDisassembler::Fail; | |
3416 | return S; | |
3417 | } | |
3418 | ||
3419 | static DecodeStatus | |
3420 | DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn, | |
3421 | uint64_t Address, const void *Decoder) { | |
3422 | DecodeStatus S = MCDisassembler::Success; | |
3423 | ||
3424 | unsigned pred = fieldFromInstruction(Insn, 22, 4); | |
3425 | if (pred == 0xE || pred == 0xF) { | |
3426 | unsigned opc = fieldFromInstruction(Insn, 4, 28); | |
3427 | switch (opc) { | |
3428 | default: | |
3429 | return MCDisassembler::Fail; | |
3430 | case 0xf3bf8f4: | |
3431 | Inst.setOpcode(ARM::t2DSB); | |
3432 | break; | |
3433 | case 0xf3bf8f5: | |
3434 | Inst.setOpcode(ARM::t2DMB); | |
3435 | break; | |
3436 | case 0xf3bf8f6: | |
3437 | Inst.setOpcode(ARM::t2ISB); | |
3438 | break; | |
3439 | } | |
3440 | ||
3441 | unsigned imm = fieldFromInstruction(Insn, 0, 4); | |
3442 | return DecodeMemBarrierOption(Inst, imm, Address, Decoder); | |
3443 | } | |
3444 | ||
3445 | unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1; | |
3446 | brtarget |= fieldFromInstruction(Insn, 11, 1) << 19; | |
3447 | brtarget |= fieldFromInstruction(Insn, 13, 1) << 18; | |
3448 | brtarget |= fieldFromInstruction(Insn, 16, 6) << 12; | |
3449 | brtarget |= fieldFromInstruction(Insn, 26, 1) << 20; | |
3450 | ||
3451 | if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder))) | |
3452 | return MCDisassembler::Fail; | |
3453 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
3454 | return MCDisassembler::Fail; | |
3455 | ||
3456 | return S; | |
3457 | } | |
3458 | ||
3459 | // Decode a shifted immediate operand. These basically consist | |
3460 | // of an 8-bit value, and a 4-bit directive that specifies either | |
3461 | // a splat operation or a rotation. | |
3462 | static DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val, | |
3463 | uint64_t Address, const void *Decoder) { | |
3464 | unsigned ctrl = fieldFromInstruction(Val, 10, 2); | |
3465 | if (ctrl == 0) { | |
3466 | unsigned byte = fieldFromInstruction(Val, 8, 2); | |
3467 | unsigned imm = fieldFromInstruction(Val, 0, 8); | |
3468 | switch (byte) { | |
3469 | case 0: | |
3470 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3471 | break; | |
3472 | case 1: | |
3473 | Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm)); | |
3474 | break; | |
3475 | case 2: | |
3476 | Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8))); | |
3477 | break; | |
3478 | case 3: | |
3479 | Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) | | |
3480 | (imm << 8) | imm)); | |
3481 | break; | |
3482 | } | |
3483 | } else { | |
3484 | unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80; | |
3485 | unsigned rot = fieldFromInstruction(Val, 7, 5); | |
3486 | unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31)); | |
3487 | Inst.addOperand(MCOperand::CreateImm(imm)); | |
3488 | } | |
3489 | ||
3490 | return MCDisassembler::Success; | |
3491 | } | |
3492 | ||
3493 | static DecodeStatus | |
3494 | DecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val, | |
3495 | uint64_t Address, const void *Decoder){ | |
3496 | if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4, | |
3497 | true, 2, Inst, Decoder)) | |
3498 | Inst.addOperand(MCOperand::CreateImm(SignExtend32<9>(Val << 1))); | |
3499 | return MCDisassembler::Success; | |
3500 | } | |
3501 | ||
3502 | static DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val, | |
3503 | uint64_t Address, const void *Decoder){ | |
3504 | // Val is passed in as S:J1:J2:imm10:imm11 | |
3505 | // Note no trailing zero after imm11. Also the J1 and J2 values are from | |
3506 | // the encoded instruction. So here change to I1 and I2 values via: | |
3507 | // I1 = NOT(J1 EOR S); | |
3508 | // I2 = NOT(J2 EOR S); | |
3509 | // and build the imm32 with one trailing zero as documented: | |
3510 | // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32); | |
3511 | unsigned S = (Val >> 23) & 1; | |
3512 | unsigned J1 = (Val >> 22) & 1; | |
3513 | unsigned J2 = (Val >> 21) & 1; | |
3514 | unsigned I1 = !(J1 ^ S); | |
3515 | unsigned I2 = !(J2 ^ S); | |
3516 | unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21); | |
3517 | int imm32 = SignExtend32<25>(tmp << 1); | |
3518 | ||
3519 | if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4, | |
3520 | true, 4, Inst, Decoder)) | |
3521 | Inst.addOperand(MCOperand::CreateImm(imm32)); | |
3522 | return MCDisassembler::Success; | |
3523 | } | |
3524 | ||
3525 | static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val, | |
3526 | uint64_t Address, const void *Decoder) { | |
3527 | if (Val & ~0xf) | |
3528 | return MCDisassembler::Fail; | |
3529 | ||
3530 | Inst.addOperand(MCOperand::CreateImm(Val)); | |
3531 | return MCDisassembler::Success; | |
3532 | } | |
3533 | ||
3534 | static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val, | |
3535 | uint64_t Address, const void *Decoder) { | |
3536 | if (!Val) return MCDisassembler::Fail; | |
3537 | Inst.addOperand(MCOperand::CreateImm(Val)); | |
3538 | return MCDisassembler::Success; | |
3539 | } | |
3540 | ||
3541 | static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, | |
3542 | uint64_t Address, const void *Decoder) { | |
3543 | DecodeStatus S = MCDisassembler::Success; | |
3544 | ||
3545 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
3546 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3547 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
3548 | ||
3549 | if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail; | |
3550 | ||
3551 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
3552 | return MCDisassembler::Fail; | |
3553 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) | |
3554 | return MCDisassembler::Fail; | |
3555 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3556 | return MCDisassembler::Fail; | |
3557 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
3558 | return MCDisassembler::Fail; | |
3559 | ||
3560 | return S; | |
3561 | } | |
3562 | ||
3563 | ||
3564 | static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, | |
3565 | uint64_t Address, const void *Decoder){ | |
3566 | DecodeStatus S = MCDisassembler::Success; | |
3567 | ||
3568 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
3569 | unsigned Rt = fieldFromInstruction(Insn, 0, 4); | |
3570 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3571 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
3572 | ||
3573 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder))) | |
3574 | return MCDisassembler::Fail; | |
3575 | ||
3576 | if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail; | |
3577 | if (Rd == Rn || Rd == Rt || Rd == Rt+1) return MCDisassembler::Fail; | |
3578 | ||
3579 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
3580 | return MCDisassembler::Fail; | |
3581 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) | |
3582 | return MCDisassembler::Fail; | |
3583 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3584 | return MCDisassembler::Fail; | |
3585 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
3586 | return MCDisassembler::Fail; | |
3587 | ||
3588 | return S; | |
3589 | } | |
3590 | ||
3591 | static DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn, | |
3592 | uint64_t Address, const void *Decoder) { | |
3593 | DecodeStatus S = MCDisassembler::Success; | |
3594 | ||
3595 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3596 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
3597 | unsigned imm = fieldFromInstruction(Insn, 0, 12); | |
3598 | imm |= fieldFromInstruction(Insn, 16, 4) << 13; | |
3599 | imm |= fieldFromInstruction(Insn, 23, 1) << 12; | |
3600 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
3601 | ||
3602 | if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; | |
3603 | ||
3604 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
3605 | return MCDisassembler::Fail; | |
3606 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3607 | return MCDisassembler::Fail; | |
3608 | if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) | |
3609 | return MCDisassembler::Fail; | |
3610 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
3611 | return MCDisassembler::Fail; | |
3612 | ||
3613 | return S; | |
3614 | } | |
3615 | ||
3616 | static DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn, | |
3617 | uint64_t Address, const void *Decoder) { | |
3618 | DecodeStatus S = MCDisassembler::Success; | |
3619 | ||
3620 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3621 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
3622 | unsigned imm = fieldFromInstruction(Insn, 0, 12); | |
3623 | imm |= fieldFromInstruction(Insn, 16, 4) << 13; | |
3624 | imm |= fieldFromInstruction(Insn, 23, 1) << 12; | |
3625 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
3626 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
3627 | ||
3628 | if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; | |
3629 | if (Rm == 0xF) S = MCDisassembler::SoftFail; | |
3630 | ||
3631 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
3632 | return MCDisassembler::Fail; | |
3633 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3634 | return MCDisassembler::Fail; | |
3635 | if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) | |
3636 | return MCDisassembler::Fail; | |
3637 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
3638 | return MCDisassembler::Fail; | |
3639 | ||
3640 | return S; | |
3641 | } | |
3642 | ||
3643 | ||
3644 | static DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn, | |
3645 | uint64_t Address, const void *Decoder) { | |
3646 | DecodeStatus S = MCDisassembler::Success; | |
3647 | ||
3648 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3649 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
3650 | unsigned imm = fieldFromInstruction(Insn, 0, 12); | |
3651 | imm |= fieldFromInstruction(Insn, 16, 4) << 13; | |
3652 | imm |= fieldFromInstruction(Insn, 23, 1) << 12; | |
3653 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
3654 | ||
3655 | if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; | |
3656 | ||
3657 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3658 | return MCDisassembler::Fail; | |
3659 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
3660 | return MCDisassembler::Fail; | |
3661 | if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder))) | |
3662 | return MCDisassembler::Fail; | |
3663 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
3664 | return MCDisassembler::Fail; | |
3665 | ||
3666 | return S; | |
3667 | } | |
3668 | ||
3669 | static DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn, | |
3670 | uint64_t Address, const void *Decoder) { | |
3671 | DecodeStatus S = MCDisassembler::Success; | |
3672 | ||
3673 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3674 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
3675 | unsigned imm = fieldFromInstruction(Insn, 0, 12); | |
3676 | imm |= fieldFromInstruction(Insn, 16, 4) << 13; | |
3677 | imm |= fieldFromInstruction(Insn, 23, 1) << 12; | |
3678 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
3679 | ||
3680 | if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail; | |
3681 | ||
3682 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3683 | return MCDisassembler::Fail; | |
3684 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
3685 | return MCDisassembler::Fail; | |
3686 | if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder))) | |
3687 | return MCDisassembler::Fail; | |
3688 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
3689 | return MCDisassembler::Fail; | |
3690 | ||
3691 | return S; | |
3692 | } | |
3693 | ||
3694 | static DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn, | |
3695 | uint64_t Address, const void *Decoder) { | |
3696 | DecodeStatus S = MCDisassembler::Success; | |
3697 | ||
3698 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3699 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
3700 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
3701 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
3702 | unsigned size = fieldFromInstruction(Insn, 10, 2); | |
3703 | ||
3704 | unsigned align = 0; | |
3705 | unsigned index = 0; | |
3706 | switch (size) { | |
3707 | default: | |
3708 | return MCDisassembler::Fail; | |
3709 | case 0: | |
3710 | if (fieldFromInstruction(Insn, 4, 1)) | |
3711 | return MCDisassembler::Fail; // UNDEFINED | |
3712 | index = fieldFromInstruction(Insn, 5, 3); | |
3713 | break; | |
3714 | case 1: | |
3715 | if (fieldFromInstruction(Insn, 5, 1)) | |
3716 | return MCDisassembler::Fail; // UNDEFINED | |
3717 | index = fieldFromInstruction(Insn, 6, 2); | |
3718 | if (fieldFromInstruction(Insn, 4, 1)) | |
3719 | align = 2; | |
3720 | break; | |
3721 | case 2: | |
3722 | if (fieldFromInstruction(Insn, 6, 1)) | |
3723 | return MCDisassembler::Fail; // UNDEFINED | |
3724 | index = fieldFromInstruction(Insn, 7, 1); | |
3725 | ||
3726 | switch (fieldFromInstruction(Insn, 4, 2)) { | |
3727 | case 0 : | |
3728 | align = 0; break; | |
3729 | case 3: | |
3730 | align = 4; break; | |
3731 | default: | |
3732 | return MCDisassembler::Fail; | |
3733 | } | |
3734 | break; | |
3735 | } | |
3736 | ||
3737 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
3738 | return MCDisassembler::Fail; | |
3739 | if (Rm != 0xF) { // Writeback | |
3740 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3741 | return MCDisassembler::Fail; | |
3742 | } | |
3743 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3744 | return MCDisassembler::Fail; | |
3745 | Inst.addOperand(MCOperand::CreateImm(align)); | |
3746 | if (Rm != 0xF) { | |
3747 | if (Rm != 0xD) { | |
3748 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
3749 | return MCDisassembler::Fail; | |
3750 | } else | |
3751 | Inst.addOperand(MCOperand::CreateReg(0)); | |
3752 | } | |
3753 | ||
3754 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
3755 | return MCDisassembler::Fail; | |
3756 | Inst.addOperand(MCOperand::CreateImm(index)); | |
3757 | ||
3758 | return S; | |
3759 | } | |
3760 | ||
3761 | static DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn, | |
3762 | uint64_t Address, const void *Decoder) { | |
3763 | DecodeStatus S = MCDisassembler::Success; | |
3764 | ||
3765 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3766 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
3767 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
3768 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
3769 | unsigned size = fieldFromInstruction(Insn, 10, 2); | |
3770 | ||
3771 | unsigned align = 0; | |
3772 | unsigned index = 0; | |
3773 | switch (size) { | |
3774 | default: | |
3775 | return MCDisassembler::Fail; | |
3776 | case 0: | |
3777 | if (fieldFromInstruction(Insn, 4, 1)) | |
3778 | return MCDisassembler::Fail; // UNDEFINED | |
3779 | index = fieldFromInstruction(Insn, 5, 3); | |
3780 | break; | |
3781 | case 1: | |
3782 | if (fieldFromInstruction(Insn, 5, 1)) | |
3783 | return MCDisassembler::Fail; // UNDEFINED | |
3784 | index = fieldFromInstruction(Insn, 6, 2); | |
3785 | if (fieldFromInstruction(Insn, 4, 1)) | |
3786 | align = 2; | |
3787 | break; | |
3788 | case 2: | |
3789 | if (fieldFromInstruction(Insn, 6, 1)) | |
3790 | return MCDisassembler::Fail; // UNDEFINED | |
3791 | index = fieldFromInstruction(Insn, 7, 1); | |
3792 | ||
3793 | switch (fieldFromInstruction(Insn, 4, 2)) { | |
3794 | case 0: | |
3795 | align = 0; break; | |
3796 | case 3: | |
3797 | align = 4; break; | |
3798 | default: | |
3799 | return MCDisassembler::Fail; | |
3800 | } | |
3801 | break; | |
3802 | } | |
3803 | ||
3804 | if (Rm != 0xF) { // Writeback | |
3805 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3806 | return MCDisassembler::Fail; | |
3807 | } | |
3808 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3809 | return MCDisassembler::Fail; | |
3810 | Inst.addOperand(MCOperand::CreateImm(align)); | |
3811 | if (Rm != 0xF) { | |
3812 | if (Rm != 0xD) { | |
3813 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
3814 | return MCDisassembler::Fail; | |
3815 | } else | |
3816 | Inst.addOperand(MCOperand::CreateReg(0)); | |
3817 | } | |
3818 | ||
3819 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
3820 | return MCDisassembler::Fail; | |
3821 | Inst.addOperand(MCOperand::CreateImm(index)); | |
3822 | ||
3823 | return S; | |
3824 | } | |
3825 | ||
3826 | ||
3827 | static DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn, | |
3828 | uint64_t Address, const void *Decoder) { | |
3829 | DecodeStatus S = MCDisassembler::Success; | |
3830 | ||
3831 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3832 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
3833 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
3834 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
3835 | unsigned size = fieldFromInstruction(Insn, 10, 2); | |
3836 | ||
3837 | unsigned align = 0; | |
3838 | unsigned index = 0; | |
3839 | unsigned inc = 1; | |
3840 | switch (size) { | |
3841 | default: | |
3842 | return MCDisassembler::Fail; | |
3843 | case 0: | |
3844 | index = fieldFromInstruction(Insn, 5, 3); | |
3845 | if (fieldFromInstruction(Insn, 4, 1)) | |
3846 | align = 2; | |
3847 | break; | |
3848 | case 1: | |
3849 | index = fieldFromInstruction(Insn, 6, 2); | |
3850 | if (fieldFromInstruction(Insn, 4, 1)) | |
3851 | align = 4; | |
3852 | if (fieldFromInstruction(Insn, 5, 1)) | |
3853 | inc = 2; | |
3854 | break; | |
3855 | case 2: | |
3856 | if (fieldFromInstruction(Insn, 5, 1)) | |
3857 | return MCDisassembler::Fail; // UNDEFINED | |
3858 | index = fieldFromInstruction(Insn, 7, 1); | |
3859 | if (fieldFromInstruction(Insn, 4, 1) != 0) | |
3860 | align = 8; | |
3861 | if (fieldFromInstruction(Insn, 6, 1)) | |
3862 | inc = 2; | |
3863 | break; | |
3864 | } | |
3865 | ||
3866 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
3867 | return MCDisassembler::Fail; | |
3868 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) | |
3869 | return MCDisassembler::Fail; | |
3870 | if (Rm != 0xF) { // Writeback | |
3871 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3872 | return MCDisassembler::Fail; | |
3873 | } | |
3874 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3875 | return MCDisassembler::Fail; | |
3876 | Inst.addOperand(MCOperand::CreateImm(align)); | |
3877 | if (Rm != 0xF) { | |
3878 | if (Rm != 0xD) { | |
3879 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
3880 | return MCDisassembler::Fail; | |
3881 | } else | |
3882 | Inst.addOperand(MCOperand::CreateReg(0)); | |
3883 | } | |
3884 | ||
3885 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
3886 | return MCDisassembler::Fail; | |
3887 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) | |
3888 | return MCDisassembler::Fail; | |
3889 | Inst.addOperand(MCOperand::CreateImm(index)); | |
3890 | ||
3891 | return S; | |
3892 | } | |
3893 | ||
3894 | static DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn, | |
3895 | uint64_t Address, const void *Decoder) { | |
3896 | DecodeStatus S = MCDisassembler::Success; | |
3897 | ||
3898 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3899 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
3900 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
3901 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
3902 | unsigned size = fieldFromInstruction(Insn, 10, 2); | |
3903 | ||
3904 | unsigned align = 0; | |
3905 | unsigned index = 0; | |
3906 | unsigned inc = 1; | |
3907 | switch (size) { | |
3908 | default: | |
3909 | return MCDisassembler::Fail; | |
3910 | case 0: | |
3911 | index = fieldFromInstruction(Insn, 5, 3); | |
3912 | if (fieldFromInstruction(Insn, 4, 1)) | |
3913 | align = 2; | |
3914 | break; | |
3915 | case 1: | |
3916 | index = fieldFromInstruction(Insn, 6, 2); | |
3917 | if (fieldFromInstruction(Insn, 4, 1)) | |
3918 | align = 4; | |
3919 | if (fieldFromInstruction(Insn, 5, 1)) | |
3920 | inc = 2; | |
3921 | break; | |
3922 | case 2: | |
3923 | if (fieldFromInstruction(Insn, 5, 1)) | |
3924 | return MCDisassembler::Fail; // UNDEFINED | |
3925 | index = fieldFromInstruction(Insn, 7, 1); | |
3926 | if (fieldFromInstruction(Insn, 4, 1) != 0) | |
3927 | align = 8; | |
3928 | if (fieldFromInstruction(Insn, 6, 1)) | |
3929 | inc = 2; | |
3930 | break; | |
3931 | } | |
3932 | ||
3933 | if (Rm != 0xF) { // Writeback | |
3934 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3935 | return MCDisassembler::Fail; | |
3936 | } | |
3937 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
3938 | return MCDisassembler::Fail; | |
3939 | Inst.addOperand(MCOperand::CreateImm(align)); | |
3940 | if (Rm != 0xF) { | |
3941 | if (Rm != 0xD) { | |
3942 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
3943 | return MCDisassembler::Fail; | |
3944 | } else | |
3945 | Inst.addOperand(MCOperand::CreateReg(0)); | |
3946 | } | |
3947 | ||
3948 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
3949 | return MCDisassembler::Fail; | |
3950 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) | |
3951 | return MCDisassembler::Fail; | |
3952 | Inst.addOperand(MCOperand::CreateImm(index)); | |
3953 | ||
3954 | return S; | |
3955 | } | |
3956 | ||
3957 | ||
3958 | static DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn, | |
3959 | uint64_t Address, const void *Decoder) { | |
3960 | DecodeStatus S = MCDisassembler::Success; | |
3961 | ||
3962 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
3963 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
3964 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
3965 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
3966 | unsigned size = fieldFromInstruction(Insn, 10, 2); | |
3967 | ||
3968 | unsigned align = 0; | |
3969 | unsigned index = 0; | |
3970 | unsigned inc = 1; | |
3971 | switch (size) { | |
3972 | default: | |
3973 | return MCDisassembler::Fail; | |
3974 | case 0: | |
3975 | if (fieldFromInstruction(Insn, 4, 1)) | |
3976 | return MCDisassembler::Fail; // UNDEFINED | |
3977 | index = fieldFromInstruction(Insn, 5, 3); | |
3978 | break; | |
3979 | case 1: | |
3980 | if (fieldFromInstruction(Insn, 4, 1)) | |
3981 | return MCDisassembler::Fail; // UNDEFINED | |
3982 | index = fieldFromInstruction(Insn, 6, 2); | |
3983 | if (fieldFromInstruction(Insn, 5, 1)) | |
3984 | inc = 2; | |
3985 | break; | |
3986 | case 2: | |
3987 | if (fieldFromInstruction(Insn, 4, 2)) | |
3988 | return MCDisassembler::Fail; // UNDEFINED | |
3989 | index = fieldFromInstruction(Insn, 7, 1); | |
3990 | if (fieldFromInstruction(Insn, 6, 1)) | |
3991 | inc = 2; | |
3992 | break; | |
3993 | } | |
3994 | ||
3995 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
3996 | return MCDisassembler::Fail; | |
3997 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) | |
3998 | return MCDisassembler::Fail; | |
3999 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) | |
4000 | return MCDisassembler::Fail; | |
4001 | ||
4002 | if (Rm != 0xF) { // Writeback | |
4003 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4004 | return MCDisassembler::Fail; | |
4005 | } | |
4006 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4007 | return MCDisassembler::Fail; | |
4008 | Inst.addOperand(MCOperand::CreateImm(align)); | |
4009 | if (Rm != 0xF) { | |
4010 | if (Rm != 0xD) { | |
4011 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
4012 | return MCDisassembler::Fail; | |
4013 | } else | |
4014 | Inst.addOperand(MCOperand::CreateReg(0)); | |
4015 | } | |
4016 | ||
4017 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
4018 | return MCDisassembler::Fail; | |
4019 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) | |
4020 | return MCDisassembler::Fail; | |
4021 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) | |
4022 | return MCDisassembler::Fail; | |
4023 | Inst.addOperand(MCOperand::CreateImm(index)); | |
4024 | ||
4025 | return S; | |
4026 | } | |
4027 | ||
4028 | static DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn, | |
4029 | uint64_t Address, const void *Decoder) { | |
4030 | DecodeStatus S = MCDisassembler::Success; | |
4031 | ||
4032 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
4033 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
4034 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
4035 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
4036 | unsigned size = fieldFromInstruction(Insn, 10, 2); | |
4037 | ||
4038 | unsigned align = 0; | |
4039 | unsigned index = 0; | |
4040 | unsigned inc = 1; | |
4041 | switch (size) { | |
4042 | default: | |
4043 | return MCDisassembler::Fail; | |
4044 | case 0: | |
4045 | if (fieldFromInstruction(Insn, 4, 1)) | |
4046 | return MCDisassembler::Fail; // UNDEFINED | |
4047 | index = fieldFromInstruction(Insn, 5, 3); | |
4048 | break; | |
4049 | case 1: | |
4050 | if (fieldFromInstruction(Insn, 4, 1)) | |
4051 | return MCDisassembler::Fail; // UNDEFINED | |
4052 | index = fieldFromInstruction(Insn, 6, 2); | |
4053 | if (fieldFromInstruction(Insn, 5, 1)) | |
4054 | inc = 2; | |
4055 | break; | |
4056 | case 2: | |
4057 | if (fieldFromInstruction(Insn, 4, 2)) | |
4058 | return MCDisassembler::Fail; // UNDEFINED | |
4059 | index = fieldFromInstruction(Insn, 7, 1); | |
4060 | if (fieldFromInstruction(Insn, 6, 1)) | |
4061 | inc = 2; | |
4062 | break; | |
4063 | } | |
4064 | ||
4065 | if (Rm != 0xF) { // Writeback | |
4066 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4067 | return MCDisassembler::Fail; | |
4068 | } | |
4069 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4070 | return MCDisassembler::Fail; | |
4071 | Inst.addOperand(MCOperand::CreateImm(align)); | |
4072 | if (Rm != 0xF) { | |
4073 | if (Rm != 0xD) { | |
4074 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
4075 | return MCDisassembler::Fail; | |
4076 | } else | |
4077 | Inst.addOperand(MCOperand::CreateReg(0)); | |
4078 | } | |
4079 | ||
4080 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
4081 | return MCDisassembler::Fail; | |
4082 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) | |
4083 | return MCDisassembler::Fail; | |
4084 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) | |
4085 | return MCDisassembler::Fail; | |
4086 | Inst.addOperand(MCOperand::CreateImm(index)); | |
4087 | ||
4088 | return S; | |
4089 | } | |
4090 | ||
4091 | ||
4092 | static DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn, | |
4093 | uint64_t Address, const void *Decoder) { | |
4094 | DecodeStatus S = MCDisassembler::Success; | |
4095 | ||
4096 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
4097 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
4098 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
4099 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
4100 | unsigned size = fieldFromInstruction(Insn, 10, 2); | |
4101 | ||
4102 | unsigned align = 0; | |
4103 | unsigned index = 0; | |
4104 | unsigned inc = 1; | |
4105 | switch (size) { | |
4106 | default: | |
4107 | return MCDisassembler::Fail; | |
4108 | case 0: | |
4109 | if (fieldFromInstruction(Insn, 4, 1)) | |
4110 | align = 4; | |
4111 | index = fieldFromInstruction(Insn, 5, 3); | |
4112 | break; | |
4113 | case 1: | |
4114 | if (fieldFromInstruction(Insn, 4, 1)) | |
4115 | align = 8; | |
4116 | index = fieldFromInstruction(Insn, 6, 2); | |
4117 | if (fieldFromInstruction(Insn, 5, 1)) | |
4118 | inc = 2; | |
4119 | break; | |
4120 | case 2: | |
4121 | switch (fieldFromInstruction(Insn, 4, 2)) { | |
4122 | case 0: | |
4123 | align = 0; break; | |
4124 | case 3: | |
4125 | return MCDisassembler::Fail; | |
4126 | default: | |
4127 | align = 4 << fieldFromInstruction(Insn, 4, 2); break; | |
4128 | } | |
4129 | ||
4130 | index = fieldFromInstruction(Insn, 7, 1); | |
4131 | if (fieldFromInstruction(Insn, 6, 1)) | |
4132 | inc = 2; | |
4133 | break; | |
4134 | } | |
4135 | ||
4136 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
4137 | return MCDisassembler::Fail; | |
4138 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) | |
4139 | return MCDisassembler::Fail; | |
4140 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) | |
4141 | return MCDisassembler::Fail; | |
4142 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) | |
4143 | return MCDisassembler::Fail; | |
4144 | ||
4145 | if (Rm != 0xF) { // Writeback | |
4146 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4147 | return MCDisassembler::Fail; | |
4148 | } | |
4149 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4150 | return MCDisassembler::Fail; | |
4151 | Inst.addOperand(MCOperand::CreateImm(align)); | |
4152 | if (Rm != 0xF) { | |
4153 | if (Rm != 0xD) { | |
4154 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
4155 | return MCDisassembler::Fail; | |
4156 | } else | |
4157 | Inst.addOperand(MCOperand::CreateReg(0)); | |
4158 | } | |
4159 | ||
4160 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
4161 | return MCDisassembler::Fail; | |
4162 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) | |
4163 | return MCDisassembler::Fail; | |
4164 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) | |
4165 | return MCDisassembler::Fail; | |
4166 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) | |
4167 | return MCDisassembler::Fail; | |
4168 | Inst.addOperand(MCOperand::CreateImm(index)); | |
4169 | ||
4170 | return S; | |
4171 | } | |
4172 | ||
4173 | static DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn, | |
4174 | uint64_t Address, const void *Decoder) { | |
4175 | DecodeStatus S = MCDisassembler::Success; | |
4176 | ||
4177 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
4178 | unsigned Rm = fieldFromInstruction(Insn, 0, 4); | |
4179 | unsigned Rd = fieldFromInstruction(Insn, 12, 4); | |
4180 | Rd |= fieldFromInstruction(Insn, 22, 1) << 4; | |
4181 | unsigned size = fieldFromInstruction(Insn, 10, 2); | |
4182 | ||
4183 | unsigned align = 0; | |
4184 | unsigned index = 0; | |
4185 | unsigned inc = 1; | |
4186 | switch (size) { | |
4187 | default: | |
4188 | return MCDisassembler::Fail; | |
4189 | case 0: | |
4190 | if (fieldFromInstruction(Insn, 4, 1)) | |
4191 | align = 4; | |
4192 | index = fieldFromInstruction(Insn, 5, 3); | |
4193 | break; | |
4194 | case 1: | |
4195 | if (fieldFromInstruction(Insn, 4, 1)) | |
4196 | align = 8; | |
4197 | index = fieldFromInstruction(Insn, 6, 2); | |
4198 | if (fieldFromInstruction(Insn, 5, 1)) | |
4199 | inc = 2; | |
4200 | break; | |
4201 | case 2: | |
4202 | switch (fieldFromInstruction(Insn, 4, 2)) { | |
4203 | case 0: | |
4204 | align = 0; break; | |
4205 | case 3: | |
4206 | return MCDisassembler::Fail; | |
4207 | default: | |
4208 | align = 4 << fieldFromInstruction(Insn, 4, 2); break; | |
4209 | } | |
4210 | ||
4211 | index = fieldFromInstruction(Insn, 7, 1); | |
4212 | if (fieldFromInstruction(Insn, 6, 1)) | |
4213 | inc = 2; | |
4214 | break; | |
4215 | } | |
4216 | ||
4217 | if (Rm != 0xF) { // Writeback | |
4218 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4219 | return MCDisassembler::Fail; | |
4220 | } | |
4221 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4222 | return MCDisassembler::Fail; | |
4223 | Inst.addOperand(MCOperand::CreateImm(align)); | |
4224 | if (Rm != 0xF) { | |
4225 | if (Rm != 0xD) { | |
4226 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))) | |
4227 | return MCDisassembler::Fail; | |
4228 | } else | |
4229 | Inst.addOperand(MCOperand::CreateReg(0)); | |
4230 | } | |
4231 | ||
4232 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder))) | |
4233 | return MCDisassembler::Fail; | |
4234 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder))) | |
4235 | return MCDisassembler::Fail; | |
4236 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder))) | |
4237 | return MCDisassembler::Fail; | |
4238 | if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder))) | |
4239 | return MCDisassembler::Fail; | |
4240 | Inst.addOperand(MCOperand::CreateImm(index)); | |
4241 | ||
4242 | return S; | |
4243 | } | |
4244 | ||
4245 | static DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn, | |
4246 | uint64_t Address, const void *Decoder) { | |
4247 | DecodeStatus S = MCDisassembler::Success; | |
4248 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
4249 | unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); | |
4250 | unsigned Rm = fieldFromInstruction(Insn, 5, 1); | |
4251 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
4252 | Rm |= fieldFromInstruction(Insn, 0, 4) << 1; | |
4253 | ||
4254 | if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) | |
4255 | S = MCDisassembler::SoftFail; | |
4256 | ||
4257 | if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) | |
4258 | return MCDisassembler::Fail; | |
4259 | if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) | |
4260 | return MCDisassembler::Fail; | |
4261 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) | |
4262 | return MCDisassembler::Fail; | |
4263 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) | |
4264 | return MCDisassembler::Fail; | |
4265 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
4266 | return MCDisassembler::Fail; | |
4267 | ||
4268 | return S; | |
4269 | } | |
4270 | ||
4271 | static DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn, | |
4272 | uint64_t Address, const void *Decoder) { | |
4273 | DecodeStatus S = MCDisassembler::Success; | |
4274 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
4275 | unsigned Rt2 = fieldFromInstruction(Insn, 16, 4); | |
4276 | unsigned Rm = fieldFromInstruction(Insn, 5, 1); | |
4277 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
4278 | Rm |= fieldFromInstruction(Insn, 0, 4) << 1; | |
4279 | ||
4280 | if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) | |
4281 | S = MCDisassembler::SoftFail; | |
4282 | ||
4283 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder))) | |
4284 | return MCDisassembler::Fail; | |
4285 | if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder))) | |
4286 | return MCDisassembler::Fail; | |
4287 | if (!Check(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder))) | |
4288 | return MCDisassembler::Fail; | |
4289 | if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder))) | |
4290 | return MCDisassembler::Fail; | |
4291 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
4292 | return MCDisassembler::Fail; | |
4293 | ||
4294 | return S; | |
4295 | } | |
4296 | ||
4297 | static DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn, | |
4298 | uint64_t Address, const void *Decoder) { | |
4299 | DecodeStatus S = MCDisassembler::Success; | |
4300 | unsigned pred = fieldFromInstruction(Insn, 4, 4); | |
4301 | unsigned mask = fieldFromInstruction(Insn, 0, 4); | |
4302 | ||
4303 | if (pred == 0xF) { | |
4304 | pred = 0xE; | |
4305 | S = MCDisassembler::SoftFail; | |
4306 | } | |
4307 | ||
4308 | if (mask == 0x0) { | |
4309 | mask |= 0x8; | |
4310 | S = MCDisassembler::SoftFail; | |
4311 | } | |
4312 | ||
4313 | Inst.addOperand(MCOperand::CreateImm(pred)); | |
4314 | Inst.addOperand(MCOperand::CreateImm(mask)); | |
4315 | return S; | |
4316 | } | |
4317 | ||
4318 | static DecodeStatus | |
4319 | DecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn, | |
4320 | uint64_t Address, const void *Decoder) { | |
4321 | DecodeStatus S = MCDisassembler::Success; | |
4322 | ||
4323 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
4324 | unsigned Rt2 = fieldFromInstruction(Insn, 8, 4); | |
4325 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
4326 | unsigned addr = fieldFromInstruction(Insn, 0, 8); | |
4327 | unsigned W = fieldFromInstruction(Insn, 21, 1); | |
4328 | unsigned U = fieldFromInstruction(Insn, 23, 1); | |
4329 | unsigned P = fieldFromInstruction(Insn, 24, 1); | |
4330 | bool writeback = (W == 1) | (P == 0); | |
4331 | ||
4332 | addr |= (U << 8) | (Rn << 9); | |
4333 | ||
4334 | if (writeback && (Rn == Rt || Rn == Rt2)) | |
4335 | Check(S, MCDisassembler::SoftFail); | |
4336 | if (Rt == Rt2) | |
4337 | Check(S, MCDisassembler::SoftFail); | |
4338 | ||
4339 | // Rt | |
4340 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
4341 | return MCDisassembler::Fail; | |
4342 | // Rt2 | |
4343 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) | |
4344 | return MCDisassembler::Fail; | |
4345 | // Writeback operand | |
4346 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4347 | return MCDisassembler::Fail; | |
4348 | // addr | |
4349 | if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) | |
4350 | return MCDisassembler::Fail; | |
4351 | ||
4352 | return S; | |
4353 | } | |
4354 | ||
4355 | static DecodeStatus | |
4356 | DecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn, | |
4357 | uint64_t Address, const void *Decoder) { | |
4358 | DecodeStatus S = MCDisassembler::Success; | |
4359 | ||
4360 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
4361 | unsigned Rt2 = fieldFromInstruction(Insn, 8, 4); | |
4362 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
4363 | unsigned addr = fieldFromInstruction(Insn, 0, 8); | |
4364 | unsigned W = fieldFromInstruction(Insn, 21, 1); | |
4365 | unsigned U = fieldFromInstruction(Insn, 23, 1); | |
4366 | unsigned P = fieldFromInstruction(Insn, 24, 1); | |
4367 | bool writeback = (W == 1) | (P == 0); | |
4368 | ||
4369 | addr |= (U << 8) | (Rn << 9); | |
4370 | ||
4371 | if (writeback && (Rn == Rt || Rn == Rt2)) | |
4372 | Check(S, MCDisassembler::SoftFail); | |
4373 | ||
4374 | // Writeback operand | |
4375 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) | |
4376 | return MCDisassembler::Fail; | |
4377 | // Rt | |
4378 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder))) | |
4379 | return MCDisassembler::Fail; | |
4380 | // Rt2 | |
4381 | if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder))) | |
4382 | return MCDisassembler::Fail; | |
4383 | // addr | |
4384 | if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder))) | |
4385 | return MCDisassembler::Fail; | |
4386 | ||
4387 | return S; | |
4388 | } | |
4389 | ||
4390 | static DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn, | |
4391 | uint64_t Address, const void *Decoder) { | |
4392 | unsigned sign1 = fieldFromInstruction(Insn, 21, 1); | |
4393 | unsigned sign2 = fieldFromInstruction(Insn, 23, 1); | |
4394 | if (sign1 != sign2) return MCDisassembler::Fail; | |
4395 | ||
4396 | unsigned Val = fieldFromInstruction(Insn, 0, 8); | |
4397 | Val |= fieldFromInstruction(Insn, 12, 3) << 8; | |
4398 | Val |= fieldFromInstruction(Insn, 26, 1) << 11; | |
4399 | Val |= sign1 << 12; | |
4400 | Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val))); | |
4401 | ||
4402 | return MCDisassembler::Success; | |
4403 | } | |
4404 | ||
4405 | static DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val, | |
4406 | uint64_t Address, | |
4407 | const void *Decoder) { | |
4408 | DecodeStatus S = MCDisassembler::Success; | |
4409 | ||
4410 | // Shift of "asr #32" is not allowed in Thumb2 mode. | |
4411 | if (Val == 0x20) S = MCDisassembler::SoftFail; | |
4412 | Inst.addOperand(MCOperand::CreateImm(Val)); | |
4413 | return S; | |
4414 | } | |
4415 | ||
4416 | static DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn, | |
4417 | uint64_t Address, const void *Decoder) { | |
4418 | unsigned Rt = fieldFromInstruction(Insn, 12, 4); | |
4419 | unsigned Rt2 = fieldFromInstruction(Insn, 0, 4); | |
4420 | unsigned Rn = fieldFromInstruction(Insn, 16, 4); | |
4421 | unsigned pred = fieldFromInstruction(Insn, 28, 4); | |
4422 | ||
4423 | if (pred == 0xF) | |
4424 | return DecodeCPSInstruction(Inst, Insn, Address, Decoder); | |
4425 | ||
4426 | DecodeStatus S = MCDisassembler::Success; | |
4427 | ||
4428 | if (Rt == Rn || Rn == Rt2) | |
4429 | S = MCDisassembler::SoftFail; | |
4430 | ||
4431 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) | |
4432 | return MCDisassembler::Fail; | |
4433 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) | |
4434 | return MCDisassembler::Fail; | |
4435 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) | |
4436 | return MCDisassembler::Fail; | |
4437 | if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder))) | |
4438 | return MCDisassembler::Fail; | |
4439 | ||
4440 | return S; | |
4441 | } | |
4442 | ||
4443 | static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn, | |
4444 | uint64_t Address, const void *Decoder) { | |
4445 | unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0); | |
4446 | Vd |= (fieldFromInstruction(Insn, 22, 1) << 4); | |
4447 | unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0); | |
4448 | Vm |= (fieldFromInstruction(Insn, 5, 1) << 4); | |
4449 | unsigned imm = fieldFromInstruction(Insn, 16, 6); | |
4450 | unsigned cmode = fieldFromInstruction(Insn, 8, 4); | |
4451 | ||
4452 | DecodeStatus S = MCDisassembler::Success; | |
4453 | ||
4454 | // VMOVv2f32 is ambiguous with these decodings. | |
4455 | if (!(imm & 0x38) && cmode == 0xF) { | |
4456 | Inst.setOpcode(ARM::VMOVv2f32); | |
4457 | return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder); | |
4458 | } | |
4459 | ||
4460 | if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail); | |
4461 | ||
4462 | if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder))) | |
4463 | return MCDisassembler::Fail; | |
4464 | if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder))) | |
4465 | return MCDisassembler::Fail; | |
4466 | Inst.addOperand(MCOperand::CreateImm(64 - imm)); | |
4467 | ||
4468 | return S; | |
4469 | } | |
4470 | ||
4471 | static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn, | |
4472 | uint64_t Address, const void *Decoder) { | |
4473 | unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0); | |
4474 | Vd |= (fieldFromInstruction(Insn, 22, 1) << 4); | |
4475 | unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0); | |
4476 | Vm |= (fieldFromInstruction(Insn, 5, 1) << 4); | |
4477 | unsigned imm = fieldFromInstruction(Insn, 16, 6); | |
4478 | unsigned cmode = fieldFromInstruction(Insn, 8, 4); | |
4479 | ||
4480 | DecodeStatus S = MCDisassembler::Success; | |
4481 | ||
4482 | // VMOVv4f32 is ambiguous with these decodings. | |
4483 | if (!(imm & 0x38) && cmode == 0xF) { | |
4484 | Inst.setOpcode(ARM::VMOVv4f32); | |
4485 | return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder); | |
4486 | } | |
4487 | ||
4488 | if (!(imm & 0x20)) Check(S, MCDisassembler::SoftFail); | |
4489 | ||
4490 | if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder))) | |
4491 | return MCDisassembler::Fail; | |
4492 | if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder))) | |
4493 | return MCDisassembler::Fail; | |
4494 | Inst.addOperand(MCOperand::CreateImm(64 - imm)); | |
4495 | ||
4496 | return S; | |
4497 | } | |
4498 | ||
4499 | static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val, | |
4500 | uint64_t Address, const void *Decoder) { | |
4501 | DecodeStatus S = MCDisassembler::Success; | |
4502 | ||
4503 | unsigned Rn = fieldFromInstruction(Val, 16, 4); | |
4504 | unsigned Rt = fieldFromInstruction(Val, 12, 4); | |
4505 | unsigned Rm = fieldFromInstruction(Val, 0, 4); | |
4506 | Rm |= (fieldFromInstruction(Val, 23, 1) << 4); | |
4507 | unsigned Cond = fieldFromInstruction(Val, 28, 4); | |
4508 | ||
4509 | if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt) | |
4510 | S = MCDisassembler::SoftFail; | |
4511 | ||
4512 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) | |
4513 | return MCDisassembler::Fail; | |
4514 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) | |
4515 | return MCDisassembler::Fail; | |
4516 | if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder))) | |
4517 | return MCDisassembler::Fail; | |
4518 | if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder))) | |
4519 | return MCDisassembler::Fail; | |
4520 | if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder))) | |
4521 | return MCDisassembler::Fail; | |
4522 | ||
4523 | return S; | |
4524 | } | |
4525 | ||
4526 | static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val, | |
4527 | uint64_t Address, const void *Decoder) { | |
4528 | ||
4529 | DecodeStatus S = MCDisassembler::Success; | |
4530 | ||
4531 | unsigned CRm = fieldFromInstruction(Val, 0, 4); | |
4532 | unsigned opc1 = fieldFromInstruction(Val, 4, 4); | |
4533 | unsigned cop = fieldFromInstruction(Val, 8, 4); | |
4534 | unsigned Rt = fieldFromInstruction(Val, 12, 4); | |
4535 | unsigned Rt2 = fieldFromInstruction(Val, 16, 4); | |
4536 | ||
4537 | if ((cop & ~0x1) == 0xa) | |
4538 | return MCDisassembler::Fail; | |
4539 | ||
4540 | if (Rt == Rt2) | |
4541 | S = MCDisassembler::SoftFail; | |
4542 | ||
4543 | Inst.addOperand(MCOperand::CreateImm(cop)); | |
4544 | Inst.addOperand(MCOperand::CreateImm(opc1)); | |
4545 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder))) | |
4546 | return MCDisassembler::Fail; | |
4547 | if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder))) | |
4548 | return MCDisassembler::Fail; | |
4549 | Inst.addOperand(MCOperand::CreateImm(CRm)); | |
4550 | ||
4551 | return S; | |
4552 | } | |
4553 |