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 /* Capstone Disassembly Engine */
11 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
12
13 #ifdef CAPSTONE_HAS_ARM
14
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <capstone/platform.h>
19
20 #include "ARMAddressingModes.h"
21 #include "ARMBaseInfo.h"
22 #include "../../MCFixedLenDisassembler.h"
23 #include "../../MCInst.h"
24 #include "../../MCInstrDesc.h"
25 #include "../../MCRegisterInfo.h"
26 #include "../../LEB128.h"
27 #include "../../MCDisassembler.h"
28 #include "../../cs_priv.h"
29 #include "../../utils.h"
30
31 #include "ARMDisassembler.h"
32 #include "ARMMapping.h"
33
34 #define GET_SUBTARGETINFO_ENUM
35 #include "ARMGenSubtargetInfo.inc"
36
37 #define GET_INSTRINFO_MC_DESC
38 #include "ARMGenInstrInfo.inc"
39
40 #define GET_INSTRINFO_ENUM
41 #include "ARMGenInstrInfo.inc"
42
ITStatus_push_back(ARM_ITStatus * it,char v)43 static bool ITStatus_push_back(ARM_ITStatus *it, char v)
44 {
45 if (it->size >= sizeof(it->ITStates)) {
46 // TODO: consider warning user.
47 it->size = 0;
48 }
49 it->ITStates[it->size] = v;
50 it->size++;
51
52 return true;
53 }
54
55 // Returns true if the current instruction is in an IT block
ITStatus_instrInITBlock(ARM_ITStatus * it)56 static bool ITStatus_instrInITBlock(ARM_ITStatus *it)
57 {
58 //return !ITStates.empty();
59 return (it->size > 0);
60 }
61
62 // Returns true if current instruction is the last instruction in an IT block
ITStatus_instrLastInITBlock(ARM_ITStatus * it)63 static bool ITStatus_instrLastInITBlock(ARM_ITStatus *it)
64 {
65 return (it->size == 1);
66 }
67
68 // Handles the condition code status of instructions in IT blocks
69
70 // Returns the condition code for instruction in IT block
ITStatus_getITCC(ARM_ITStatus * it)71 static unsigned ITStatus_getITCC(ARM_ITStatus *it)
72 {
73 unsigned CC = ARMCC_AL;
74
75 if (ITStatus_instrInITBlock(it))
76 //CC = ITStates.back();
77 CC = it->ITStates[it->size-1];
78
79 return CC;
80 }
81
82 // Advances the IT block state to the next T or E
ITStatus_advanceITState(ARM_ITStatus * it)83 static void ITStatus_advanceITState(ARM_ITStatus *it)
84 {
85 //ITStates.pop_back();
86 it->size--;
87 }
88
89 // Called when decoding an IT instruction. Sets the IT state for the following
90 // instructions that for the IT block. Firstcond and Mask correspond to the
91 // fields in the IT instruction encoding.
ITStatus_setITState(ARM_ITStatus * it,char Firstcond,char Mask)92 static void ITStatus_setITState(ARM_ITStatus *it, char Firstcond, char Mask)
93 {
94 // (3 - the number of trailing zeros) is the number of then / else.
95 unsigned CondBit0 = Firstcond & 1;
96 unsigned NumTZ = CountTrailingZeros_32(Mask);
97 unsigned char CCBits = (unsigned char)Firstcond & 0xf;
98 unsigned Pos;
99
100 //assert(NumTZ <= 3 && "Invalid IT mask!");
101 // push condition codes onto the stack the correct order for the pops
102 for (Pos = NumTZ + 1; Pos <= 3; ++Pos) {
103 bool T = ((Mask >> Pos) & 1) == (int)CondBit0;
104
105 if (T)
106 ITStatus_push_back(it, CCBits);
107 else
108 ITStatus_push_back(it, CCBits ^ 1);
109 }
110
111 ITStatus_push_back(it, CCBits);
112 }
113
114 /// ThumbDisassembler - Thumb disassembler for all Thumb platforms.
115
Check(DecodeStatus * Out,DecodeStatus In)116 static bool Check(DecodeStatus *Out, DecodeStatus In)
117 {
118 switch (In) {
119 case MCDisassembler_Success:
120 // Out stays the same.
121 return true;
122 case MCDisassembler_SoftFail:
123 *Out = In;
124 return true;
125 case MCDisassembler_Fail:
126 *Out = In;
127 return false;
128 default: // never reached
129 return false;
130 }
131 }
132
133 // Forward declare these because the autogenerated code will reference them.
134 // Definitions are further down.
135 static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, unsigned RegNo,
136 uint64_t Address, const void *Decoder);
137 static DecodeStatus DecodeGPRnopcRegisterClass(MCInst *Inst,
138 unsigned RegNo, uint64_t Address, const void *Decoder);
139 static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst *Inst,
140 unsigned RegNo, uint64_t Address, const void *Decoder);
141 static DecodeStatus DecodetGPRRegisterClass(MCInst *Inst, unsigned RegNo,
142 uint64_t Address, const void *Decoder);
143 static DecodeStatus DecodetcGPRRegisterClass(MCInst *Inst, unsigned RegNo,
144 uint64_t Address, const void *Decoder);
145 static DecodeStatus DecoderGPRRegisterClass(MCInst *Inst, unsigned RegNo,
146 uint64_t Address, const void *Decoder);
147 static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, unsigned RegNo,
148 uint64_t Address, const void *Decoder);
149 static DecodeStatus DecodeSPRRegisterClass(MCInst *Inst, unsigned RegNo,
150 uint64_t Address, const void *Decoder);
151 static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,
152 uint64_t Address, const void *Decoder);
153 static DecodeStatus DecodeDPR_8RegisterClass(MCInst *Inst, unsigned RegNo,
154 uint64_t Address, const void *Decoder);
155 static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst *Inst,
156 unsigned RegNo, uint64_t Address, const void *Decoder);
157 static DecodeStatus DecodeQPRRegisterClass(MCInst *Inst, unsigned RegNo,
158 uint64_t Address, const void *Decoder);
159 static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,
160 uint64_t Address, const void *Decoder);
161 static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst *Inst,
162 unsigned RegNo, uint64_t Address, const void *Decoder);
163 static DecodeStatus DecodePredicateOperand(MCInst *Inst, unsigned Val,
164 uint64_t Address, const void *Decoder);
165 static DecodeStatus DecodeCCOutOperand(MCInst *Inst, unsigned Val,
166 uint64_t Address, const void *Decoder);
167 static DecodeStatus DecodeRegListOperand(MCInst *Inst, unsigned Val,
168 uint64_t Address, const void *Decoder);
169 static DecodeStatus DecodeSPRRegListOperand(MCInst *Inst, unsigned Val,
170 uint64_t Address, const void *Decoder);
171 static DecodeStatus DecodeDPRRegListOperand(MCInst *Inst, unsigned Val,
172 uint64_t Address, const void *Decoder);
173 static DecodeStatus DecodeBitfieldMaskOperand(MCInst *Inst, unsigned Insn,
174 uint64_t Address, const void *Decoder);
175 static DecodeStatus DecodeCopMemInstruction(MCInst *Inst, unsigned Insn,
176 uint64_t Address, const void *Decoder);
177 static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst *Inst,
178 unsigned Insn, uint64_t Address, const void *Decoder);
179 static DecodeStatus DecodeSORegMemOperand(MCInst *Inst, unsigned Insn,
180 uint64_t Address, const void *Decoder);
181 static DecodeStatus DecodeAddrMode3Instruction(MCInst *Inst,unsigned Insn,
182 uint64_t Address, const void *Decoder);
183 static DecodeStatus DecodeSORegImmOperand(MCInst *Inst, unsigned Insn,
184 uint64_t Address, const void *Decoder);
185 static DecodeStatus DecodeSORegRegOperand(MCInst *Inst, unsigned Insn,
186 uint64_t Address, const void *Decoder);
187 static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst * Inst,
188 unsigned Insn, uint64_t Adddress, const void *Decoder);
189 static DecodeStatus DecodeT2MOVTWInstruction(MCInst *Inst, unsigned Insn,
190 uint64_t Address, const void *Decoder);
191 static DecodeStatus DecodeArmMOVTWInstruction(MCInst *Inst, unsigned Insn,
192 uint64_t Address, const void *Decoder);
193 static DecodeStatus DecodeSMLAInstruction(MCInst *Inst, unsigned Insn,
194 uint64_t Address, const void *Decoder);
195 static DecodeStatus DecodeCPSInstruction(MCInst *Inst, unsigned Insn,
196 uint64_t Address, const void *Decoder);
197 static DecodeStatus DecodeT2CPSInstruction(MCInst *Inst, unsigned Insn,
198 uint64_t Address, const void *Decoder);
199 static DecodeStatus DecodeAddrModeImm12Operand(MCInst *Inst, unsigned Val,
200 uint64_t Address, const void *Decoder);
201 static DecodeStatus DecodeAddrMode5Operand(MCInst *Inst, unsigned Val,
202 uint64_t Address, const void *Decoder);
203 static DecodeStatus DecodeAddrMode7Operand(MCInst *Inst, unsigned Val,
204 uint64_t Address, const void *Decoder);
205 static DecodeStatus DecodeT2BInstruction(MCInst *Inst, unsigned Insn,
206 uint64_t Address, const void *Decoder);
207 static DecodeStatus DecodeBranchImmInstruction(MCInst *Inst,unsigned Insn,
208 uint64_t Address, const void *Decoder);
209 static DecodeStatus DecodeAddrMode6Operand(MCInst *Inst, unsigned Val,
210 uint64_t Address, const void *Decoder);
211 static DecodeStatus DecodeVLDST1Instruction(MCInst *Inst, unsigned Val,
212 uint64_t Address, const void *Decoder);
213 static DecodeStatus DecodeVLDST2Instruction(MCInst *Inst, unsigned Val,
214 uint64_t Address, const void *Decoder);
215 static DecodeStatus DecodeVLDST3Instruction(MCInst *Inst, unsigned Val,
216 uint64_t Address, const void *Decoder);
217 static DecodeStatus DecodeVLDST4Instruction(MCInst *Inst, unsigned Val,
218 uint64_t Address, const void *Decoder);
219 static DecodeStatus DecodeVLDInstruction(MCInst *Inst, unsigned Val,
220 uint64_t Address, const void *Decoder);
221 static DecodeStatus DecodeVSTInstruction(MCInst *Inst, unsigned Val,
222 uint64_t Address, const void *Decoder);
223 static DecodeStatus DecodeVLD1DupInstruction(MCInst *Inst, unsigned Val,
224 uint64_t Address, const void *Decoder);
225 static DecodeStatus DecodeVLD2DupInstruction(MCInst *Inst, unsigned Val,
226 uint64_t Address, const void *Decoder);
227 static DecodeStatus DecodeVLD3DupInstruction(MCInst *Inst, unsigned Val,
228 uint64_t Address, const void *Decoder);
229 static DecodeStatus DecodeVLD4DupInstruction(MCInst *Inst, unsigned Val,
230 uint64_t Address, const void *Decoder);
231 static DecodeStatus DecodeNEONModImmInstruction(MCInst *Inst,unsigned Val,
232 uint64_t Address, const void *Decoder);
233 static DecodeStatus DecodeVSHLMaxInstruction(MCInst *Inst, unsigned Val,
234 uint64_t Address, const void *Decoder);
235 static DecodeStatus DecodeShiftRight8Imm(MCInst *Inst, unsigned Val,
236 uint64_t Address, const void *Decoder);
237 static DecodeStatus DecodeShiftRight16Imm(MCInst *Inst, unsigned Val,
238 uint64_t Address, const void *Decoder);
239 static DecodeStatus DecodeShiftRight32Imm(MCInst *Inst, unsigned Val,
240 uint64_t Address, const void *Decoder);
241 static DecodeStatus DecodeShiftRight64Imm(MCInst *Inst, unsigned Val,
242 uint64_t Address, const void *Decoder);
243 static DecodeStatus DecodeTBLInstruction(MCInst *Inst, unsigned Insn,
244 uint64_t Address, const void *Decoder);
245 static DecodeStatus DecodePostIdxReg(MCInst *Inst, unsigned Insn,
246 uint64_t Address, const void *Decoder);
247 static DecodeStatus DecodeCoprocessor(MCInst *Inst, unsigned Insn,
248 uint64_t Address, const void *Decoder);
249 static DecodeStatus DecodeMemBarrierOption(MCInst *Inst, unsigned Insn,
250 uint64_t Address, const void *Decoder);
251 static DecodeStatus DecodeInstSyncBarrierOption(MCInst *Inst, unsigned Insn,
252 uint64_t Address, const void *Decoder);
253 static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Insn,
254 uint64_t Address, const void *Decoder);
255 static DecodeStatus DecodeBankedReg(MCInst *Inst, unsigned Insn,
256 uint64_t Address, const void *Decoder);
257 static DecodeStatus DecodeDoubleRegLoad(MCInst *Inst, unsigned Insn,
258 uint64_t Address, const void *Decoder);
259 static DecodeStatus DecodeDoubleRegStore(MCInst *Inst, unsigned Insn,
260 uint64_t Address, const void *Decoder);
261 static DecodeStatus DecodeLDRPreImm(MCInst *Inst, unsigned Insn,
262 uint64_t Address, const void *Decoder);
263 static DecodeStatus DecodeLDRPreReg(MCInst *Inst, unsigned Insn,
264 uint64_t Address, const void *Decoder);
265 static DecodeStatus DecodeSTRPreImm(MCInst *Inst, unsigned Insn,
266 uint64_t Address, const void *Decoder);
267 static DecodeStatus DecodeSTRPreReg(MCInst *Inst, unsigned Insn,
268 uint64_t Address, const void *Decoder);
269 static DecodeStatus DecodeVLD1LN(MCInst *Inst, unsigned Insn,
270 uint64_t Address, const void *Decoder);
271 static DecodeStatus DecodeVLD2LN(MCInst *Inst, unsigned Insn,
272 uint64_t Address, const void *Decoder);
273 static DecodeStatus DecodeVLD3LN(MCInst *Inst, unsigned Insn,
274 uint64_t Address, const void *Decoder);
275 static DecodeStatus DecodeVLD4LN(MCInst *Inst, unsigned Insn,
276 uint64_t Address, const void *Decoder);
277 static DecodeStatus DecodeVST1LN(MCInst *Inst, unsigned Insn,
278 uint64_t Address, const void *Decoder);
279 static DecodeStatus DecodeVST2LN(MCInst *Inst, unsigned Insn,
280 uint64_t Address, const void *Decoder);
281 static DecodeStatus DecodeVST3LN(MCInst *Inst, unsigned Insn,
282 uint64_t Address, const void *Decoder);
283 static DecodeStatus DecodeVST4LN(MCInst *Inst, unsigned Insn,
284 uint64_t Address, const void *Decoder);
285 static DecodeStatus DecodeVMOVSRR(MCInst *Inst, unsigned Insn,
286 uint64_t Address, const void *Decoder);
287 static DecodeStatus DecodeVMOVRRS(MCInst *Inst, unsigned Insn,
288 uint64_t Address, const void *Decoder);
289 static DecodeStatus DecodeSwap(MCInst *Inst, unsigned Insn,
290 uint64_t Address, const void *Decoder);
291 static DecodeStatus DecodeVCVTD(MCInst *Inst, unsigned Insn,
292 uint64_t Address, const void *Decoder);
293 static DecodeStatus DecodeVCVTQ(MCInst *Inst, unsigned Insn,
294 uint64_t Address, const void *Decoder);
295 static DecodeStatus DecodeThumbAddSpecialReg(MCInst *Inst, uint16_t Insn,
296 uint64_t Address, const void *Decoder);
297 static DecodeStatus DecodeThumbBROperand(MCInst *Inst, unsigned Val,
298 uint64_t Address, const void *Decoder);
299 static DecodeStatus DecodeT2BROperand(MCInst *Inst, unsigned Val,
300 uint64_t Address, const void *Decoder);
301 static DecodeStatus DecodeThumbCmpBROperand(MCInst *Inst, unsigned Val,
302 uint64_t Address, const void *Decoder);
303 static DecodeStatus DecodeThumbAddrModeRR(MCInst *Inst, unsigned Val,
304 uint64_t Address, const void *Decoder);
305 static DecodeStatus DecodeThumbAddrModeIS(MCInst *Inst, unsigned Val,
306 uint64_t Address, const void *Decoder);
307 static DecodeStatus DecodeThumbAddrModePC(MCInst *Inst, unsigned Val,
308 uint64_t Address, const void *Decoder);
309 static DecodeStatus DecodeThumbAddrModeSP(MCInst *Inst, unsigned Val,
310 uint64_t Address, const void *Decoder);
311 static DecodeStatus DecodeT2AddrModeSOReg(MCInst *Inst, unsigned Val,
312 uint64_t Address, const void *Decoder);
313 static DecodeStatus DecodeT2LoadShift(MCInst *Inst, unsigned Val,
314 uint64_t Address, const void *Decoder);
315 static DecodeStatus DecodeT2LoadImm8(MCInst *Inst, unsigned Insn,
316 uint64_t Address, const void* Decoder);
317 static DecodeStatus DecodeT2LoadImm12(MCInst *Inst, unsigned Insn,
318 uint64_t Address, const void* Decoder);
319 static DecodeStatus DecodeT2LoadT(MCInst *Inst, unsigned Insn,
320 uint64_t Address, const void* Decoder);
321 static DecodeStatus DecodeT2LoadLabel(MCInst *Inst, unsigned Insn,
322 uint64_t Address, const void* Decoder);
323 static DecodeStatus DecodeT2Imm8S4(MCInst *Inst, unsigned Val,
324 uint64_t Address, const void *Decoder);
325 static DecodeStatus DecodeT2AddrModeImm8s4(MCInst *Inst, unsigned Val,
326 uint64_t Address, const void *Decoder);
327 static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst *Inst,unsigned Val,
328 uint64_t Address, const void *Decoder);
329 static DecodeStatus DecodeT2Imm8(MCInst *Inst, unsigned Val,
330 uint64_t Address, const void *Decoder);
331 static DecodeStatus DecodeT2AddrModeImm8(MCInst *Inst, unsigned Val,
332 uint64_t Address, const void *Decoder);
333 static DecodeStatus DecodeThumbAddSPImm(MCInst *Inst, uint16_t Val,
334 uint64_t Address, const void *Decoder);
335 static DecodeStatus DecodeThumbAddSPReg(MCInst *Inst, uint16_t Insn,
336 uint64_t Address, const void *Decoder);
337 static DecodeStatus DecodeThumbCPS(MCInst *Inst, uint16_t Insn,
338 uint64_t Address, const void *Decoder);
339 static DecodeStatus DecodeQADDInstruction(MCInst *Inst, unsigned Insn,
340 uint64_t Address, const void *Decoder);
341 static DecodeStatus DecodeThumbBLXOffset(MCInst *Inst, unsigned Insn,
342 uint64_t Address, const void *Decoder);
343 static DecodeStatus DecodeT2AddrModeImm12(MCInst *Inst, unsigned Val,
344 uint64_t Address, const void *Decoder);
345 static DecodeStatus DecodeThumbTableBranch(MCInst *Inst, unsigned Val,
346 uint64_t Address, const void *Decoder);
347 static DecodeStatus DecodeThumb2BCCInstruction(MCInst *Inst, unsigned Val,
348 uint64_t Address, const void *Decoder);
349 static DecodeStatus DecodeT2SOImm(MCInst *Inst, unsigned Val,
350 uint64_t Address, const void *Decoder);
351 static DecodeStatus DecodeThumbBCCTargetOperand(MCInst *Inst,unsigned Val,
352 uint64_t Address, const void *Decoder);
353 static DecodeStatus DecodeThumbBLTargetOperand(MCInst *Inst, unsigned Val,
354 uint64_t Address, const void *Decoder);
355 static DecodeStatus DecodeIT(MCInst *Inst, unsigned Val,
356 uint64_t Address, const void *Decoder);
357 static DecodeStatus DecodeT2LDRDPreInstruction(MCInst *Inst,unsigned Insn,
358 uint64_t Address, const void *Decoder);
359 static DecodeStatus DecodeT2STRDPreInstruction(MCInst *Inst,unsigned Insn,
360 uint64_t Address, const void *Decoder);
361 static DecodeStatus DecodeT2Adr(MCInst *Inst, uint32_t Val,
362 uint64_t Address, const void *Decoder);
363 static DecodeStatus DecodeT2LdStPre(MCInst *Inst, unsigned Val,
364 uint64_t Address, const void *Decoder);
365 static DecodeStatus DecodeT2ShifterImmOperand(MCInst *Inst, uint32_t Val,
366 uint64_t Address, const void *Decoder);
367 static DecodeStatus DecodeLDR(MCInst *Inst, unsigned Val,
368 uint64_t Address, const void *Decoder);
369 static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst *Inst, unsigned Val,
370 uint64_t Address, const void *Decoder);
371 static DecodeStatus DecodeHINTInstruction(MCInst *Inst, unsigned Insn,
372 uint64_t Address, const void *Decoder);
373 static DecodeStatus DecodeTSTInstruction(MCInst *Inst, unsigned Insn,
374 uint64_t Address, const void *Decoder);
375 static DecodeStatus DecodeSETPANInstruction(MCInst *Inst, unsigned Insn,
376 uint64_t Address, const void *Decoder);
377 static DecodeStatus DecodeAddrMode5FP16Operand(MCInst *Inst, unsigned Val,
378 uint64_t Address, const void *Decoder);
379 static DecodeStatus DecodeForVMRSandVMSR(MCInst *Inst, unsigned Val,
380 uint64_t Address, const void *Decoder);
381 static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst *Inst, unsigned Insn,
382 uint64_t Address, const void *Decoder);
383 static DecodeStatus DecodeHPRRegisterClass(MCInst *Inst, unsigned RegNo,
384 uint64_t Address, const void *Decoder);
385
386 // Hacky: enable all features for disassembler
ARM_getFeatureBits(unsigned int mode,unsigned int feature)387 bool ARM_getFeatureBits(unsigned int mode, unsigned int feature)
388 {
389 if ((mode & CS_MODE_V8) == 0) {
390 // not V8 mode
391 if (feature == ARM_HasV8Ops || feature == ARM_HasV8_1aOps ||
392 feature == ARM_HasV8_4aOps || feature == ARM_HasV8_3aOps)
393 // HasV8MBaselineOps
394 return false;
395 } else {
396 if (feature == ARM_FeatureVFPOnlySP)
397 return false;
398 }
399
400 if ((mode & CS_MODE_MCLASS) == 0) {
401 if (feature == ARM_FeatureMClass)
402 return false;
403 }
404
405 if ((mode & CS_MODE_THUMB) == 0) {
406 // not Thumb
407 if (feature == ARM_FeatureThumb2 || feature == ARM_ModeThumb)
408 return false;
409 // FIXME: what mode enables D16?
410 if (feature == ARM_FeatureD16)
411 return false;
412 } else {
413 // Thumb
414 if (feature == ARM_FeatureD16)
415 return false;
416 }
417
418 if (feature == ARM_FeatureMClass && (mode & CS_MODE_MCLASS) == 0)
419 return false;
420
421 // we support everything
422 return true;
423 }
424
425 #include "ARMGenDisassemblerTables.inc"
426
DecodePredicateOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)427 static DecodeStatus DecodePredicateOperand(MCInst *Inst, unsigned Val,
428 uint64_t Address, const void *Decoder)
429 {
430 if (Val == 0xF) return MCDisassembler_Fail;
431
432 // AL predicate is not allowed on Thumb1 branches.
433 if (MCInst_getOpcode(Inst) == ARM_tBcc && Val == 0xE)
434 return MCDisassembler_Fail;
435
436 MCOperand_CreateImm0(Inst, Val);
437
438 if (Val == ARMCC_AL) {
439 MCOperand_CreateReg0(Inst, 0);
440 } else
441 MCOperand_CreateReg0(Inst, ARM_CPSR);
442
443 return MCDisassembler_Success;
444 }
445
446 #define GET_REGINFO_MC_DESC
447 #include "ARMGenRegisterInfo.inc"
ARM_init(MCRegisterInfo * MRI)448 void ARM_init(MCRegisterInfo *MRI)
449 {
450 /*
451 InitMCRegisterInfo(ARMRegDesc, 289,
452 RA, PC,
453 ARMMCRegisterClasses, 103,
454 ARMRegUnitRoots, 77, ARMRegDiffLists, ARMRegStrings,
455 ARMSubRegIdxLists, 57,
456 ARMSubRegIdxRanges, ARMRegEncodingTable);
457 */
458
459 MCRegisterInfo_InitMCRegisterInfo(MRI, ARMRegDesc, 289,
460 0, 0,
461 ARMMCRegisterClasses, 103,
462 0, 0, ARMRegDiffLists, 0,
463 ARMSubRegIdxLists, 57,
464 0);
465 }
466
467 // Post-decoding checks
checkDecodedInstruction(MCInst * MI,uint32_t Insn,DecodeStatus Result)468 static DecodeStatus checkDecodedInstruction(MCInst *MI,
469 uint32_t Insn,
470 DecodeStatus Result)
471 {
472 switch (MCInst_getOpcode(MI)) {
473 case ARM_HVC: {
474 // HVC is undefined if condition = 0xf otherwise upredictable
475 // if condition != 0xe
476 uint32_t Cond = (Insn >> 28) & 0xF;
477
478 if (Cond == 0xF)
479 return MCDisassembler_Fail;
480
481 if (Cond != 0xE)
482 return MCDisassembler_SoftFail;
483
484 return Result;
485 }
486 default:
487 return Result;
488 }
489 }
490
_ARM_getInstruction(cs_struct * ud,MCInst * MI,const uint8_t * code,size_t code_len,uint16_t * Size,uint64_t Address)491 static DecodeStatus _ARM_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t *code, size_t code_len,
492 uint16_t *Size, uint64_t Address)
493 {
494 uint32_t insn;
495 DecodeStatus result;
496
497 *Size = 0;
498
499 if (code_len < 4)
500 // not enough data
501 return MCDisassembler_Fail;
502
503 if (MI->flat_insn->detail) {
504 unsigned int i;
505
506 memset(MI->flat_insn->detail, 0, offsetof(cs_detail, arm) + sizeof(cs_arm));
507
508 for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
509 MI->flat_insn->detail->arm.operands[i].vector_index = -1;
510 MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
511 }
512 }
513
514 if (MODE_IS_BIG_ENDIAN(ud->mode))
515 insn = (code[3] << 0) | (code[2] << 8) |
516 (code[1] << 16) | ((uint32_t) code[0] << 24);
517 else
518 insn = ((uint32_t) code[3] << 24) | (code[2] << 16) |
519 (code[1] << 8) | (code[0] << 0);
520
521 // Calling the auto-generated decoder function.
522 result = decodeInstruction_4(DecoderTableARM32, MI, insn, Address);
523 if (result != MCDisassembler_Fail) {
524 result = checkDecodedInstruction(MI, insn, result);
525 if (result != MCDisassembler_Fail)
526 *Size = 4;
527
528 return result;
529 }
530
531 // VFP and NEON instructions, similarly, are shared between ARM
532 // and Thumb modes.
533 MCInst_clear(MI);
534 result = decodeInstruction_4(DecoderTableVFP32, MI, insn, Address);
535 if (result != MCDisassembler_Fail) {
536 *Size = 4;
537 return result;
538 }
539
540 MCInst_clear(MI);
541 result = decodeInstruction_4(DecoderTableVFPV832, MI, insn, Address);
542 if (result != MCDisassembler_Fail) {
543 *Size = 4;
544 return result;
545 }
546
547 MCInst_clear(MI);
548 result = decodeInstruction_4(DecoderTableNEONData32, MI, insn, Address);
549 if (result != MCDisassembler_Fail) {
550 *Size = 4;
551 // Add a fake predicate operand, because we share these instruction
552 // definitions with Thumb2 where these instructions are predicable.
553 if (!DecodePredicateOperand(MI, 0xE, Address, NULL))
554 return MCDisassembler_Fail;
555 return result;
556 }
557
558 MCInst_clear(MI);
559 result = decodeInstruction_4(DecoderTableNEONLoadStore32, MI, insn, Address);
560 if (result != MCDisassembler_Fail) {
561 *Size = 4;
562 // Add a fake predicate operand, because we share these instruction
563 // definitions with Thumb2 where these instructions are predicable.
564 if (!DecodePredicateOperand(MI, 0xE, Address, NULL))
565 return MCDisassembler_Fail;
566 return result;
567 }
568
569 MCInst_clear(MI);
570 result = decodeInstruction_4(DecoderTableNEONDup32, MI, insn, Address);
571 if (result != MCDisassembler_Fail) {
572 *Size = 4;
573 // Add a fake predicate operand, because we share these instruction
574 // definitions with Thumb2 where these instructions are predicable.
575 if (!DecodePredicateOperand(MI, 0xE, Address, NULL))
576 return MCDisassembler_Fail;
577 return result;
578 }
579
580 MCInst_clear(MI);
581 result = decodeInstruction_4(DecoderTablev8NEON32, MI, insn, Address);
582 if (result != MCDisassembler_Fail) {
583 *Size = 4;
584 return result;
585 }
586
587 MCInst_clear(MI);
588 result = decodeInstruction_4(DecoderTablev8Crypto32, MI, insn, Address);
589 if (result != MCDisassembler_Fail) {
590 *Size = 4;
591 return result;
592 }
593
594 result = decodeInstruction_4(DecoderTableCoProc32, MI, insn, Address);
595 if (result != MCDisassembler_Fail) {
596 result = checkDecodedInstruction(MI, insn, result);
597 if (result != MCDisassembler_Fail)
598 *Size = 4;
599
600 return result;
601 }
602
603 MCInst_clear(MI);
604 *Size = 0;
605 return MCDisassembler_Fail;
606 }
607
608 // Thumb1 instructions don't have explicit S bits. Rather, they
609 // implicitly set CPSR. Since it's not represented in the encoding, the
610 // auto-generated decoder won't inject the CPSR operand. We need to fix
611 // that as a post-pass.
AddThumb1SBit(MCInst * MI,bool InITBlock)612 static void AddThumb1SBit(MCInst *MI, bool InITBlock)
613 {
614 const MCOperandInfo *OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
615 unsigned short NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
616 unsigned i;
617
618 for (i = 0; i < NumOps; ++i) {
619 if (i == MCInst_getNumOperands(MI)) break;
620
621 if (MCOperandInfo_isOptionalDef(&OpInfo[i]) && OpInfo[i].RegClass == ARM_CCRRegClassID) {
622 if (i > 0 && MCOperandInfo_isPredicate(&OpInfo[i - 1])) continue;
623 MCInst_insert0(MI, i, MCOperand_CreateReg1(MI, InITBlock ? 0 : ARM_CPSR));
624 return;
625 }
626 }
627
628 //MI.insert(I, MCOperand_CreateReg0(Inst, InITBlock ? 0 : ARM_CPSR));
629 MCInst_insert0(MI, i, MCOperand_CreateReg1(MI, InITBlock ? 0 : ARM_CPSR));
630 }
631
632 // Most Thumb instructions don't have explicit predicates in the
633 // encoding, but rather get their predicates from IT context. We need
634 // to fix up the predicate operands using this context information as a
635 // post-pass.
AddThumbPredicate(cs_struct * ud,MCInst * MI)636 static DecodeStatus AddThumbPredicate(cs_struct *ud, MCInst *MI)
637 {
638 DecodeStatus S = MCDisassembler_Success;
639 const MCOperandInfo *OpInfo;
640 unsigned short NumOps;
641 unsigned int i;
642 unsigned CC;
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 (MCInst_getOpcode(MI)) {
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 (ITStatus_instrInITBlock(&(ud->ITBlock)))
660 S = MCDisassembler_SoftFail;
661 else
662 return MCDisassembler_Success;
663 break;
664
665 case ARM_t2HINT:
666 if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 0x10)
667 S = MCDisassembler_SoftFail;
668 break;
669
670 case ARM_tB:
671 case ARM_t2B:
672 case ARM_t2TBB:
673 case ARM_t2TBH:
674 // Some instructions (mostly unconditional branches) can
675 // only appears at the end of, or outside of, an IT.
676 // if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
677 if (ITStatus_instrInITBlock(&(ud->ITBlock)) && !ITStatus_instrLastInITBlock(&(ud->ITBlock)))
678 S = MCDisassembler_SoftFail;
679 break;
680 default:
681 break;
682 }
683
684 // If we're in an IT block, base the predicate on that. Otherwise,
685 // assume a predicate of AL.
686 CC = ITStatus_getITCC(&(ud->ITBlock));
687 if (CC == 0xF)
688 CC = ARMCC_AL;
689
690 if (ITStatus_instrInITBlock(&(ud->ITBlock)))
691 ITStatus_advanceITState(&(ud->ITBlock));
692
693 OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
694 NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
695
696 for (i = 0; i < NumOps; ++i) {
697 if (i == MCInst_getNumOperands(MI)) break;
698
699 if (MCOperandInfo_isPredicate(&OpInfo[i])) {
700 MCInst_insert0(MI, i, MCOperand_CreateImm1(MI, CC));
701
702 if (CC == ARMCC_AL)
703 MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, 0));
704 else
705 MCInst_insert0(MI, i+1, MCOperand_CreateReg1(MI, ARM_CPSR));
706
707 return S;
708 }
709 }
710
711 MCInst_insert0(MI, i, MCOperand_CreateImm1(MI, CC));
712
713 if (CC == ARMCC_AL)
714 MCInst_insert0(MI, i + 1, MCOperand_CreateReg1(MI, 0));
715 else
716 MCInst_insert0(MI, i + 1, MCOperand_CreateReg1(MI, ARM_CPSR));
717
718 return S;
719 }
720
721 // Thumb VFP instructions are a special case. Because we share their
722 // encodings between ARM and Thumb modes, and they are predicable in ARM
723 // mode, the auto-generated decoder will give them an (incorrect)
724 // predicate operand. We need to rewrite these operands based on the IT
725 // context as a post-pass.
UpdateThumbVFPPredicate(cs_struct * ud,MCInst * MI)726 static void UpdateThumbVFPPredicate(cs_struct *ud, MCInst *MI)
727 {
728 unsigned CC;
729 unsigned short NumOps;
730 const MCOperandInfo *OpInfo;
731 unsigned i;
732
733 CC = ITStatus_getITCC(&(ud->ITBlock));
734 if (ITStatus_instrInITBlock(&(ud->ITBlock)))
735 ITStatus_advanceITState(&(ud->ITBlock));
736
737 OpInfo = ARMInsts[MCInst_getOpcode(MI)].OpInfo;
738 NumOps = ARMInsts[MCInst_getOpcode(MI)].NumOperands;
739
740 for (i = 0; i < NumOps; ++i) {
741 if (MCOperandInfo_isPredicate(&OpInfo[i])) {
742 MCOperand_setImm(MCInst_getOperand(MI, i), CC);
743
744 if (CC == ARMCC_AL)
745 MCOperand_setReg(MCInst_getOperand(MI, i + 1), 0);
746 else
747 MCOperand_setReg(MCInst_getOperand(MI, i + 1), ARM_CPSR);
748
749 return;
750 }
751 }
752 }
753
_Thumb_getInstruction(cs_struct * ud,MCInst * MI,const uint8_t * code,size_t code_len,uint16_t * Size,uint64_t Address)754 static DecodeStatus _Thumb_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t *code, size_t code_len,
755 uint16_t *Size, uint64_t Address)
756 {
757 uint16_t insn16;
758 DecodeStatus result;
759 bool InITBlock;
760 unsigned Firstcond, Mask;
761 uint32_t NEONLdStInsn, insn32, NEONDataInsn, NEONCryptoInsn, NEONv8Insn;
762 size_t i;
763
764 // We want to read exactly 2 bytes of data.
765 if (code_len < 2)
766 // not enough data
767 return MCDisassembler_Fail;
768
769 if (MI->flat_insn->detail) {
770 memset(MI->flat_insn->detail, 0, offsetof(cs_detail, arm)+sizeof(cs_arm));
771 for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
772 MI->flat_insn->detail->arm.operands[i].vector_index = -1;
773 MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
774 }
775 }
776
777 if (MODE_IS_BIG_ENDIAN(ud->mode))
778 insn16 = (code[0] << 8) | code[1];
779 else
780 insn16 = (code[1] << 8) | code[0];
781
782 result = decodeInstruction_2(DecoderTableThumb16, MI, insn16, Address);
783 if (result != MCDisassembler_Fail) {
784 *Size = 2;
785 Check(&result, AddThumbPredicate(ud, MI));
786 return result;
787 }
788
789 MCInst_clear(MI);
790 result = decodeInstruction_2(DecoderTableThumbSBit16, MI, insn16, Address);
791 if (result) {
792 *Size = 2;
793 InITBlock = ITStatus_instrInITBlock(&(ud->ITBlock));
794 Check(&result, AddThumbPredicate(ud, MI));
795 AddThumb1SBit(MI, InITBlock);
796 return result;
797 }
798
799 MCInst_clear(MI);
800 result = decodeInstruction_2(DecoderTableThumb216, MI, insn16, Address);
801 if (result != MCDisassembler_Fail) {
802 *Size = 2;
803
804 // Nested IT blocks are UNPREDICTABLE. Must be checked before we add
805 // the Thumb predicate.
806 if (MCInst_getOpcode(MI) == ARM_t2IT && ITStatus_instrInITBlock(&(ud->ITBlock)))
807 return MCDisassembler_SoftFail;
808
809 Check(&result, AddThumbPredicate(ud, MI));
810
811 // If we find an IT instruction, we need to parse its condition
812 // code and mask operands so that we can apply them correctly
813 // to the subsequent instructions.
814 if (MCInst_getOpcode(MI) == ARM_t2IT) {
815 Firstcond = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, 0));
816 Mask = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, 1));
817 ITStatus_setITState(&(ud->ITBlock), (char)Firstcond, (char)Mask);
818
819 // An IT instruction that would give a 'NV' predicate is unpredictable.
820 // if (Firstcond == ARMCC_AL && !isPowerOf2_32(Mask))
821 // CS << "unpredictable IT predicate sequence";
822 }
823
824 return result;
825 }
826
827 // We want to read exactly 4 bytes of data.
828 if (code_len < 4)
829 // not enough data
830 return MCDisassembler_Fail;
831
832 if (MODE_IS_BIG_ENDIAN(ud->mode))
833 insn32 = (code[3] << 0) | (code[2] << 8) |
834 (code[1] << 16) | ((uint32_t) code[0] << 24);
835 else
836 insn32 = (code[3] << 8) | (code[2] << 0) |
837 ((uint32_t) code[1] << 24) | (code[0] << 16);
838
839 MCInst_clear(MI);
840 result = decodeInstruction_4(DecoderTableThumb32, MI, insn32, Address);
841 if (result != MCDisassembler_Fail) {
842 *Size = 4;
843 InITBlock = ITStatus_instrInITBlock(&(ud->ITBlock));
844 Check(&result, AddThumbPredicate(ud, MI));
845 AddThumb1SBit(MI, InITBlock);
846
847 return result;
848 }
849
850 MCInst_clear(MI);
851 result = decodeInstruction_4(DecoderTableThumb232, MI, insn32, Address);
852 if (result != MCDisassembler_Fail) {
853 *Size = 4;
854 Check(&result, AddThumbPredicate(ud, MI));
855 return result;
856 }
857
858 if (fieldFromInstruction_4(insn32, 28, 4) == 0xE) {
859 MCInst_clear(MI);
860 result = decodeInstruction_4(DecoderTableVFP32, MI, insn32, Address);
861 if (result != MCDisassembler_Fail) {
862 *Size = 4;
863 UpdateThumbVFPPredicate(ud, MI);
864 return result;
865 }
866 }
867
868 MCInst_clear(MI);
869 result = decodeInstruction_4(DecoderTableVFPV832, MI, insn32, Address);
870 if (result != MCDisassembler_Fail) {
871 *Size = 4;
872 return result;
873 }
874
875 if (fieldFromInstruction_4(insn32, 28, 4) == 0xE) {
876 MCInst_clear(MI);
877 result = decodeInstruction_4(DecoderTableNEONDup32, MI, insn32, Address);
878 if (result != MCDisassembler_Fail) {
879 *Size = 4;
880 Check(&result, AddThumbPredicate(ud, MI));
881 return result;
882 }
883 }
884
885 if (fieldFromInstruction_4(insn32, 24, 8) == 0xF9) {
886 MCInst_clear(MI);
887 NEONLdStInsn = insn32;
888 NEONLdStInsn &= 0xF0FFFFFF;
889 NEONLdStInsn |= 0x04000000;
890 result = decodeInstruction_4(DecoderTableNEONLoadStore32, MI, NEONLdStInsn, Address);
891 if (result != MCDisassembler_Fail) {
892 *Size = 4;
893 Check(&result, AddThumbPredicate(ud, MI));
894 return result;
895 }
896 }
897
898 if (fieldFromInstruction_4(insn32, 24, 4) == 0xF) {
899 MCInst_clear(MI);
900 NEONDataInsn = insn32;
901 NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
902 NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
903 NEONDataInsn |= 0x12000000; // Set bits 28 and 25
904 result = decodeInstruction_4(DecoderTableNEONData32, MI, NEONDataInsn, Address);
905 if (result != MCDisassembler_Fail) {
906 *Size = 4;
907 Check(&result, AddThumbPredicate(ud, MI));
908 return result;
909 }
910 }
911
912 MCInst_clear(MI);
913 NEONCryptoInsn = insn32;
914 NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
915 NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
916 NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
917 result = decodeInstruction_4(DecoderTablev8Crypto32, MI, NEONCryptoInsn, Address);
918 if (result != MCDisassembler_Fail) {
919 *Size = 4;
920 return result;
921 }
922
923 MCInst_clear(MI);
924 NEONv8Insn = insn32;
925 NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
926 result = decodeInstruction_4(DecoderTablev8NEON32, MI, NEONv8Insn, Address);
927 if (result != MCDisassembler_Fail) {
928 *Size = 4;
929 return result;
930 }
931
932 MCInst_clear(MI);
933 result = decodeInstruction_4(DecoderTableThumb2CoProc32, MI, insn32, Address);
934 if (result != MCDisassembler_Fail) {
935 *Size = 4;
936 Check(&result, AddThumbPredicate(ud, MI));
937 return result;
938 }
939
940 MCInst_clear(MI);
941 *Size = 0;
942
943 return MCDisassembler_Fail;
944 }
945
Thumb_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * instr,uint16_t * size,uint64_t address,void * info)946 bool Thumb_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,
947 uint16_t *size, uint64_t address, void *info)
948 {
949 DecodeStatus status = _Thumb_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);
950
951 // TODO: fix table gen to eliminate these special cases
952 if (instr->Opcode == ARM_t__brkdiv0)
953 return false;
954
955 //return status == MCDisassembler_Success;
956 return status != MCDisassembler_Fail;
957 }
958
ARM_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * instr,uint16_t * size,uint64_t address,void * info)959 bool ARM_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *instr,
960 uint16_t *size, uint64_t address, void *info)
961 {
962 DecodeStatus status = _ARM_getInstruction((cs_struct *)ud, instr, code, code_len, size, address);
963
964 //return status == MCDisassembler_Success;
965 return status != MCDisassembler_Fail;
966 }
967
968 static const uint16_t GPRDecoderTable[] = {
969 ARM_R0, ARM_R1, ARM_R2, ARM_R3,
970 ARM_R4, ARM_R5, ARM_R6, ARM_R7,
971 ARM_R8, ARM_R9, ARM_R10, ARM_R11,
972 ARM_R12, ARM_SP, ARM_LR, ARM_PC
973 };
974
DecodeGPRRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)975 static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, unsigned RegNo,
976 uint64_t Address, const void *Decoder)
977 {
978 unsigned Register;
979
980 if (RegNo > 15)
981 return MCDisassembler_Fail;
982
983 Register = GPRDecoderTable[RegNo];
984 MCOperand_CreateReg0(Inst, Register);
985
986 return MCDisassembler_Success;
987 }
988
DecodeGPRnopcRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)989 static DecodeStatus DecodeGPRnopcRegisterClass(MCInst *Inst, unsigned RegNo,
990 uint64_t Address, const void *Decoder)
991 {
992 DecodeStatus S = MCDisassembler_Success;
993
994 if (RegNo == 15)
995 S = MCDisassembler_SoftFail;
996
997 Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
998
999 return S;
1000 }
1001
DecodeGPRwithAPSRRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1002 static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst *Inst, unsigned RegNo,
1003 uint64_t Address, const void *Decoder)
1004 {
1005 DecodeStatus S = MCDisassembler_Success;
1006
1007 if (RegNo == 15) {
1008 MCOperand_CreateReg0(Inst, ARM_APSR_NZCV);
1009
1010 return MCDisassembler_Success;
1011 }
1012
1013 Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1014 return S;
1015 }
1016
DecodetGPRRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1017 static DecodeStatus DecodetGPRRegisterClass(MCInst *Inst, unsigned RegNo,
1018 uint64_t Address, const void *Decoder)
1019 {
1020 if (RegNo > 7)
1021 return MCDisassembler_Fail;
1022
1023 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
1024 }
1025
1026 static const uint16_t GPRPairDecoderTable[] = {
1027 ARM_R0_R1, ARM_R2_R3, ARM_R4_R5, ARM_R6_R7,
1028 ARM_R8_R9, ARM_R10_R11, ARM_R12_SP
1029 };
1030
DecodeGPRPairRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1031 static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, unsigned RegNo,
1032 uint64_t Address, const void *Decoder)
1033 {
1034 unsigned RegisterPair;
1035 DecodeStatus S = MCDisassembler_Success;
1036
1037 if (RegNo > 13)
1038 return MCDisassembler_Fail;
1039
1040 if ((RegNo & 1) || RegNo == 0xe)
1041 S = MCDisassembler_SoftFail;
1042
1043 RegisterPair = GPRPairDecoderTable[RegNo / 2];
1044 MCOperand_CreateReg0(Inst, RegisterPair);
1045
1046 return S;
1047 }
1048
DecodetcGPRRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1049 static DecodeStatus DecodetcGPRRegisterClass(MCInst *Inst, unsigned RegNo,
1050 uint64_t Address, const void *Decoder)
1051 {
1052 unsigned Register = 0;
1053
1054 switch (RegNo) {
1055 case 0:
1056 Register = ARM_R0;
1057 break;
1058 case 1:
1059 Register = ARM_R1;
1060 break;
1061 case 2:
1062 Register = ARM_R2;
1063 break;
1064 case 3:
1065 Register = ARM_R3;
1066 break;
1067 case 9:
1068 Register = ARM_R9;
1069 break;
1070 case 12:
1071 Register = ARM_R12;
1072 break;
1073 default:
1074 return MCDisassembler_Fail;
1075 }
1076
1077 MCOperand_CreateReg0(Inst, Register);
1078
1079 return MCDisassembler_Success;
1080 }
1081
DecoderGPRRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1082 static DecodeStatus DecoderGPRRegisterClass(MCInst *Inst, unsigned RegNo,
1083 uint64_t Address, const void *Decoder)
1084 {
1085 DecodeStatus S = MCDisassembler_Success;
1086
1087 if ((RegNo == 13 && !ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops)) || RegNo == 15)
1088 S = MCDisassembler_SoftFail;
1089
1090 Check(&S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
1091
1092 return S;
1093 }
1094
1095 static const uint16_t SPRDecoderTable[] = {
1096 ARM_S0, ARM_S1, ARM_S2, ARM_S3,
1097 ARM_S4, ARM_S5, ARM_S6, ARM_S7,
1098 ARM_S8, ARM_S9, ARM_S10, ARM_S11,
1099 ARM_S12, ARM_S13, ARM_S14, ARM_S15,
1100 ARM_S16, ARM_S17, ARM_S18, ARM_S19,
1101 ARM_S20, ARM_S21, ARM_S22, ARM_S23,
1102 ARM_S24, ARM_S25, ARM_S26, ARM_S27,
1103 ARM_S28, ARM_S29, ARM_S30, ARM_S31
1104 };
1105
DecodeSPRRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1106 static DecodeStatus DecodeSPRRegisterClass(MCInst *Inst, unsigned RegNo,
1107 uint64_t Address, const void *Decoder)
1108 {
1109 unsigned Register;
1110
1111 if (RegNo > 31)
1112 return MCDisassembler_Fail;
1113
1114 Register = SPRDecoderTable[RegNo];
1115 MCOperand_CreateReg0(Inst, Register);
1116
1117 return MCDisassembler_Success;
1118 }
1119
DecodeHPRRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1120 static DecodeStatus DecodeHPRRegisterClass(MCInst *Inst, unsigned RegNo,
1121 uint64_t Address, const void *Decoder)
1122 {
1123 return DecodeSPRRegisterClass(Inst, RegNo, Address, Decoder);
1124 }
1125
1126 static const uint16_t DPRDecoderTable[] = {
1127 ARM_D0, ARM_D1, ARM_D2, ARM_D3,
1128 ARM_D4, ARM_D5, ARM_D6, ARM_D7,
1129 ARM_D8, ARM_D9, ARM_D10, ARM_D11,
1130 ARM_D12, ARM_D13, ARM_D14, ARM_D15,
1131 ARM_D16, ARM_D17, ARM_D18, ARM_D19,
1132 ARM_D20, ARM_D21, ARM_D22, ARM_D23,
1133 ARM_D24, ARM_D25, ARM_D26, ARM_D27,
1134 ARM_D28, ARM_D29, ARM_D30, ARM_D31
1135 };
1136
DecodeDPRRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1137 static DecodeStatus DecodeDPRRegisterClass(MCInst *Inst, unsigned RegNo,
1138 uint64_t Address, const void *Decoder)
1139 {
1140 unsigned Register;
1141
1142 if (RegNo > 31 || (ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureD16) && RegNo > 15))
1143 return MCDisassembler_Fail;
1144
1145 Register = DPRDecoderTable[RegNo];
1146 MCOperand_CreateReg0(Inst, Register);
1147
1148 return MCDisassembler_Success;
1149 }
1150
DecodeDPR_8RegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1151 static DecodeStatus DecodeDPR_8RegisterClass(MCInst *Inst, unsigned RegNo,
1152 uint64_t Address, const void *Decoder)
1153 {
1154 if (RegNo > 7)
1155 return MCDisassembler_Fail;
1156
1157 return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
1158 }
1159
DecodeDPR_VFP2RegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1160 static DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst *Inst, unsigned RegNo,
1161 uint64_t Address, const void *Decoder)
1162 {
1163 if (RegNo > 15)
1164 return MCDisassembler_Fail;
1165
1166 return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
1167 }
1168
1169 static const uint16_t QPRDecoderTable[] = {
1170 ARM_Q0, ARM_Q1, ARM_Q2, ARM_Q3,
1171 ARM_Q4, ARM_Q5, ARM_Q6, ARM_Q7,
1172 ARM_Q8, ARM_Q9, ARM_Q10, ARM_Q11,
1173 ARM_Q12, ARM_Q13, ARM_Q14, ARM_Q15
1174 };
1175
DecodeQPRRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1176 static DecodeStatus DecodeQPRRegisterClass(MCInst *Inst, unsigned RegNo,
1177 uint64_t Address, const void *Decoder)
1178 {
1179 unsigned Register;
1180
1181 if (RegNo > 31 || (RegNo & 1) != 0)
1182 return MCDisassembler_Fail;
1183
1184 RegNo >>= 1;
1185
1186 Register = QPRDecoderTable[RegNo];
1187 MCOperand_CreateReg0(Inst, Register);
1188
1189 return MCDisassembler_Success;
1190 }
1191
1192 static const uint16_t DPairDecoderTable[] = {
1193 ARM_Q0, ARM_D1_D2, ARM_Q1, ARM_D3_D4, ARM_Q2, ARM_D5_D6,
1194 ARM_Q3, ARM_D7_D8, ARM_Q4, ARM_D9_D10, ARM_Q5, ARM_D11_D12,
1195 ARM_Q6, ARM_D13_D14, ARM_Q7, ARM_D15_D16, ARM_Q8, ARM_D17_D18,
1196 ARM_Q9, ARM_D19_D20, ARM_Q10, ARM_D21_D22, ARM_Q11, ARM_D23_D24,
1197 ARM_Q12, ARM_D25_D26, ARM_Q13, ARM_D27_D28, ARM_Q14, ARM_D29_D30,
1198 ARM_Q15
1199 };
1200
DecodeDPairRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1201 static DecodeStatus DecodeDPairRegisterClass(MCInst *Inst, unsigned RegNo,
1202 uint64_t Address, const void *Decoder)
1203 {
1204 unsigned Register;
1205
1206 if (RegNo > 30)
1207 return MCDisassembler_Fail;
1208
1209 Register = DPairDecoderTable[RegNo];
1210 MCOperand_CreateReg0(Inst, Register);
1211
1212 return MCDisassembler_Success;
1213 }
1214
1215 static const uint16_t DPairSpacedDecoderTable[] = {
1216 ARM_D0_D2, ARM_D1_D3, ARM_D2_D4, ARM_D3_D5,
1217 ARM_D4_D6, ARM_D5_D7, ARM_D6_D8, ARM_D7_D9,
1218 ARM_D8_D10, ARM_D9_D11, ARM_D10_D12, ARM_D11_D13,
1219 ARM_D12_D14, ARM_D13_D15, ARM_D14_D16, ARM_D15_D17,
1220 ARM_D16_D18, ARM_D17_D19, ARM_D18_D20, ARM_D19_D21,
1221 ARM_D20_D22, ARM_D21_D23, ARM_D22_D24, ARM_D23_D25,
1222 ARM_D24_D26, ARM_D25_D27, ARM_D26_D28, ARM_D27_D29,
1223 ARM_D28_D30, ARM_D29_D31
1224 };
1225
DecodeDPairSpacedRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)1226 static DecodeStatus DecodeDPairSpacedRegisterClass(MCInst *Inst,
1227 unsigned RegNo, uint64_t Address, const void *Decoder)
1228 {
1229 unsigned Register;
1230
1231 if (RegNo > 29)
1232 return MCDisassembler_Fail;
1233
1234 Register = DPairSpacedDecoderTable[RegNo];
1235 MCOperand_CreateReg0(Inst, Register);
1236
1237 return MCDisassembler_Success;
1238 }
1239
DecodeCCOutOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)1240 static DecodeStatus DecodeCCOutOperand(MCInst *Inst, unsigned Val,
1241 uint64_t Address, const void *Decoder)
1242 {
1243 if (Val)
1244 MCOperand_CreateReg0(Inst, ARM_CPSR);
1245 else
1246 MCOperand_CreateReg0(Inst, 0);
1247
1248 return MCDisassembler_Success;
1249 }
1250
DecodeSORegImmOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)1251 static DecodeStatus DecodeSORegImmOperand(MCInst *Inst, unsigned Val,
1252 uint64_t Address, const void *Decoder)
1253 {
1254 DecodeStatus S = MCDisassembler_Success;
1255 ARM_AM_ShiftOpc Shift;
1256 unsigned Op;
1257 unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
1258 unsigned type = fieldFromInstruction_4(Val, 5, 2);
1259 unsigned imm = fieldFromInstruction_4(Val, 7, 5);
1260
1261 // Register-immediate
1262 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
1263 return MCDisassembler_Fail;
1264
1265 Shift = ARM_AM_lsl;
1266 switch (type) {
1267 case 0:
1268 Shift = ARM_AM_lsl;
1269 break;
1270 case 1:
1271 Shift = ARM_AM_lsr;
1272 break;
1273 case 2:
1274 Shift = ARM_AM_asr;
1275 break;
1276 case 3:
1277 Shift = ARM_AM_ror;
1278 break;
1279 }
1280
1281 if (Shift == ARM_AM_ror && imm == 0)
1282 Shift = ARM_AM_rrx;
1283
1284 Op = Shift | (imm << 3);
1285 MCOperand_CreateImm0(Inst, Op);
1286
1287 return S;
1288 }
1289
DecodeSORegRegOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)1290 static DecodeStatus DecodeSORegRegOperand(MCInst *Inst, unsigned Val,
1291 uint64_t Address, const void *Decoder)
1292 {
1293 DecodeStatus S = MCDisassembler_Success;
1294 ARM_AM_ShiftOpc Shift;
1295
1296 unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
1297 unsigned type = fieldFromInstruction_4(Val, 5, 2);
1298 unsigned Rs = fieldFromInstruction_4(Val, 8, 4);
1299
1300 // Register-register
1301 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1302 return MCDisassembler_Fail;
1303 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
1304 return MCDisassembler_Fail;
1305
1306 Shift = ARM_AM_lsl;
1307 switch (type) {
1308 case 0:
1309 Shift = ARM_AM_lsl;
1310 break;
1311 case 1:
1312 Shift = ARM_AM_lsr;
1313 break;
1314 case 2:
1315 Shift = ARM_AM_asr;
1316 break;
1317 case 3:
1318 Shift = ARM_AM_ror;
1319 break;
1320 }
1321
1322 MCOperand_CreateImm0(Inst, Shift);
1323
1324 return S;
1325 }
1326
DecodeRegListOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)1327 static DecodeStatus DecodeRegListOperand(MCInst *Inst, unsigned Val,
1328 uint64_t Address, const void *Decoder)
1329 {
1330 unsigned i;
1331 DecodeStatus S = MCDisassembler_Success;
1332 unsigned opcode;
1333 bool NeedDisjointWriteback = false;
1334 unsigned WritebackReg = 0;
1335
1336 opcode = MCInst_getOpcode(Inst);
1337 switch (opcode) {
1338 default:
1339 break;
1340
1341 case ARM_LDMIA_UPD:
1342 case ARM_LDMDB_UPD:
1343 case ARM_LDMIB_UPD:
1344 case ARM_LDMDA_UPD:
1345 case ARM_t2LDMIA_UPD:
1346 case ARM_t2LDMDB_UPD:
1347 case ARM_t2STMIA_UPD:
1348 case ARM_t2STMDB_UPD:
1349 NeedDisjointWriteback = true;
1350 WritebackReg = MCOperand_getReg(MCInst_getOperand(Inst, 0));
1351 break;
1352 }
1353
1354 // Empty register lists are not allowed.
1355 if (Val == 0) return MCDisassembler_Fail;
1356
1357 for (i = 0; i < 16; ++i) {
1358 if (Val & (1 << i)) {
1359 if (!Check(&S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
1360 return MCDisassembler_Fail;
1361
1362 // Writeback not allowed if Rn is in the target list.
1363 if (NeedDisjointWriteback && WritebackReg == MCOperand_getReg(&(Inst->Operands[Inst->size - 1])))
1364 Check(&S, MCDisassembler_SoftFail);
1365 }
1366 }
1367
1368 return S;
1369 }
1370
DecodeSPRRegListOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)1371 static DecodeStatus DecodeSPRRegListOperand(MCInst *Inst, unsigned Val,
1372 uint64_t Address, const void *Decoder)
1373 {
1374 DecodeStatus S = MCDisassembler_Success;
1375 unsigned i;
1376 unsigned Vd = fieldFromInstruction_4(Val, 8, 5);
1377 unsigned regs = fieldFromInstruction_4(Val, 0, 8);
1378
1379 // In case of unpredictable encoding, tweak the operands.
1380 if (regs == 0 || (Vd + regs) > 32) {
1381 regs = Vd + regs > 32 ? 32 - Vd : regs;
1382 regs = (1u > regs? 1u : regs);
1383 S = MCDisassembler_SoftFail;
1384 }
1385
1386 if (!Check(&S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
1387 return MCDisassembler_Fail;
1388
1389 for (i = 0; i < (regs - 1); ++i) {
1390 if (!Check(&S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1391 return MCDisassembler_Fail;
1392 }
1393
1394 return S;
1395 }
1396
DecodeDPRRegListOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)1397 static DecodeStatus DecodeDPRRegListOperand(MCInst *Inst, unsigned Val,
1398 uint64_t Address, const void *Decoder)
1399 {
1400 DecodeStatus S = MCDisassembler_Success;
1401 unsigned i;
1402 unsigned Vd = fieldFromInstruction_4(Val, 8, 5);
1403 unsigned regs = fieldFromInstruction_4(Val, 1, 7);
1404
1405 // In case of unpredictable encoding, tweak the operands.
1406 if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
1407 regs = Vd + regs > 32 ? 32 - Vd : regs;
1408 regs = (1u > regs? 1u : regs);
1409 regs = (16u > regs? regs : 16u);
1410 S = MCDisassembler_SoftFail;
1411 }
1412
1413 if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
1414 return MCDisassembler_Fail;
1415
1416 for (i = 0; i < (regs - 1); ++i) {
1417 if (!Check(&S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1418 return MCDisassembler_Fail;
1419 }
1420
1421 return S;
1422 }
1423
DecodeBitfieldMaskOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)1424 static DecodeStatus DecodeBitfieldMaskOperand(MCInst *Inst, unsigned Val,
1425 uint64_t Address, const void *Decoder)
1426 {
1427 // This operand encodes a mask of contiguous zeros between a specified MSB
1428 // and LSB. To decode it, we create the mask of all bits MSB-and-lower,
1429 // the mask of all bits LSB-and-lower, and then xor them to create
1430 // the mask of that's all ones on [msb, lsb]. Finally we not it to
1431 // create the final mask.
1432 unsigned msb = fieldFromInstruction_4(Val, 5, 5);
1433 unsigned lsb = fieldFromInstruction_4(Val, 0, 5);
1434 uint32_t lsb_mask, msb_mask;
1435
1436 DecodeStatus S = MCDisassembler_Success;
1437 if (lsb > msb) {
1438 Check(&S, MCDisassembler_SoftFail);
1439 // The check above will cause the warning for the "potentially undefined
1440 // instruction encoding" but we can't build a bad MCOperand value here
1441 // with a lsb > msb or else printing the MCInst will cause a crash.
1442 lsb = msb;
1443 }
1444
1445 msb_mask = 0xFFFFFFFF;
1446 if (msb != 31) msb_mask = (1U << (msb + 1)) - 1;
1447 lsb_mask = (1U << lsb) - 1;
1448
1449 MCOperand_CreateImm0(Inst, ~(msb_mask ^ lsb_mask));
1450 return S;
1451 }
1452
DecodeCopMemInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)1453 static DecodeStatus DecodeCopMemInstruction(MCInst *Inst, unsigned Insn,
1454 uint64_t Address, const void *Decoder)
1455 {
1456 DecodeStatus S = MCDisassembler_Success;
1457
1458 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
1459 unsigned CRd = fieldFromInstruction_4(Insn, 12, 4);
1460 unsigned coproc = fieldFromInstruction_4(Insn, 8, 4);
1461 unsigned imm = fieldFromInstruction_4(Insn, 0, 8);
1462 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
1463 unsigned U = fieldFromInstruction_4(Insn, 23, 1);
1464
1465 switch (MCInst_getOpcode(Inst)) {
1466 case ARM_LDC_OFFSET:
1467 case ARM_LDC_PRE:
1468 case ARM_LDC_POST:
1469 case ARM_LDC_OPTION:
1470 case ARM_LDCL_OFFSET:
1471 case ARM_LDCL_PRE:
1472 case ARM_LDCL_POST:
1473 case ARM_LDCL_OPTION:
1474 case ARM_STC_OFFSET:
1475 case ARM_STC_PRE:
1476 case ARM_STC_POST:
1477 case ARM_STC_OPTION:
1478 case ARM_STCL_OFFSET:
1479 case ARM_STCL_PRE:
1480 case ARM_STCL_POST:
1481 case ARM_STCL_OPTION:
1482 case ARM_t2LDC_OFFSET:
1483 case ARM_t2LDC_PRE:
1484 case ARM_t2LDC_POST:
1485 case ARM_t2LDC_OPTION:
1486 case ARM_t2LDCL_OFFSET:
1487 case ARM_t2LDCL_PRE:
1488 case ARM_t2LDCL_POST:
1489 case ARM_t2LDCL_OPTION:
1490 case ARM_t2STC_OFFSET:
1491 case ARM_t2STC_PRE:
1492 case ARM_t2STC_POST:
1493 case ARM_t2STC_OPTION:
1494 case ARM_t2STCL_OFFSET:
1495 case ARM_t2STCL_PRE:
1496 case ARM_t2STCL_POST:
1497 case ARM_t2STCL_OPTION:
1498 if (coproc == 0xA || coproc == 0xB)
1499 return MCDisassembler_Fail;
1500 break;
1501 default:
1502 break;
1503 }
1504
1505 if (ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops) && (coproc != 14))
1506 return MCDisassembler_Fail;
1507
1508 MCOperand_CreateImm0(Inst, coproc);
1509 MCOperand_CreateImm0(Inst, CRd);
1510 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1511 return MCDisassembler_Fail;
1512
1513 switch (MCInst_getOpcode(Inst)) {
1514 case ARM_t2LDC2_OFFSET:
1515 case ARM_t2LDC2L_OFFSET:
1516 case ARM_t2LDC2_PRE:
1517 case ARM_t2LDC2L_PRE:
1518 case ARM_t2STC2_OFFSET:
1519 case ARM_t2STC2L_OFFSET:
1520 case ARM_t2STC2_PRE:
1521 case ARM_t2STC2L_PRE:
1522 case ARM_LDC2_OFFSET:
1523 case ARM_LDC2L_OFFSET:
1524 case ARM_LDC2_PRE:
1525 case ARM_LDC2L_PRE:
1526 case ARM_STC2_OFFSET:
1527 case ARM_STC2L_OFFSET:
1528 case ARM_STC2_PRE:
1529 case ARM_STC2L_PRE:
1530 case ARM_t2LDC_OFFSET:
1531 case ARM_t2LDCL_OFFSET:
1532 case ARM_t2LDC_PRE:
1533 case ARM_t2LDCL_PRE:
1534 case ARM_t2STC_OFFSET:
1535 case ARM_t2STCL_OFFSET:
1536 case ARM_t2STC_PRE:
1537 case ARM_t2STCL_PRE:
1538 case ARM_LDC_OFFSET:
1539 case ARM_LDCL_OFFSET:
1540 case ARM_LDC_PRE:
1541 case ARM_LDCL_PRE:
1542 case ARM_STC_OFFSET:
1543 case ARM_STCL_OFFSET:
1544 case ARM_STC_PRE:
1545 case ARM_STCL_PRE:
1546 imm = ARM_AM_getAM5Opc(U ? ARM_AM_add : ARM_AM_sub, (unsigned char)imm);
1547 MCOperand_CreateImm0(Inst, imm);
1548 break;
1549 case ARM_t2LDC2_POST:
1550 case ARM_t2LDC2L_POST:
1551 case ARM_t2STC2_POST:
1552 case ARM_t2STC2L_POST:
1553 case ARM_LDC2_POST:
1554 case ARM_LDC2L_POST:
1555 case ARM_STC2_POST:
1556 case ARM_STC2L_POST:
1557 case ARM_t2LDC_POST:
1558 case ARM_t2LDCL_POST:
1559 case ARM_t2STC_POST:
1560 case ARM_t2STCL_POST:
1561 case ARM_LDC_POST:
1562 case ARM_LDCL_POST:
1563 case ARM_STC_POST:
1564 case ARM_STCL_POST:
1565 imm |= U << 8;
1566 // fall through.
1567 default:
1568 // The 'option' variant doesn't encode 'U' in the immediate since
1569 // the immediate is unsigned [0,255].
1570 MCOperand_CreateImm0(Inst, imm);
1571 break;
1572 }
1573
1574 switch (MCInst_getOpcode(Inst)) {
1575 case ARM_LDC_OFFSET:
1576 case ARM_LDC_PRE:
1577 case ARM_LDC_POST:
1578 case ARM_LDC_OPTION:
1579 case ARM_LDCL_OFFSET:
1580 case ARM_LDCL_PRE:
1581 case ARM_LDCL_POST:
1582 case ARM_LDCL_OPTION:
1583 case ARM_STC_OFFSET:
1584 case ARM_STC_PRE:
1585 case ARM_STC_POST:
1586 case ARM_STC_OPTION:
1587 case ARM_STCL_OFFSET:
1588 case ARM_STCL_PRE:
1589 case ARM_STCL_POST:
1590 case ARM_STCL_OPTION:
1591 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1592 return MCDisassembler_Fail;
1593 break;
1594 default:
1595 break;
1596 }
1597
1598 return S;
1599 }
1600
DecodeAddrMode2IdxInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)1601 static DecodeStatus DecodeAddrMode2IdxInstruction(MCInst *Inst, unsigned Insn,
1602 uint64_t Address, const void *Decoder)
1603 {
1604 DecodeStatus S = MCDisassembler_Success;
1605 ARM_AM_AddrOpc Op;
1606 ARM_AM_ShiftOpc Opc;
1607 bool writeback;
1608 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
1609 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
1610 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
1611 unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
1612 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
1613 unsigned reg = fieldFromInstruction_4(Insn, 25, 1);
1614 unsigned P = fieldFromInstruction_4(Insn, 24, 1);
1615 unsigned W = fieldFromInstruction_4(Insn, 21, 1);
1616 unsigned idx_mode = 0, amt, tmp;
1617
1618 // On stores, the writeback operand precedes Rt.
1619 switch (MCInst_getOpcode(Inst)) {
1620 case ARM_STR_POST_IMM:
1621 case ARM_STR_POST_REG:
1622 case ARM_STRB_POST_IMM:
1623 case ARM_STRB_POST_REG:
1624 case ARM_STRT_POST_REG:
1625 case ARM_STRT_POST_IMM:
1626 case ARM_STRBT_POST_REG:
1627 case ARM_STRBT_POST_IMM:
1628 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1629 return MCDisassembler_Fail;
1630 break;
1631 default:
1632 break;
1633 }
1634
1635 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1636 return MCDisassembler_Fail;
1637
1638 // On loads, the writeback operand comes after Rt.
1639 switch (MCInst_getOpcode(Inst)) {
1640 case ARM_LDR_POST_IMM:
1641 case ARM_LDR_POST_REG:
1642 case ARM_LDRB_POST_IMM:
1643 case ARM_LDRB_POST_REG:
1644 case ARM_LDRBT_POST_REG:
1645 case ARM_LDRBT_POST_IMM:
1646 case ARM_LDRT_POST_REG:
1647 case ARM_LDRT_POST_IMM:
1648 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1649 return MCDisassembler_Fail;
1650 break;
1651 default:
1652 break;
1653 }
1654
1655 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1656 return MCDisassembler_Fail;
1657
1658 Op = ARM_AM_add;
1659 if (!fieldFromInstruction_4(Insn, 23, 1))
1660 Op = ARM_AM_sub;
1661
1662 writeback = (P == 0) || (W == 1);
1663 if (P && writeback)
1664 idx_mode = ARMII_IndexModePre;
1665 else if (!P && writeback)
1666 idx_mode = ARMII_IndexModePost;
1667
1668 if (writeback && (Rn == 15 || Rn == Rt))
1669 S = MCDisassembler_SoftFail; // UNPREDICTABLE
1670
1671 if (reg) {
1672 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1673 return MCDisassembler_Fail;
1674
1675 Opc = ARM_AM_lsl;
1676 switch(fieldFromInstruction_4(Insn, 5, 2)) {
1677 case 0:
1678 Opc = ARM_AM_lsl;
1679 break;
1680 case 1:
1681 Opc = ARM_AM_lsr;
1682 break;
1683 case 2:
1684 Opc = ARM_AM_asr;
1685 break;
1686 case 3:
1687 Opc = ARM_AM_ror;
1688 break;
1689 default:
1690 return MCDisassembler_Fail;
1691 }
1692
1693 amt = fieldFromInstruction_4(Insn, 7, 5);
1694 if (Opc == ARM_AM_ror && amt == 0)
1695 Opc = ARM_AM_rrx;
1696
1697 imm = ARM_AM_getAM2Opc(Op, amt, Opc, idx_mode);
1698
1699 MCOperand_CreateImm0(Inst, imm);
1700 } else {
1701 MCOperand_CreateReg0(Inst, 0);
1702 tmp = ARM_AM_getAM2Opc(Op, imm, ARM_AM_lsl, idx_mode);
1703 MCOperand_CreateImm0(Inst, tmp);
1704 }
1705
1706 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1707 return MCDisassembler_Fail;
1708
1709 return S;
1710 }
1711
DecodeSORegMemOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)1712 static DecodeStatus DecodeSORegMemOperand(MCInst *Inst, unsigned Val,
1713 uint64_t Address, const void *Decoder)
1714 {
1715 DecodeStatus S = MCDisassembler_Success;
1716 ARM_AM_ShiftOpc ShOp;
1717 unsigned shift;
1718 unsigned Rn = fieldFromInstruction_4(Val, 13, 4);
1719 unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
1720 unsigned type = fieldFromInstruction_4(Val, 5, 2);
1721 unsigned imm = fieldFromInstruction_4(Val, 7, 5);
1722 unsigned U = fieldFromInstruction_4(Val, 12, 1);
1723
1724 ShOp = ARM_AM_lsl;
1725 switch (type) {
1726 case 0:
1727 ShOp = ARM_AM_lsl;
1728 break;
1729 case 1:
1730 ShOp = ARM_AM_lsr;
1731 break;
1732 case 2:
1733 ShOp = ARM_AM_asr;
1734 break;
1735 case 3:
1736 ShOp = ARM_AM_ror;
1737 break;
1738 }
1739
1740 if (ShOp == ARM_AM_ror && imm == 0)
1741 ShOp = ARM_AM_rrx;
1742
1743 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1744 return MCDisassembler_Fail;
1745
1746 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1747 return MCDisassembler_Fail;
1748
1749 if (U)
1750 shift = ARM_AM_getAM2Opc(ARM_AM_add, imm, ShOp, 0);
1751 else
1752 shift = ARM_AM_getAM2Opc(ARM_AM_sub, imm, ShOp, 0);
1753
1754 MCOperand_CreateImm0(Inst, shift);
1755
1756 return S;
1757 }
1758
DecodeAddrMode3Instruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)1759 static DecodeStatus DecodeAddrMode3Instruction(MCInst *Inst, unsigned Insn,
1760 uint64_t Address, const void *Decoder)
1761 {
1762 DecodeStatus S = MCDisassembler_Success;
1763
1764 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
1765 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
1766 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
1767 unsigned type = fieldFromInstruction_4(Insn, 22, 1);
1768 unsigned imm = fieldFromInstruction_4(Insn, 8, 4);
1769 unsigned U = ((~fieldFromInstruction_4(Insn, 23, 1)) & 1) << 8;
1770 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
1771 unsigned W = fieldFromInstruction_4(Insn, 21, 1);
1772 unsigned P = fieldFromInstruction_4(Insn, 24, 1);
1773 unsigned Rt2 = Rt + 1;
1774
1775 bool writeback = (W == 1) | (P == 0);
1776
1777 // For {LD,ST}RD, Rt must be even, else undefined.
1778 switch (MCInst_getOpcode(Inst)) {
1779 case ARM_STRD:
1780 case ARM_STRD_PRE:
1781 case ARM_STRD_POST:
1782 case ARM_LDRD:
1783 case ARM_LDRD_PRE:
1784 case ARM_LDRD_POST:
1785 if (Rt & 0x1)
1786 S = MCDisassembler_SoftFail;
1787 break;
1788 default:
1789 break;
1790 }
1791
1792 switch (MCInst_getOpcode(Inst)) {
1793 case ARM_STRD:
1794 case ARM_STRD_PRE:
1795 case ARM_STRD_POST:
1796 if (P == 0 && W == 1)
1797 S = MCDisassembler_SoftFail;
1798
1799 if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
1800 S = MCDisassembler_SoftFail;
1801
1802 if (type && Rm == 15)
1803 S = MCDisassembler_SoftFail;
1804
1805 if (Rt2 == 15)
1806 S = MCDisassembler_SoftFail;
1807
1808 if (!type && fieldFromInstruction_4(Insn, 8, 4))
1809 S = MCDisassembler_SoftFail;
1810
1811 break;
1812
1813 case ARM_STRH:
1814 case ARM_STRH_PRE:
1815 case ARM_STRH_POST:
1816 if (Rt == 15)
1817 S = MCDisassembler_SoftFail;
1818
1819 if (writeback && (Rn == 15 || Rn == Rt))
1820 S = MCDisassembler_SoftFail;
1821
1822 if (!type && Rm == 15)
1823 S = MCDisassembler_SoftFail;
1824
1825 break;
1826
1827 case ARM_LDRD:
1828 case ARM_LDRD_PRE:
1829 case ARM_LDRD_POST:
1830 if (type && Rn == 15) {
1831 if (Rt2 == 15)
1832 S = MCDisassembler_SoftFail;
1833 break;
1834 }
1835
1836 if (P == 0 && W == 1)
1837 S = MCDisassembler_SoftFail;
1838
1839 if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
1840 S = MCDisassembler_SoftFail;
1841
1842 if (!type && writeback && Rn == 15)
1843 S = MCDisassembler_SoftFail;
1844
1845 if (writeback && (Rn == Rt || Rn == Rt2))
1846 S = MCDisassembler_SoftFail;
1847
1848 break;
1849
1850 case ARM_LDRH:
1851 case ARM_LDRH_PRE:
1852 case ARM_LDRH_POST:
1853 if (type && Rn == 15) {
1854 if (Rt == 15)
1855 S = MCDisassembler_SoftFail;
1856 break;
1857 }
1858
1859 if (Rt == 15)
1860 S = MCDisassembler_SoftFail;
1861
1862 if (!type && Rm == 15)
1863 S = MCDisassembler_SoftFail;
1864
1865 if (!type && writeback && (Rn == 15 || Rn == Rt))
1866 S = MCDisassembler_SoftFail;
1867 break;
1868
1869 case ARM_LDRSH:
1870 case ARM_LDRSH_PRE:
1871 case ARM_LDRSH_POST:
1872 case ARM_LDRSB:
1873 case ARM_LDRSB_PRE:
1874 case ARM_LDRSB_POST:
1875 if (type && Rn == 15){
1876 if (Rt == 15)
1877 S = MCDisassembler_SoftFail;
1878 break;
1879 }
1880
1881 if (type && (Rt == 15 || (writeback && Rn == Rt)))
1882 S = MCDisassembler_SoftFail;
1883
1884 if (!type && (Rt == 15 || Rm == 15))
1885 S = MCDisassembler_SoftFail;
1886
1887 if (!type && writeback && (Rn == 15 || Rn == Rt))
1888 S = MCDisassembler_SoftFail;
1889
1890 break;
1891
1892 default:
1893 break;
1894 }
1895
1896 if (writeback) { // Writeback
1897 Inst->writeback = true;
1898
1899 if (P)
1900 U |= ARMII_IndexModePre << 9;
1901 else
1902 U |= ARMII_IndexModePost << 9;
1903
1904 // On stores, the writeback operand precedes Rt.
1905 switch (MCInst_getOpcode(Inst)) {
1906 case ARM_STRD:
1907 case ARM_STRD_PRE:
1908 case ARM_STRD_POST:
1909 case ARM_STRH:
1910 case ARM_STRH_PRE:
1911 case ARM_STRH_POST:
1912 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1913 return MCDisassembler_Fail;
1914 break;
1915 default:
1916 break;
1917 }
1918 }
1919
1920 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1921 return MCDisassembler_Fail;
1922
1923 switch (MCInst_getOpcode(Inst)) {
1924 case ARM_STRD:
1925 case ARM_STRD_PRE:
1926 case ARM_STRD_POST:
1927 case ARM_LDRD:
1928 case ARM_LDRD_PRE:
1929 case ARM_LDRD_POST:
1930 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt + 1, Address, Decoder)))
1931 return MCDisassembler_Fail;
1932 break;
1933 default:
1934 break;
1935 }
1936
1937 if (writeback) {
1938 // On loads, the writeback operand comes after Rt.
1939 switch (MCInst_getOpcode(Inst)) {
1940 case ARM_LDRD:
1941 case ARM_LDRD_PRE:
1942 case ARM_LDRD_POST:
1943 case ARM_LDRH:
1944 case ARM_LDRH_PRE:
1945 case ARM_LDRH_POST:
1946 case ARM_LDRSH:
1947 case ARM_LDRSH_PRE:
1948 case ARM_LDRSH_POST:
1949 case ARM_LDRSB:
1950 case ARM_LDRSB_PRE:
1951 case ARM_LDRSB_POST:
1952 case ARM_LDRHTr:
1953 case ARM_LDRSBTr:
1954 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1955 return MCDisassembler_Fail;
1956 break;
1957 default:
1958 break;
1959 }
1960 }
1961
1962 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1963 return MCDisassembler_Fail;
1964
1965 if (type) {
1966 MCOperand_CreateReg0(Inst, 0);
1967 MCOperand_CreateImm0(Inst, U | (imm << 4) | Rm);
1968 } else {
1969 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1970 return MCDisassembler_Fail;
1971
1972 MCOperand_CreateImm0(Inst, U);
1973 }
1974
1975 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1976 return MCDisassembler_Fail;
1977
1978 return S;
1979 }
1980
DecodeRFEInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)1981 static DecodeStatus DecodeRFEInstruction(MCInst *Inst, unsigned Insn,
1982 uint64_t Address, const void *Decoder)
1983 {
1984 DecodeStatus S = MCDisassembler_Success;
1985
1986 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
1987 unsigned mode = fieldFromInstruction_4(Insn, 23, 2);
1988
1989 switch (mode) {
1990 case 0:
1991 mode = ARM_AM_da;
1992 break;
1993 case 1:
1994 mode = ARM_AM_ia;
1995 break;
1996 case 2:
1997 mode = ARM_AM_db;
1998 break;
1999 case 3:
2000 mode = ARM_AM_ib;
2001 break;
2002 }
2003
2004 MCOperand_CreateImm0(Inst, mode);
2005
2006 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2007 return MCDisassembler_Fail;
2008
2009 return S;
2010 }
2011
DecodeQADDInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2012 static DecodeStatus DecodeQADDInstruction(MCInst *Inst, unsigned Insn,
2013 uint64_t Address, const void *Decoder)
2014 {
2015 DecodeStatus S = MCDisassembler_Success;
2016
2017 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
2018 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
2019 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
2020 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
2021
2022 if (pred == 0xF)
2023 return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
2024
2025 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2026 return MCDisassembler_Fail;
2027
2028 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
2029 return MCDisassembler_Fail;
2030
2031 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2032 return MCDisassembler_Fail;
2033
2034 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2035 return MCDisassembler_Fail;
2036
2037 return S;
2038 }
2039
DecodeMemMultipleWritebackInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2040 static DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst *Inst,
2041 unsigned Insn, uint64_t Address, const void *Decoder)
2042 {
2043 DecodeStatus S = MCDisassembler_Success;
2044
2045 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
2046 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
2047 unsigned reglist = fieldFromInstruction_4(Insn, 0, 16);
2048
2049 if (pred == 0xF) {
2050 // Ambiguous with RFE and SRS
2051 switch (MCInst_getOpcode(Inst)) {
2052 case ARM_LDMDA:
2053 MCInst_setOpcode(Inst, ARM_RFEDA);
2054 break;
2055 case ARM_LDMDA_UPD:
2056 MCInst_setOpcode(Inst, ARM_RFEDA_UPD);
2057 break;
2058 case ARM_LDMDB:
2059 MCInst_setOpcode(Inst, ARM_RFEDB);
2060 break;
2061 case ARM_LDMDB_UPD:
2062 MCInst_setOpcode(Inst, ARM_RFEDB_UPD);
2063 break;
2064 case ARM_LDMIA:
2065 MCInst_setOpcode(Inst, ARM_RFEIA);
2066 break;
2067 case ARM_LDMIA_UPD:
2068 MCInst_setOpcode(Inst, ARM_RFEIA_UPD);
2069 break;
2070 case ARM_LDMIB:
2071 MCInst_setOpcode(Inst, ARM_RFEIB);
2072 break;
2073 case ARM_LDMIB_UPD:
2074 MCInst_setOpcode(Inst, ARM_RFEIB_UPD);
2075 break;
2076 case ARM_STMDA:
2077 MCInst_setOpcode(Inst, ARM_SRSDA);
2078 break;
2079 case ARM_STMDA_UPD:
2080 MCInst_setOpcode(Inst, ARM_SRSDA_UPD);
2081 break;
2082 case ARM_STMDB:
2083 MCInst_setOpcode(Inst, ARM_SRSDB);
2084 break;
2085 case ARM_STMDB_UPD:
2086 MCInst_setOpcode(Inst, ARM_SRSDB_UPD);
2087 break;
2088 case ARM_STMIA:
2089 MCInst_setOpcode(Inst, ARM_SRSIA);
2090 break;
2091 case ARM_STMIA_UPD:
2092 MCInst_setOpcode(Inst, ARM_SRSIA_UPD);
2093 break;
2094 case ARM_STMIB:
2095 MCInst_setOpcode(Inst, ARM_SRSIB);
2096 break;
2097 case ARM_STMIB_UPD:
2098 MCInst_setOpcode(Inst, ARM_SRSIB_UPD);
2099 break;
2100 default:
2101 return MCDisassembler_Fail;
2102 }
2103
2104 // For stores (which become SRS's, the only operand is the mode.
2105 if (fieldFromInstruction_4(Insn, 20, 1) == 0) {
2106 // Check SRS encoding constraints
2107 if (!(fieldFromInstruction_4(Insn, 22, 1) == 1 &&
2108 fieldFromInstruction_4(Insn, 20, 1) == 0))
2109 return MCDisassembler_Fail;
2110
2111 MCOperand_CreateImm0(Inst, fieldFromInstruction_4(Insn, 0, 4));
2112 return S;
2113 }
2114
2115 return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
2116 }
2117
2118 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2119 return MCDisassembler_Fail;
2120
2121 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2122 return MCDisassembler_Fail; // Tied
2123
2124 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2125 return MCDisassembler_Fail;
2126
2127 if (!Check(&S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
2128 return MCDisassembler_Fail;
2129
2130 return S;
2131 }
2132
2133 // Check for UNPREDICTABLE predicated ESB instruction
DecodeHINTInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2134 static DecodeStatus DecodeHINTInstruction(MCInst *Inst, unsigned Insn,
2135 uint64_t Address, const void *Decoder)
2136 {
2137 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
2138 unsigned imm8 = fieldFromInstruction_4(Insn, 0, 8);
2139 DecodeStatus result = MCDisassembler_Success;
2140
2141 MCOperand_CreateImm0(Inst, imm8);
2142
2143 if (!Check(&result, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2144 return MCDisassembler_Fail;
2145
2146 // ESB is unpredictable if pred != AL. Without the RAS extension, it is a NOP,
2147 // so all predicates should be allowed.
2148 if (imm8 == 0x10 && pred != 0xe && ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureRAS))
2149 result = MCDisassembler_SoftFail;
2150
2151 return result;
2152 }
2153
DecodeCPSInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2154 static DecodeStatus DecodeCPSInstruction(MCInst *Inst, unsigned Insn,
2155 uint64_t Address, const void *Decoder)
2156 {
2157 unsigned imod = fieldFromInstruction_4(Insn, 18, 2);
2158 unsigned M = fieldFromInstruction_4(Insn, 17, 1);
2159 unsigned iflags = fieldFromInstruction_4(Insn, 6, 3);
2160 unsigned mode = fieldFromInstruction_4(Insn, 0, 5);
2161
2162 DecodeStatus S = MCDisassembler_Success;
2163
2164 // This decoder is called from multiple location that do not check
2165 // the full encoding is valid before they do.
2166 if (fieldFromInstruction_4(Insn, 5, 1) != 0 ||
2167 fieldFromInstruction_4(Insn, 16, 1) != 0 ||
2168 fieldFromInstruction_4(Insn, 20, 8) != 0x10)
2169 return MCDisassembler_Fail;
2170
2171 // imod == '01' --> UNPREDICTABLE
2172 // NOTE: Even though this is technically UNPREDICTABLE, we choose to
2173 // return failure here. The '01' imod value is unprintable, so there's
2174 // nothing useful we could do even if we returned UNPREDICTABLE.
2175
2176 if (imod == 1) return MCDisassembler_Fail;
2177
2178 if (imod && M) {
2179 MCInst_setOpcode(Inst, ARM_CPS3p);
2180 MCOperand_CreateImm0(Inst, imod);
2181 MCOperand_CreateImm0(Inst, iflags);
2182 MCOperand_CreateImm0(Inst, mode);
2183 } else if (imod && !M) {
2184 MCInst_setOpcode(Inst, ARM_CPS2p);
2185 MCOperand_CreateImm0(Inst, imod);
2186 MCOperand_CreateImm0(Inst, iflags);
2187 if (mode) S = MCDisassembler_SoftFail;
2188 } else if (!imod && M) {
2189 MCInst_setOpcode(Inst, ARM_CPS1p);
2190 MCOperand_CreateImm0(Inst, mode);
2191 if (iflags) S = MCDisassembler_SoftFail;
2192 } else {
2193 // imod == '00' && M == '0' --> UNPREDICTABLE
2194 MCInst_setOpcode(Inst, ARM_CPS1p);
2195 MCOperand_CreateImm0(Inst, mode);
2196 S = MCDisassembler_SoftFail;
2197 }
2198
2199 return S;
2200 }
2201
DecodeT2CPSInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2202 static DecodeStatus DecodeT2CPSInstruction(MCInst *Inst, unsigned Insn,
2203 uint64_t Address, const void *Decoder)
2204 {
2205 unsigned imod = fieldFromInstruction_4(Insn, 9, 2);
2206 unsigned M = fieldFromInstruction_4(Insn, 8, 1);
2207 unsigned iflags = fieldFromInstruction_4(Insn, 5, 3);
2208 unsigned mode = fieldFromInstruction_4(Insn, 0, 5);
2209
2210 DecodeStatus S = MCDisassembler_Success;
2211
2212 // imod == '01' --> UNPREDICTABLE
2213 // NOTE: Even though this is technically UNPREDICTABLE, we choose to
2214 // return failure here. The '01' imod value is unprintable, so there's
2215 // nothing useful we could do even if we returned UNPREDICTABLE.
2216
2217 if (imod == 1) return MCDisassembler_Fail;
2218
2219 if (imod && M) {
2220 MCInst_setOpcode(Inst, ARM_t2CPS3p);
2221 MCOperand_CreateImm0(Inst, imod);
2222 MCOperand_CreateImm0(Inst, iflags);
2223 MCOperand_CreateImm0(Inst, mode);
2224 } else if (imod && !M) {
2225 MCInst_setOpcode(Inst, ARM_t2CPS2p);
2226 MCOperand_CreateImm0(Inst, imod);
2227 MCOperand_CreateImm0(Inst, iflags);
2228 if (mode) S = MCDisassembler_SoftFail;
2229 } else if (!imod && M) {
2230 MCInst_setOpcode(Inst, ARM_t2CPS1p);
2231 MCOperand_CreateImm0(Inst, mode);
2232 if (iflags) S = MCDisassembler_SoftFail;
2233 } else {
2234 // imod == '00' && M == '0' --> this is a HINT instruction
2235 int imm = fieldFromInstruction_4(Insn, 0, 8);
2236 // HINT are defined only for immediate in [0..4]
2237 if (imm > 4) return MCDisassembler_Fail;
2238
2239 MCInst_setOpcode(Inst, ARM_t2HINT);
2240 MCOperand_CreateImm0(Inst, imm);
2241 }
2242
2243 return S;
2244 }
2245
DecodeT2MOVTWInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2246 static DecodeStatus DecodeT2MOVTWInstruction(MCInst *Inst, unsigned Insn,
2247 uint64_t Address, const void *Decoder)
2248 {
2249 DecodeStatus S = MCDisassembler_Success;
2250
2251 unsigned Rd = fieldFromInstruction_4(Insn, 8, 4);
2252 unsigned imm = 0;
2253
2254 imm |= (fieldFromInstruction_4(Insn, 0, 8) << 0);
2255 imm |= (fieldFromInstruction_4(Insn, 12, 3) << 8);
2256 imm |= (fieldFromInstruction_4(Insn, 16, 4) << 12);
2257 imm |= (fieldFromInstruction_4(Insn, 26, 1) << 11);
2258
2259 if (MCInst_getOpcode(Inst) == ARM_t2MOVTi16)
2260 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
2261 return MCDisassembler_Fail;
2262
2263 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
2264 return MCDisassembler_Fail;
2265
2266 MCOperand_CreateImm0(Inst, imm);
2267
2268 return S;
2269 }
2270
DecodeArmMOVTWInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2271 static DecodeStatus DecodeArmMOVTWInstruction(MCInst *Inst, unsigned Insn,
2272 uint64_t Address, const void *Decoder)
2273 {
2274 DecodeStatus S = MCDisassembler_Success;
2275
2276 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
2277 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
2278 unsigned imm = 0;
2279
2280 imm |= (fieldFromInstruction_4(Insn, 0, 12) << 0);
2281 imm |= (fieldFromInstruction_4(Insn, 16, 4) << 12);
2282
2283 if (MCInst_getOpcode(Inst) == ARM_MOVTi16)
2284 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2285 return MCDisassembler_Fail;
2286
2287 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2288 return MCDisassembler_Fail;
2289
2290 MCOperand_CreateImm0(Inst, imm);
2291
2292 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2293 return MCDisassembler_Fail;
2294
2295 return S;
2296 }
2297
DecodeSMLAInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2298 static DecodeStatus DecodeSMLAInstruction(MCInst *Inst, unsigned Insn,
2299 uint64_t Address, const void *Decoder)
2300 {
2301 DecodeStatus S = MCDisassembler_Success;
2302
2303 unsigned Rd = fieldFromInstruction_4(Insn, 16, 4);
2304 unsigned Rn = fieldFromInstruction_4(Insn, 0, 4);
2305 unsigned Rm = fieldFromInstruction_4(Insn, 8, 4);
2306 unsigned Ra = fieldFromInstruction_4(Insn, 12, 4);
2307 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
2308
2309 if (pred == 0xF)
2310 return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
2311
2312 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2313 return MCDisassembler_Fail;
2314
2315 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2316 return MCDisassembler_Fail;
2317
2318 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
2319 return MCDisassembler_Fail;
2320
2321 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
2322 return MCDisassembler_Fail;
2323
2324 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2325 return MCDisassembler_Fail;
2326
2327 return S;
2328 }
2329
DecodeTSTInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2330 static DecodeStatus DecodeTSTInstruction(MCInst *Inst, unsigned Insn,
2331 uint64_t Address, const void *Decoder)
2332 {
2333 DecodeStatus S = MCDisassembler_Success;
2334 unsigned Pred = fieldFromInstruction_4(Insn, 28, 4);
2335 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
2336 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
2337
2338 if (Pred == 0xF)
2339 return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
2340
2341 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2342 return MCDisassembler_Fail;
2343
2344 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2345 return MCDisassembler_Fail;
2346
2347 if (!Check(&S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
2348 return MCDisassembler_Fail;
2349
2350 return S;
2351 }
2352
DecodeSETPANInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2353 static DecodeStatus DecodeSETPANInstruction(MCInst *Inst, unsigned Insn,
2354 uint64_t Address, const void *Decoder)
2355 {
2356 DecodeStatus S = MCDisassembler_Success;
2357 unsigned Imm = fieldFromInstruction_4(Insn, 9, 1);
2358
2359 if (!ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8_1aOps) || !ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops))
2360 return MCDisassembler_Fail;
2361
2362 // Decoder can be called from DecodeTST, which does not check the full
2363 // encoding is valid.
2364 if (fieldFromInstruction_4(Insn, 20, 12) != 0xf11 ||
2365 fieldFromInstruction_4(Insn, 4, 4) != 0)
2366 return MCDisassembler_Fail;
2367
2368 if (fieldFromInstruction_4(Insn, 10, 10) != 0 ||
2369 fieldFromInstruction_4(Insn, 0, 4) != 0)
2370 S = MCDisassembler_SoftFail;
2371
2372 MCInst_setOpcode(Inst, ARM_SETPAN);
2373 MCOperand_CreateImm0(Inst, Imm);
2374
2375 return S;
2376 }
2377
DecodeAddrModeImm12Operand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)2378 static DecodeStatus DecodeAddrModeImm12Operand(MCInst *Inst, unsigned Val,
2379 uint64_t Address, const void *Decoder)
2380 {
2381 DecodeStatus S = MCDisassembler_Success;
2382 unsigned add = fieldFromInstruction_4(Val, 12, 1);
2383 unsigned imm = fieldFromInstruction_4(Val, 0, 12);
2384 unsigned Rn = fieldFromInstruction_4(Val, 13, 4);
2385
2386 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2387 return MCDisassembler_Fail;
2388
2389 if (!add) imm *= (unsigned int)-1;
2390 if (imm == 0 && !add) imm = (unsigned int)INT32_MIN;
2391
2392 MCOperand_CreateImm0(Inst, imm);
2393 //if (Rn == 15)
2394 // tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
2395
2396 return S;
2397 }
2398
DecodeAddrMode5Operand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)2399 static DecodeStatus DecodeAddrMode5Operand(MCInst *Inst, unsigned Val,
2400 uint64_t Address, const void *Decoder)
2401 {
2402 DecodeStatus S = MCDisassembler_Success;
2403 unsigned Rn = fieldFromInstruction_4(Val, 9, 4);
2404 // U == 1 to add imm, 0 to subtract it.
2405 unsigned U = fieldFromInstruction_4(Val, 8, 1);
2406 unsigned imm = fieldFromInstruction_4(Val, 0, 8);
2407
2408 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2409 return MCDisassembler_Fail;
2410
2411 if (U)
2412 MCOperand_CreateImm0(Inst, ARM_AM_getAM5Opc(ARM_AM_add, (unsigned char)imm));
2413 else
2414 MCOperand_CreateImm0(Inst, ARM_AM_getAM5Opc(ARM_AM_sub, (unsigned char)imm));
2415
2416 return S;
2417 }
2418
DecodeAddrMode5FP16Operand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)2419 static DecodeStatus DecodeAddrMode5FP16Operand(MCInst *Inst, unsigned Val,
2420 uint64_t Address, const void *Decoder)
2421 {
2422 DecodeStatus S = MCDisassembler_Success;
2423 unsigned Rn = fieldFromInstruction_4(Val, 9, 4);
2424 // U == 1 to add imm, 0 to subtract it.
2425 unsigned U = fieldFromInstruction_4(Val, 8, 1);
2426 unsigned imm = fieldFromInstruction_4(Val, 0, 8);
2427
2428 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2429 return MCDisassembler_Fail;
2430
2431 if (U)
2432 MCOperand_CreateImm0(Inst, getAM5FP16Opc(ARM_AM_add, imm));
2433 else
2434 MCOperand_CreateImm0(Inst, getAM5FP16Opc(ARM_AM_sub, imm));
2435
2436 return S;
2437 }
2438
DecodeAddrMode7Operand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)2439 static DecodeStatus DecodeAddrMode7Operand(MCInst *Inst, unsigned Val,
2440 uint64_t Address, const void *Decoder)
2441 {
2442 return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
2443 }
2444
DecodeT2BInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2445 static DecodeStatus DecodeT2BInstruction(MCInst *Inst, unsigned Insn,
2446 uint64_t Address, const void *Decoder)
2447 {
2448 DecodeStatus Status = MCDisassembler_Success;
2449
2450 // Note the J1 and J2 values are from the encoded instruction. So here
2451 // change them to I1 and I2 values via as documented:
2452 // I1 = NOT(J1 EOR S);
2453 // I2 = NOT(J2 EOR S);
2454 // and build the imm32 with one trailing zero as documented:
2455 // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
2456 unsigned S = fieldFromInstruction_4(Insn, 26, 1);
2457 unsigned J1 = fieldFromInstruction_4(Insn, 13, 1);
2458 unsigned J2 = fieldFromInstruction_4(Insn, 11, 1);
2459 unsigned I1 = !(J1 ^ S);
2460 unsigned I2 = !(J2 ^ S);
2461 unsigned imm10 = fieldFromInstruction_4(Insn, 16, 10);
2462 unsigned imm11 = fieldFromInstruction_4(Insn, 0, 11);
2463 unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
2464 int imm32 = SignExtend32(tmp << 1, 25);
2465
2466 MCOperand_CreateImm0(Inst, imm32);
2467
2468 return Status;
2469 }
2470
DecodeBranchImmInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2471 static DecodeStatus DecodeBranchImmInstruction(MCInst *Inst, unsigned Insn,
2472 uint64_t Address, const void *Decoder)
2473 {
2474 DecodeStatus S = MCDisassembler_Success;
2475
2476 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
2477 unsigned imm = fieldFromInstruction_4(Insn, 0, 24) << 2;
2478
2479 if (pred == 0xF) {
2480 MCInst_setOpcode(Inst, ARM_BLXi);
2481 imm |= fieldFromInstruction_4(Insn, 24, 1) << 1;
2482 MCOperand_CreateImm0(Inst, SignExtend32(imm, 26));
2483 return S;
2484 }
2485
2486 MCOperand_CreateImm0(Inst, SignExtend32(imm, 26));
2487
2488 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2489 return MCDisassembler_Fail;
2490
2491 return S;
2492 }
2493
2494
DecodeAddrMode6Operand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)2495 static DecodeStatus DecodeAddrMode6Operand(MCInst *Inst, unsigned Val,
2496 uint64_t Address, const void *Decoder)
2497 {
2498 DecodeStatus S = MCDisassembler_Success;
2499
2500 unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
2501 unsigned align = fieldFromInstruction_4(Val, 4, 2);
2502
2503 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2504 return MCDisassembler_Fail;
2505
2506 if (!align)
2507 MCOperand_CreateImm0(Inst, 0);
2508 else
2509 MCOperand_CreateImm0(Inst, 4 << align);
2510
2511 return S;
2512 }
2513
DecodeVLDInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2514 static DecodeStatus DecodeVLDInstruction(MCInst *Inst, unsigned Insn,
2515 uint64_t Address, const void *Decoder)
2516 {
2517 DecodeStatus S = MCDisassembler_Success;
2518 unsigned wb, Rn, Rm;
2519 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
2520 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
2521 wb = fieldFromInstruction_4(Insn, 16, 4);
2522 Rn = fieldFromInstruction_4(Insn, 16, 4);
2523 Rn |= fieldFromInstruction_4(Insn, 4, 2) << 4;
2524 Rm = fieldFromInstruction_4(Insn, 0, 4);
2525
2526 // First output register
2527 switch (MCInst_getOpcode(Inst)) {
2528 case ARM_VLD1q16: case ARM_VLD1q32: case ARM_VLD1q64: case ARM_VLD1q8:
2529 case ARM_VLD1q16wb_fixed: case ARM_VLD1q16wb_register:
2530 case ARM_VLD1q32wb_fixed: case ARM_VLD1q32wb_register:
2531 case ARM_VLD1q64wb_fixed: case ARM_VLD1q64wb_register:
2532 case ARM_VLD1q8wb_fixed: case ARM_VLD1q8wb_register:
2533 case ARM_VLD2d16: case ARM_VLD2d32: case ARM_VLD2d8:
2534 case ARM_VLD2d16wb_fixed: case ARM_VLD2d16wb_register:
2535 case ARM_VLD2d32wb_fixed: case ARM_VLD2d32wb_register:
2536 case ARM_VLD2d8wb_fixed: case ARM_VLD2d8wb_register:
2537 if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2538 return MCDisassembler_Fail;
2539 break;
2540
2541 case ARM_VLD2b16:
2542 case ARM_VLD2b32:
2543 case ARM_VLD2b8:
2544 case ARM_VLD2b16wb_fixed:
2545 case ARM_VLD2b16wb_register:
2546 case ARM_VLD2b32wb_fixed:
2547 case ARM_VLD2b32wb_register:
2548 case ARM_VLD2b8wb_fixed:
2549 case ARM_VLD2b8wb_register:
2550 if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2551 return MCDisassembler_Fail;
2552 break;
2553
2554 default:
2555 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2556 return MCDisassembler_Fail;
2557 }
2558
2559 // Second output register
2560 switch (MCInst_getOpcode(Inst)) {
2561 case ARM_VLD3d8:
2562 case ARM_VLD3d16:
2563 case ARM_VLD3d32:
2564 case ARM_VLD3d8_UPD:
2565 case ARM_VLD3d16_UPD:
2566 case ARM_VLD3d32_UPD:
2567 case ARM_VLD4d8:
2568 case ARM_VLD4d16:
2569 case ARM_VLD4d32:
2570 case ARM_VLD4d8_UPD:
2571 case ARM_VLD4d16_UPD:
2572 case ARM_VLD4d32_UPD:
2573 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 1) % 32, Address, Decoder)))
2574 return MCDisassembler_Fail;
2575 break;
2576
2577 case ARM_VLD3q8:
2578 case ARM_VLD3q16:
2579 case ARM_VLD3q32:
2580 case ARM_VLD3q8_UPD:
2581 case ARM_VLD3q16_UPD:
2582 case ARM_VLD3q32_UPD:
2583 case ARM_VLD4q8:
2584 case ARM_VLD4q16:
2585 case ARM_VLD4q32:
2586 case ARM_VLD4q8_UPD:
2587 case ARM_VLD4q16_UPD:
2588 case ARM_VLD4q32_UPD:
2589 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2) % 32, Address, Decoder)))
2590 return MCDisassembler_Fail;
2591
2592 default:
2593 break;
2594 }
2595
2596 // Third output register
2597 switch(MCInst_getOpcode(Inst)) {
2598 case ARM_VLD3d8:
2599 case ARM_VLD3d16:
2600 case ARM_VLD3d32:
2601 case ARM_VLD3d8_UPD:
2602 case ARM_VLD3d16_UPD:
2603 case ARM_VLD3d32_UPD:
2604 case ARM_VLD4d8:
2605 case ARM_VLD4d16:
2606 case ARM_VLD4d32:
2607 case ARM_VLD4d8_UPD:
2608 case ARM_VLD4d16_UPD:
2609 case ARM_VLD4d32_UPD:
2610 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2) % 32, Address, Decoder)))
2611 return MCDisassembler_Fail;
2612 break;
2613 case ARM_VLD3q8:
2614 case ARM_VLD3q16:
2615 case ARM_VLD3q32:
2616 case ARM_VLD3q8_UPD:
2617 case ARM_VLD3q16_UPD:
2618 case ARM_VLD3q32_UPD:
2619 case ARM_VLD4q8:
2620 case ARM_VLD4q16:
2621 case ARM_VLD4q32:
2622 case ARM_VLD4q8_UPD:
2623 case ARM_VLD4q16_UPD:
2624 case ARM_VLD4q32_UPD:
2625 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 4) % 32, Address, Decoder)))
2626 return MCDisassembler_Fail;
2627 break;
2628 default:
2629 break;
2630 }
2631
2632 // Fourth output register
2633 switch (MCInst_getOpcode(Inst)) {
2634 case ARM_VLD4d8:
2635 case ARM_VLD4d16:
2636 case ARM_VLD4d32:
2637 case ARM_VLD4d8_UPD:
2638 case ARM_VLD4d16_UPD:
2639 case ARM_VLD4d32_UPD:
2640 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 3) % 32, Address, Decoder)))
2641 return MCDisassembler_Fail;
2642 break;
2643 case ARM_VLD4q8:
2644 case ARM_VLD4q16:
2645 case ARM_VLD4q32:
2646 case ARM_VLD4q8_UPD:
2647 case ARM_VLD4q16_UPD:
2648 case ARM_VLD4q32_UPD:
2649 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 6) % 32, Address, Decoder)))
2650 return MCDisassembler_Fail;
2651 break;
2652 default:
2653 break;
2654 }
2655
2656 // Writeback operand
2657 switch (MCInst_getOpcode(Inst)) {
2658 case ARM_VLD1d8wb_fixed:
2659 case ARM_VLD1d16wb_fixed:
2660 case ARM_VLD1d32wb_fixed:
2661 case ARM_VLD1d64wb_fixed:
2662 case ARM_VLD1d8wb_register:
2663 case ARM_VLD1d16wb_register:
2664 case ARM_VLD1d32wb_register:
2665 case ARM_VLD1d64wb_register:
2666 case ARM_VLD1q8wb_fixed:
2667 case ARM_VLD1q16wb_fixed:
2668 case ARM_VLD1q32wb_fixed:
2669 case ARM_VLD1q64wb_fixed:
2670 case ARM_VLD1q8wb_register:
2671 case ARM_VLD1q16wb_register:
2672 case ARM_VLD1q32wb_register:
2673 case ARM_VLD1q64wb_register:
2674 case ARM_VLD1d8Twb_fixed:
2675 case ARM_VLD1d8Twb_register:
2676 case ARM_VLD1d16Twb_fixed:
2677 case ARM_VLD1d16Twb_register:
2678 case ARM_VLD1d32Twb_fixed:
2679 case ARM_VLD1d32Twb_register:
2680 case ARM_VLD1d64Twb_fixed:
2681 case ARM_VLD1d64Twb_register:
2682 case ARM_VLD1d8Qwb_fixed:
2683 case ARM_VLD1d8Qwb_register:
2684 case ARM_VLD1d16Qwb_fixed:
2685 case ARM_VLD1d16Qwb_register:
2686 case ARM_VLD1d32Qwb_fixed:
2687 case ARM_VLD1d32Qwb_register:
2688 case ARM_VLD1d64Qwb_fixed:
2689 case ARM_VLD1d64Qwb_register:
2690 case ARM_VLD2d8wb_fixed:
2691 case ARM_VLD2d16wb_fixed:
2692 case ARM_VLD2d32wb_fixed:
2693 case ARM_VLD2q8wb_fixed:
2694 case ARM_VLD2q16wb_fixed:
2695 case ARM_VLD2q32wb_fixed:
2696 case ARM_VLD2d8wb_register:
2697 case ARM_VLD2d16wb_register:
2698 case ARM_VLD2d32wb_register:
2699 case ARM_VLD2q8wb_register:
2700 case ARM_VLD2q16wb_register:
2701 case ARM_VLD2q32wb_register:
2702 case ARM_VLD2b8wb_fixed:
2703 case ARM_VLD2b16wb_fixed:
2704 case ARM_VLD2b32wb_fixed:
2705 case ARM_VLD2b8wb_register:
2706 case ARM_VLD2b16wb_register:
2707 case ARM_VLD2b32wb_register:
2708 MCOperand_CreateImm0(Inst, 0);
2709 break;
2710
2711 case ARM_VLD3d8_UPD:
2712 case ARM_VLD3d16_UPD:
2713 case ARM_VLD3d32_UPD:
2714 case ARM_VLD3q8_UPD:
2715 case ARM_VLD3q16_UPD:
2716 case ARM_VLD3q32_UPD:
2717 case ARM_VLD4d8_UPD:
2718 case ARM_VLD4d16_UPD:
2719 case ARM_VLD4d32_UPD:
2720 case ARM_VLD4q8_UPD:
2721 case ARM_VLD4q16_UPD:
2722 case ARM_VLD4q32_UPD:
2723 if (!Check(&S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2724 return MCDisassembler_Fail;
2725 break;
2726
2727 default:
2728 break;
2729 }
2730
2731 // AddrMode6 Base (register+alignment)
2732 if (!Check(&S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2733 return MCDisassembler_Fail;
2734
2735 // AddrMode6 Offset (register)
2736 switch (MCInst_getOpcode(Inst)) {
2737 default:
2738 // The below have been updated to have explicit am6offset split
2739 // between fixed and register offset. For those instructions not
2740 // yet updated, we need to add an additional reg0 operand for the
2741 // fixed variant.
2742 //
2743 // The fixed offset encodes as Rm == 0xd, so we check for that.
2744 if (Rm == 0xd) {
2745 MCOperand_CreateReg0(Inst, 0);
2746 break;
2747 }
2748 // Fall through to handle the register offset variant.
2749
2750 case ARM_VLD1d8wb_fixed:
2751 case ARM_VLD1d16wb_fixed:
2752 case ARM_VLD1d32wb_fixed:
2753 case ARM_VLD1d64wb_fixed:
2754 case ARM_VLD1d8Twb_fixed:
2755 case ARM_VLD1d16Twb_fixed:
2756 case ARM_VLD1d32Twb_fixed:
2757 case ARM_VLD1d64Twb_fixed:
2758 case ARM_VLD1d8Qwb_fixed:
2759 case ARM_VLD1d16Qwb_fixed:
2760 case ARM_VLD1d32Qwb_fixed:
2761 case ARM_VLD1d64Qwb_fixed:
2762 case ARM_VLD1d8wb_register:
2763 case ARM_VLD1d16wb_register:
2764 case ARM_VLD1d32wb_register:
2765 case ARM_VLD1d64wb_register:
2766 case ARM_VLD1q8wb_fixed:
2767 case ARM_VLD1q16wb_fixed:
2768 case ARM_VLD1q32wb_fixed:
2769 case ARM_VLD1q64wb_fixed:
2770 case ARM_VLD1q8wb_register:
2771 case ARM_VLD1q16wb_register:
2772 case ARM_VLD1q32wb_register:
2773 case ARM_VLD1q64wb_register:
2774 // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2775 // variant encodes Rm == 0xf. Anything else is a register offset post-
2776 // increment and we need to add the register operand to the instruction.
2777 if (Rm != 0xD && Rm != 0xF &&
2778 !Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2779 return MCDisassembler_Fail;
2780 break;
2781
2782 case ARM_VLD2d8wb_fixed:
2783 case ARM_VLD2d16wb_fixed:
2784 case ARM_VLD2d32wb_fixed:
2785 case ARM_VLD2b8wb_fixed:
2786 case ARM_VLD2b16wb_fixed:
2787 case ARM_VLD2b32wb_fixed:
2788 case ARM_VLD2q8wb_fixed:
2789 case ARM_VLD2q16wb_fixed:
2790 case ARM_VLD2q32wb_fixed:
2791 break;
2792 }
2793
2794 return S;
2795 }
2796
DecodeVLDST1Instruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2797 static DecodeStatus DecodeVLDST1Instruction(MCInst *Inst, unsigned Insn,
2798 uint64_t Address, const void *Decoder)
2799 {
2800 unsigned load;
2801 unsigned type = fieldFromInstruction_4(Insn, 8, 4);
2802 unsigned align = fieldFromInstruction_4(Insn, 4, 2);
2803 if (type == 6 && (align & 2)) return MCDisassembler_Fail;
2804 if (type == 7 && (align & 2)) return MCDisassembler_Fail;
2805 if (type == 10 && align == 3) return MCDisassembler_Fail;
2806
2807 load = fieldFromInstruction_4(Insn, 21, 1);
2808
2809 return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2810 : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2811 }
2812
DecodeVLDST2Instruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2813 static DecodeStatus DecodeVLDST2Instruction(MCInst *Inst, unsigned Insn,
2814 uint64_t Address, const void *Decoder)
2815 {
2816 unsigned type, align, load;
2817 unsigned size = fieldFromInstruction_4(Insn, 6, 2);
2818 if (size == 3) return MCDisassembler_Fail;
2819
2820 type = fieldFromInstruction_4(Insn, 8, 4);
2821 align = fieldFromInstruction_4(Insn, 4, 2);
2822 if (type == 8 && align == 3) return MCDisassembler_Fail;
2823 if (type == 9 && align == 3) return MCDisassembler_Fail;
2824
2825 load = fieldFromInstruction_4(Insn, 21, 1);
2826
2827 return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2828 : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2829 }
2830
DecodeVLDST3Instruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2831 static DecodeStatus DecodeVLDST3Instruction(MCInst *Inst, unsigned Insn,
2832 uint64_t Address, const void *Decoder)
2833 {
2834 unsigned align, load;
2835 unsigned size = fieldFromInstruction_4(Insn, 6, 2);
2836 if (size == 3) return MCDisassembler_Fail;
2837
2838 align = fieldFromInstruction_4(Insn, 4, 2);
2839 if (align & 2) return MCDisassembler_Fail;
2840
2841 load = fieldFromInstruction_4(Insn, 21, 1);
2842
2843 return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2844 : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2845 }
2846
DecodeVLDST4Instruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2847 static DecodeStatus DecodeVLDST4Instruction(MCInst *Inst, unsigned Insn,
2848 uint64_t Address, const void *Decoder)
2849 {
2850 unsigned load;
2851 unsigned size = fieldFromInstruction_4(Insn, 6, 2);
2852 if (size == 3) return MCDisassembler_Fail;
2853
2854 load = fieldFromInstruction_4(Insn, 21, 1);
2855
2856 return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2857 : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
2858 }
2859
DecodeVSTInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)2860 static DecodeStatus DecodeVSTInstruction(MCInst *Inst, unsigned Insn,
2861 uint64_t Address, const void *Decoder)
2862 {
2863 DecodeStatus S = MCDisassembler_Success;
2864 unsigned wb, Rn, Rm;
2865 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
2866 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
2867 wb = fieldFromInstruction_4(Insn, 16, 4);
2868 Rn = fieldFromInstruction_4(Insn, 16, 4);
2869 Rn |= fieldFromInstruction_4(Insn, 4, 2) << 4;
2870 Rm = fieldFromInstruction_4(Insn, 0, 4);
2871
2872 // Writeback Operand
2873 switch (MCInst_getOpcode(Inst)) {
2874 case ARM_VST1d8wb_fixed:
2875 case ARM_VST1d16wb_fixed:
2876 case ARM_VST1d32wb_fixed:
2877 case ARM_VST1d64wb_fixed:
2878 case ARM_VST1d8wb_register:
2879 case ARM_VST1d16wb_register:
2880 case ARM_VST1d32wb_register:
2881 case ARM_VST1d64wb_register:
2882 case ARM_VST1q8wb_fixed:
2883 case ARM_VST1q16wb_fixed:
2884 case ARM_VST1q32wb_fixed:
2885 case ARM_VST1q64wb_fixed:
2886 case ARM_VST1q8wb_register:
2887 case ARM_VST1q16wb_register:
2888 case ARM_VST1q32wb_register:
2889 case ARM_VST1q64wb_register:
2890 case ARM_VST1d8Twb_fixed:
2891 case ARM_VST1d16Twb_fixed:
2892 case ARM_VST1d32Twb_fixed:
2893 case ARM_VST1d64Twb_fixed:
2894 case ARM_VST1d8Twb_register:
2895 case ARM_VST1d16Twb_register:
2896 case ARM_VST1d32Twb_register:
2897 case ARM_VST1d64Twb_register:
2898 case ARM_VST1d8Qwb_fixed:
2899 case ARM_VST1d16Qwb_fixed:
2900 case ARM_VST1d32Qwb_fixed:
2901 case ARM_VST1d64Qwb_fixed:
2902 case ARM_VST1d8Qwb_register:
2903 case ARM_VST1d16Qwb_register:
2904 case ARM_VST1d32Qwb_register:
2905 case ARM_VST1d64Qwb_register:
2906 case ARM_VST2d8wb_fixed:
2907 case ARM_VST2d16wb_fixed:
2908 case ARM_VST2d32wb_fixed:
2909 case ARM_VST2d8wb_register:
2910 case ARM_VST2d16wb_register:
2911 case ARM_VST2d32wb_register:
2912 case ARM_VST2q8wb_fixed:
2913 case ARM_VST2q16wb_fixed:
2914 case ARM_VST2q32wb_fixed:
2915 case ARM_VST2q8wb_register:
2916 case ARM_VST2q16wb_register:
2917 case ARM_VST2q32wb_register:
2918 case ARM_VST2b8wb_fixed:
2919 case ARM_VST2b16wb_fixed:
2920 case ARM_VST2b32wb_fixed:
2921 case ARM_VST2b8wb_register:
2922 case ARM_VST2b16wb_register:
2923 case ARM_VST2b32wb_register:
2924 if (Rm == 0xF)
2925 return MCDisassembler_Fail;
2926 MCOperand_CreateImm0(Inst, 0);
2927 break;
2928 case ARM_VST3d8_UPD:
2929 case ARM_VST3d16_UPD:
2930 case ARM_VST3d32_UPD:
2931 case ARM_VST3q8_UPD:
2932 case ARM_VST3q16_UPD:
2933 case ARM_VST3q32_UPD:
2934 case ARM_VST4d8_UPD:
2935 case ARM_VST4d16_UPD:
2936 case ARM_VST4d32_UPD:
2937 case ARM_VST4q8_UPD:
2938 case ARM_VST4q16_UPD:
2939 case ARM_VST4q32_UPD:
2940 if (!Check(&S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2941 return MCDisassembler_Fail;
2942 break;
2943 default:
2944 break;
2945 }
2946
2947 // AddrMode6 Base (register+alignment)
2948 if (!Check(&S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2949 return MCDisassembler_Fail;
2950
2951 // AddrMode6 Offset (register)
2952 switch (MCInst_getOpcode(Inst)) {
2953 default:
2954 if (Rm == 0xD)
2955 MCOperand_CreateReg0(Inst, 0);
2956 else if (Rm != 0xF) {
2957 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2958 return MCDisassembler_Fail;
2959 }
2960 break;
2961
2962 case ARM_VST1d8wb_fixed:
2963 case ARM_VST1d16wb_fixed:
2964 case ARM_VST1d32wb_fixed:
2965 case ARM_VST1d64wb_fixed:
2966 case ARM_VST1q8wb_fixed:
2967 case ARM_VST1q16wb_fixed:
2968 case ARM_VST1q32wb_fixed:
2969 case ARM_VST1q64wb_fixed:
2970 case ARM_VST1d8Twb_fixed:
2971 case ARM_VST1d16Twb_fixed:
2972 case ARM_VST1d32Twb_fixed:
2973 case ARM_VST1d64Twb_fixed:
2974 case ARM_VST1d8Qwb_fixed:
2975 case ARM_VST1d16Qwb_fixed:
2976 case ARM_VST1d32Qwb_fixed:
2977 case ARM_VST1d64Qwb_fixed:
2978 case ARM_VST2d8wb_fixed:
2979 case ARM_VST2d16wb_fixed:
2980 case ARM_VST2d32wb_fixed:
2981 case ARM_VST2q8wb_fixed:
2982 case ARM_VST2q16wb_fixed:
2983 case ARM_VST2q32wb_fixed:
2984 case ARM_VST2b8wb_fixed:
2985 case ARM_VST2b16wb_fixed:
2986 case ARM_VST2b32wb_fixed:
2987 break;
2988 }
2989
2990
2991 // First input register
2992 switch (MCInst_getOpcode(Inst)) {
2993 case ARM_VST1q16:
2994 case ARM_VST1q32:
2995 case ARM_VST1q64:
2996 case ARM_VST1q8:
2997 case ARM_VST1q16wb_fixed:
2998 case ARM_VST1q16wb_register:
2999 case ARM_VST1q32wb_fixed:
3000 case ARM_VST1q32wb_register:
3001 case ARM_VST1q64wb_fixed:
3002 case ARM_VST1q64wb_register:
3003 case ARM_VST1q8wb_fixed:
3004 case ARM_VST1q8wb_register:
3005 case ARM_VST2d16:
3006 case ARM_VST2d32:
3007 case ARM_VST2d8:
3008 case ARM_VST2d16wb_fixed:
3009 case ARM_VST2d16wb_register:
3010 case ARM_VST2d32wb_fixed:
3011 case ARM_VST2d32wb_register:
3012 case ARM_VST2d8wb_fixed:
3013 case ARM_VST2d8wb_register:
3014 if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
3015 return MCDisassembler_Fail;
3016 break;
3017
3018 case ARM_VST2b16:
3019 case ARM_VST2b32:
3020 case ARM_VST2b8:
3021 case ARM_VST2b16wb_fixed:
3022 case ARM_VST2b16wb_register:
3023 case ARM_VST2b32wb_fixed:
3024 case ARM_VST2b32wb_register:
3025 case ARM_VST2b8wb_fixed:
3026 case ARM_VST2b8wb_register:
3027 if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
3028 return MCDisassembler_Fail;
3029 break;
3030
3031 default:
3032 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3033 return MCDisassembler_Fail;
3034 }
3035
3036 // Second input register
3037 switch (MCInst_getOpcode(Inst)) {
3038 case ARM_VST3d8:
3039 case ARM_VST3d16:
3040 case ARM_VST3d32:
3041 case ARM_VST3d8_UPD:
3042 case ARM_VST3d16_UPD:
3043 case ARM_VST3d32_UPD:
3044 case ARM_VST4d8:
3045 case ARM_VST4d16:
3046 case ARM_VST4d32:
3047 case ARM_VST4d8_UPD:
3048 case ARM_VST4d16_UPD:
3049 case ARM_VST4d32_UPD:
3050 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 1) % 32, Address, Decoder)))
3051 return MCDisassembler_Fail;
3052 break;
3053
3054 case ARM_VST3q8:
3055 case ARM_VST3q16:
3056 case ARM_VST3q32:
3057 case ARM_VST3q8_UPD:
3058 case ARM_VST3q16_UPD:
3059 case ARM_VST3q32_UPD:
3060 case ARM_VST4q8:
3061 case ARM_VST4q16:
3062 case ARM_VST4q32:
3063 case ARM_VST4q8_UPD:
3064 case ARM_VST4q16_UPD:
3065 case ARM_VST4q32_UPD:
3066 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2) % 32, Address, Decoder)))
3067 return MCDisassembler_Fail;
3068 break;
3069 default:
3070 break;
3071 }
3072
3073 // Third input register
3074 switch (MCInst_getOpcode(Inst)) {
3075 case ARM_VST3d8:
3076 case ARM_VST3d16:
3077 case ARM_VST3d32:
3078 case ARM_VST3d8_UPD:
3079 case ARM_VST3d16_UPD:
3080 case ARM_VST3d32_UPD:
3081 case ARM_VST4d8:
3082 case ARM_VST4d16:
3083 case ARM_VST4d32:
3084 case ARM_VST4d8_UPD:
3085 case ARM_VST4d16_UPD:
3086 case ARM_VST4d32_UPD:
3087 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2) % 32, Address, Decoder)))
3088 return MCDisassembler_Fail;
3089 break;
3090
3091 case ARM_VST3q8:
3092 case ARM_VST3q16:
3093 case ARM_VST3q32:
3094 case ARM_VST3q8_UPD:
3095 case ARM_VST3q16_UPD:
3096 case ARM_VST3q32_UPD:
3097 case ARM_VST4q8:
3098 case ARM_VST4q16:
3099 case ARM_VST4q32:
3100 case ARM_VST4q8_UPD:
3101 case ARM_VST4q16_UPD:
3102 case ARM_VST4q32_UPD:
3103 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 4) % 32, Address, Decoder)))
3104 return MCDisassembler_Fail;
3105 break;
3106 default:
3107 break;
3108 }
3109
3110 // Fourth input register
3111 switch (MCInst_getOpcode(Inst)) {
3112 case ARM_VST4d8:
3113 case ARM_VST4d16:
3114 case ARM_VST4d32:
3115 case ARM_VST4d8_UPD:
3116 case ARM_VST4d16_UPD:
3117 case ARM_VST4d32_UPD:
3118 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 3) % 32, Address, Decoder)))
3119 return MCDisassembler_Fail;
3120 break;
3121
3122 case ARM_VST4q8:
3123 case ARM_VST4q16:
3124 case ARM_VST4q32:
3125 case ARM_VST4q8_UPD:
3126 case ARM_VST4q16_UPD:
3127 case ARM_VST4q32_UPD:
3128 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 6) % 32, Address, Decoder)))
3129 return MCDisassembler_Fail;
3130 break;
3131 default:
3132 break;
3133 }
3134
3135 return S;
3136 }
3137
DecodeVLD1DupInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3138 static DecodeStatus DecodeVLD1DupInstruction(MCInst *Inst, unsigned Insn,
3139 uint64_t Address, const void *Decoder)
3140 {
3141 DecodeStatus S = MCDisassembler_Success;
3142 unsigned Rn, Rm, align, size;
3143 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
3144 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
3145 Rn = fieldFromInstruction_4(Insn, 16, 4);
3146 Rm = fieldFromInstruction_4(Insn, 0, 4);
3147 align = fieldFromInstruction_4(Insn, 4, 1);
3148 size = fieldFromInstruction_4(Insn, 6, 2);
3149
3150 if (size == 0 && align == 1)
3151 return MCDisassembler_Fail;
3152
3153 align *= (1 << size);
3154
3155 switch (MCInst_getOpcode(Inst)) {
3156 case ARM_VLD1DUPq16: case ARM_VLD1DUPq32: case ARM_VLD1DUPq8:
3157 case ARM_VLD1DUPq16wb_fixed: case ARM_VLD1DUPq16wb_register:
3158 case ARM_VLD1DUPq32wb_fixed: case ARM_VLD1DUPq32wb_register:
3159 case ARM_VLD1DUPq8wb_fixed: case ARM_VLD1DUPq8wb_register:
3160 if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
3161 return MCDisassembler_Fail;
3162 break;
3163
3164 default:
3165 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3166 return MCDisassembler_Fail;
3167 break;
3168 }
3169
3170 if (Rm != 0xF) {
3171 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3172 return MCDisassembler_Fail;
3173 }
3174
3175 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3176 return MCDisassembler_Fail;
3177
3178 MCOperand_CreateImm0(Inst, align);
3179
3180 // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
3181 // variant encodes Rm == 0xf. Anything else is a register offset post-
3182 // increment and we need to add the register operand to the instruction.
3183 if (Rm != 0xD && Rm != 0xF &&
3184 !Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3185 return MCDisassembler_Fail;
3186
3187 return S;
3188 }
3189
DecodeVLD2DupInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3190 static DecodeStatus DecodeVLD2DupInstruction(MCInst *Inst, unsigned Insn,
3191 uint64_t Address, const void *Decoder)
3192 {
3193 DecodeStatus S = MCDisassembler_Success;
3194 unsigned Rn, Rm, align, size;
3195 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
3196 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
3197 Rn = fieldFromInstruction_4(Insn, 16, 4);
3198 Rm = fieldFromInstruction_4(Insn, 0, 4);
3199 align = fieldFromInstruction_4(Insn, 4, 1);
3200 size = 1 << fieldFromInstruction_4(Insn, 6, 2);
3201 align *= 2 * size;
3202
3203 switch (MCInst_getOpcode(Inst)) {
3204 case ARM_VLD2DUPd16: case ARM_VLD2DUPd32: case ARM_VLD2DUPd8:
3205 case ARM_VLD2DUPd16wb_fixed: case ARM_VLD2DUPd16wb_register:
3206 case ARM_VLD2DUPd32wb_fixed: case ARM_VLD2DUPd32wb_register:
3207 case ARM_VLD2DUPd8wb_fixed: case ARM_VLD2DUPd8wb_register:
3208 if (!Check(&S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
3209 return MCDisassembler_Fail;
3210 break;
3211
3212 case ARM_VLD2DUPd16x2: case ARM_VLD2DUPd32x2: case ARM_VLD2DUPd8x2:
3213 case ARM_VLD2DUPd16x2wb_fixed: case ARM_VLD2DUPd16x2wb_register:
3214 case ARM_VLD2DUPd32x2wb_fixed: case ARM_VLD2DUPd32x2wb_register:
3215 case ARM_VLD2DUPd8x2wb_fixed: case ARM_VLD2DUPd8x2wb_register:
3216 if (!Check(&S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
3217 return MCDisassembler_Fail;
3218 break;
3219
3220 default:
3221 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3222 return MCDisassembler_Fail;
3223 break;
3224 }
3225
3226 if (Rm != 0xF)
3227 MCOperand_CreateImm0(Inst, 0);
3228
3229 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3230 return MCDisassembler_Fail;
3231
3232 MCOperand_CreateImm0(Inst, align);
3233
3234 if (Rm != 0xD && Rm != 0xF) {
3235 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3236 return MCDisassembler_Fail;
3237 }
3238
3239 return S;
3240 }
3241
DecodeVLD3DupInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3242 static DecodeStatus DecodeVLD3DupInstruction(MCInst *Inst, unsigned Insn,
3243 uint64_t Address, const void *Decoder)
3244 {
3245 DecodeStatus S = MCDisassembler_Success;
3246 unsigned Rn, Rm, inc;
3247 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
3248 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
3249 Rn = fieldFromInstruction_4(Insn, 16, 4);
3250 Rm = fieldFromInstruction_4(Insn, 0, 4);
3251 inc = fieldFromInstruction_4(Insn, 5, 1) + 1;
3252
3253 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3254 return MCDisassembler_Fail;
3255
3256 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + inc) % 32, Address, Decoder)))
3257 return MCDisassembler_Fail;
3258
3259 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2*inc) % 32, Address, Decoder)))
3260 return MCDisassembler_Fail;
3261
3262 if (Rm != 0xF) {
3263 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3264 return MCDisassembler_Fail;
3265 }
3266
3267 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3268 return MCDisassembler_Fail;
3269
3270 MCOperand_CreateImm0(Inst, 0);
3271
3272 if (Rm == 0xD)
3273 MCOperand_CreateReg0(Inst, 0);
3274 else if (Rm != 0xF) {
3275 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3276 return MCDisassembler_Fail;
3277 }
3278
3279 return S;
3280 }
3281
DecodeVLD4DupInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3282 static DecodeStatus DecodeVLD4DupInstruction(MCInst *Inst, unsigned Insn,
3283 uint64_t Address, const void *Decoder)
3284 {
3285 DecodeStatus S = MCDisassembler_Success;
3286 unsigned Rn, Rm, size, inc, align;
3287 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
3288 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
3289 Rn = fieldFromInstruction_4(Insn, 16, 4);
3290 Rm = fieldFromInstruction_4(Insn, 0, 4);
3291 size = fieldFromInstruction_4(Insn, 6, 2);
3292 inc = fieldFromInstruction_4(Insn, 5, 1) + 1;
3293 align = fieldFromInstruction_4(Insn, 4, 1);
3294
3295 if (size == 0x3) {
3296 if (align == 0)
3297 return MCDisassembler_Fail;
3298 align = 16;
3299 } else {
3300 if (size == 2) {
3301 align *= 8;
3302 } else {
3303 size = 1 << size;
3304 align *= 4 * size;
3305 }
3306 }
3307
3308 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3309 return MCDisassembler_Fail;
3310
3311 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + inc) % 32, Address, Decoder)))
3312 return MCDisassembler_Fail;
3313
3314 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 2*inc) % 32, Address, Decoder)))
3315 return MCDisassembler_Fail;
3316
3317 if (!Check(&S, DecodeDPRRegisterClass(Inst, (Rd + 3*inc) % 32, Address, Decoder)))
3318 return MCDisassembler_Fail;
3319
3320 if (Rm != 0xF) {
3321 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3322 return MCDisassembler_Fail;
3323 }
3324
3325 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3326 return MCDisassembler_Fail;
3327
3328 MCOperand_CreateImm0(Inst, align);
3329
3330 if (Rm == 0xD)
3331 MCOperand_CreateReg0(Inst, 0);
3332 else if (Rm != 0xF) {
3333 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3334 return MCDisassembler_Fail;
3335 }
3336
3337 return S;
3338 }
3339
DecodeNEONModImmInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3340 static DecodeStatus DecodeNEONModImmInstruction(MCInst *Inst, unsigned Insn,
3341 uint64_t Address, const void *Decoder)
3342 {
3343 DecodeStatus S = MCDisassembler_Success;
3344 unsigned imm, Q;
3345 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
3346 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
3347 imm = fieldFromInstruction_4(Insn, 0, 4);
3348 imm |= fieldFromInstruction_4(Insn, 16, 3) << 4;
3349 imm |= fieldFromInstruction_4(Insn, 24, 1) << 7;
3350 imm |= fieldFromInstruction_4(Insn, 8, 4) << 8;
3351 imm |= fieldFromInstruction_4(Insn, 5, 1) << 12;
3352 Q = fieldFromInstruction_4(Insn, 6, 1);
3353
3354 if (Q) {
3355 if (!Check(&S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3356 return MCDisassembler_Fail;
3357 } else {
3358 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3359 return MCDisassembler_Fail;
3360 }
3361
3362 MCOperand_CreateImm0(Inst, imm);
3363
3364 switch (MCInst_getOpcode(Inst)) {
3365 case ARM_VORRiv4i16:
3366 case ARM_VORRiv2i32:
3367 case ARM_VBICiv4i16:
3368 case ARM_VBICiv2i32:
3369 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3370 return MCDisassembler_Fail;
3371 break;
3372 case ARM_VORRiv8i16:
3373 case ARM_VORRiv4i32:
3374 case ARM_VBICiv8i16:
3375 case ARM_VBICiv4i32:
3376 if (!Check(&S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3377 return MCDisassembler_Fail;
3378 break;
3379 default:
3380 break;
3381 }
3382
3383 return S;
3384 }
3385
DecodeVSHLMaxInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3386 static DecodeStatus DecodeVSHLMaxInstruction(MCInst *Inst, unsigned Insn,
3387 uint64_t Address, const void *Decoder)
3388 {
3389 DecodeStatus S = MCDisassembler_Success;
3390 unsigned Rm, size;
3391 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
3392 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
3393 Rm = fieldFromInstruction_4(Insn, 0, 4);
3394 Rm |= fieldFromInstruction_4(Insn, 5, 1) << 4;
3395 size = fieldFromInstruction_4(Insn, 18, 2);
3396
3397 if (!Check(&S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3398 return MCDisassembler_Fail;
3399
3400 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3401 return MCDisassembler_Fail;
3402
3403 MCOperand_CreateImm0(Inst, 8 << size);
3404
3405 return S;
3406 }
3407
DecodeShiftRight8Imm(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3408 static DecodeStatus DecodeShiftRight8Imm(MCInst *Inst, unsigned Val,
3409 uint64_t Address, const void *Decoder)
3410 {
3411 MCOperand_CreateImm0(Inst, 8 - Val);
3412
3413 return MCDisassembler_Success;
3414 }
3415
DecodeShiftRight16Imm(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3416 static DecodeStatus DecodeShiftRight16Imm(MCInst *Inst, unsigned Val,
3417 uint64_t Address, const void *Decoder)
3418 {
3419 MCOperand_CreateImm0(Inst, 16 - Val);
3420
3421 return MCDisassembler_Success;
3422 }
3423
DecodeShiftRight32Imm(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3424 static DecodeStatus DecodeShiftRight32Imm(MCInst *Inst, unsigned Val,
3425 uint64_t Address, const void *Decoder)
3426 {
3427 MCOperand_CreateImm0(Inst, 32 - Val);
3428
3429 return MCDisassembler_Success;
3430 }
3431
DecodeShiftRight64Imm(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3432 static DecodeStatus DecodeShiftRight64Imm(MCInst *Inst, unsigned Val,
3433 uint64_t Address, const void *Decoder)
3434 {
3435 MCOperand_CreateImm0(Inst, 64 - Val);
3436
3437 return MCDisassembler_Success;
3438 }
3439
DecodeTBLInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3440 static DecodeStatus DecodeTBLInstruction(MCInst *Inst, unsigned Insn,
3441 uint64_t Address, const void *Decoder)
3442 {
3443 DecodeStatus S = MCDisassembler_Success;
3444 unsigned Rn, Rm, op;
3445 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
3446 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
3447 Rn = fieldFromInstruction_4(Insn, 16, 4);
3448 Rn |= fieldFromInstruction_4(Insn, 7, 1) << 4;
3449 Rm = fieldFromInstruction_4(Insn, 0, 4);
3450 Rm |= fieldFromInstruction_4(Insn, 5, 1) << 4;
3451 op = fieldFromInstruction_4(Insn, 6, 1);
3452
3453 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3454 return MCDisassembler_Fail;
3455
3456 if (op) {
3457 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3458 return MCDisassembler_Fail; // Writeback
3459 }
3460
3461 switch (MCInst_getOpcode(Inst)) {
3462 case ARM_VTBL2:
3463 case ARM_VTBX2:
3464 if (!Check(&S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
3465 return MCDisassembler_Fail;
3466 break;
3467 default:
3468 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
3469 return MCDisassembler_Fail;
3470 }
3471
3472 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3473 return MCDisassembler_Fail;
3474
3475 return S;
3476 }
3477
DecodeThumbAddSpecialReg(MCInst * Inst,uint16_t Insn,uint64_t Address,const void * Decoder)3478 static DecodeStatus DecodeThumbAddSpecialReg(MCInst *Inst, uint16_t Insn,
3479 uint64_t Address, const void *Decoder)
3480 {
3481 DecodeStatus S = MCDisassembler_Success;
3482 unsigned dst = fieldFromInstruction_2(Insn, 8, 3);
3483 unsigned imm = fieldFromInstruction_2(Insn, 0, 8);
3484
3485 if (!Check(&S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
3486 return MCDisassembler_Fail;
3487
3488 switch(MCInst_getOpcode(Inst)) {
3489 default:
3490 return MCDisassembler_Fail;
3491 case ARM_tADR:
3492 break; // tADR does not explicitly represent the PC as an operand.
3493 case ARM_tADDrSPi:
3494 MCOperand_CreateReg0(Inst, ARM_SP);
3495 break;
3496 }
3497
3498 MCOperand_CreateImm0(Inst, imm);
3499
3500 return S;
3501 }
3502
DecodeThumbBROperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3503 static DecodeStatus DecodeThumbBROperand(MCInst *Inst, unsigned Val,
3504 uint64_t Address, const void *Decoder)
3505 {
3506 MCOperand_CreateImm0(Inst, SignExtend32(Val << 1, 12));
3507
3508 return MCDisassembler_Success;
3509 }
3510
DecodeT2BROperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3511 static DecodeStatus DecodeT2BROperand(MCInst *Inst, unsigned Val,
3512 uint64_t Address, const void *Decoder)
3513 {
3514 MCOperand_CreateImm0(Inst, SignExtend32(Val, 21));
3515
3516 return MCDisassembler_Success;
3517 }
3518
DecodeThumbCmpBROperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3519 static DecodeStatus DecodeThumbCmpBROperand(MCInst *Inst, unsigned Val,
3520 uint64_t Address, const void *Decoder)
3521 {
3522 MCOperand_CreateImm0(Inst, Val << 1);
3523
3524 return MCDisassembler_Success;
3525 }
3526
DecodeThumbAddrModeRR(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3527 static DecodeStatus DecodeThumbAddrModeRR(MCInst *Inst, unsigned Val,
3528 uint64_t Address, const void *Decoder)
3529 {
3530 DecodeStatus S = MCDisassembler_Success;
3531 unsigned Rn = fieldFromInstruction_4(Val, 0, 3);
3532 unsigned Rm = fieldFromInstruction_4(Val, 3, 3);
3533
3534 if (!Check(&S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3535 return MCDisassembler_Fail;
3536
3537 if (!Check(&S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
3538 return MCDisassembler_Fail;
3539
3540 return S;
3541 }
3542
DecodeThumbAddrModeIS(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3543 static DecodeStatus DecodeThumbAddrModeIS(MCInst *Inst, unsigned Val,
3544 uint64_t Address, const void *Decoder)
3545 {
3546 DecodeStatus S = MCDisassembler_Success;
3547 unsigned Rn = fieldFromInstruction_4(Val, 0, 3);
3548 unsigned imm = fieldFromInstruction_4(Val, 3, 5);
3549
3550 if (!Check(&S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3551 return MCDisassembler_Fail;
3552
3553 MCOperand_CreateImm0(Inst, imm);
3554
3555 return S;
3556 }
3557
DecodeThumbAddrModePC(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3558 static DecodeStatus DecodeThumbAddrModePC(MCInst *Inst, unsigned Val,
3559 uint64_t Address, const void *Decoder)
3560 {
3561 unsigned imm = Val << 2;
3562
3563 MCOperand_CreateImm0(Inst, imm);
3564 //tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
3565
3566 return MCDisassembler_Success;
3567 }
3568
DecodeThumbAddrModeSP(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3569 static DecodeStatus DecodeThumbAddrModeSP(MCInst *Inst, unsigned Val,
3570 uint64_t Address, const void *Decoder)
3571 {
3572 MCOperand_CreateReg0(Inst, ARM_SP);
3573 MCOperand_CreateImm0(Inst, Val);
3574
3575 return MCDisassembler_Success;
3576 }
3577
DecodeT2AddrModeSOReg(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3578 static DecodeStatus DecodeT2AddrModeSOReg(MCInst *Inst, unsigned Val,
3579 uint64_t Address, const void *Decoder)
3580 {
3581 DecodeStatus S = MCDisassembler_Success;
3582 unsigned Rn = fieldFromInstruction_4(Val, 6, 4);
3583 unsigned Rm = fieldFromInstruction_4(Val, 2, 4);
3584 unsigned imm = fieldFromInstruction_4(Val, 0, 2);
3585
3586 // Thumb stores cannot use PC as dest register.
3587 switch (MCInst_getOpcode(Inst)) {
3588 case ARM_t2STRHs:
3589 case ARM_t2STRBs:
3590 case ARM_t2STRs:
3591 if (Rn == 15)
3592 return MCDisassembler_Fail;
3593 default:
3594 break;
3595 }
3596
3597 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3598 return MCDisassembler_Fail;
3599
3600 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3601 return MCDisassembler_Fail;
3602
3603 MCOperand_CreateImm0(Inst, imm);
3604
3605 return S;
3606 }
3607
DecodeT2LoadShift(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3608 static DecodeStatus DecodeT2LoadShift(MCInst *Inst, unsigned Insn,
3609 uint64_t Address, const void *Decoder)
3610 {
3611 DecodeStatus S = MCDisassembler_Success;
3612 unsigned addrmode;
3613 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
3614 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
3615 bool hasMP = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureMP);
3616 bool hasV7Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops);
3617
3618 if (Rn == 15) {
3619 switch (MCInst_getOpcode(Inst)) {
3620 case ARM_t2LDRBs:
3621 MCInst_setOpcode(Inst, ARM_t2LDRBpci);
3622 break;
3623 case ARM_t2LDRHs:
3624 MCInst_setOpcode(Inst, ARM_t2LDRHpci);
3625 break;
3626 case ARM_t2LDRSHs:
3627 MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
3628 break;
3629 case ARM_t2LDRSBs:
3630 MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
3631 break;
3632 case ARM_t2LDRs:
3633 MCInst_setOpcode(Inst, ARM_t2LDRpci);
3634 break;
3635 case ARM_t2PLDs:
3636 MCInst_setOpcode(Inst, ARM_t2PLDpci);
3637 break;
3638 case ARM_t2PLIs:
3639 MCInst_setOpcode(Inst, ARM_t2PLIpci);
3640 break;
3641 default:
3642 return MCDisassembler_Fail;
3643 }
3644
3645 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3646 }
3647
3648 if (Rt == 15) {
3649 switch (MCInst_getOpcode(Inst)) {
3650 case ARM_t2LDRSHs:
3651 return MCDisassembler_Fail;
3652 case ARM_t2LDRHs:
3653 MCInst_setOpcode(Inst, ARM_t2PLDWs);
3654 break;
3655 case ARM_t2LDRSBs:
3656 MCInst_setOpcode(Inst, ARM_t2PLIs);
3657 default:
3658 break;
3659 }
3660 }
3661
3662 switch (MCInst_getOpcode(Inst)) {
3663 case ARM_t2PLDs:
3664 break;
3665 case ARM_t2PLIs:
3666 if (!hasV7Ops)
3667 return MCDisassembler_Fail;
3668 break;
3669 case ARM_t2PLDWs:
3670 if (!hasV7Ops || !hasMP)
3671 return MCDisassembler_Fail;
3672 break;
3673 default:
3674 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3675 return MCDisassembler_Fail;
3676 }
3677
3678 addrmode = fieldFromInstruction_4(Insn, 4, 2);
3679 addrmode |= fieldFromInstruction_4(Insn, 0, 4) << 2;
3680 addrmode |= fieldFromInstruction_4(Insn, 16, 4) << 6;
3681
3682 if (!Check(&S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
3683 return MCDisassembler_Fail;
3684
3685 return S;
3686 }
3687
DecodeT2LoadImm8(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3688 static DecodeStatus DecodeT2LoadImm8(MCInst *Inst, unsigned Insn,
3689 uint64_t Address, const void* Decoder)
3690 {
3691 DecodeStatus S = MCDisassembler_Success;
3692 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
3693 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
3694 unsigned U = fieldFromInstruction_4(Insn, 9, 1);
3695 unsigned imm = fieldFromInstruction_4(Insn, 0, 8);
3696 unsigned add = fieldFromInstruction_4(Insn, 9, 1);
3697 bool hasMP = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureMP);
3698 bool hasV7Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops);
3699
3700 imm |= (U << 8);
3701 imm |= (Rn << 9);
3702
3703 if (Rn == 15) {
3704 switch (MCInst_getOpcode(Inst)) {
3705 case ARM_t2LDRi8:
3706 MCInst_setOpcode(Inst, ARM_t2LDRpci);
3707 break;
3708 case ARM_t2LDRBi8:
3709 MCInst_setOpcode(Inst, ARM_t2LDRBpci);
3710 break;
3711 case ARM_t2LDRSBi8:
3712 MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
3713 break;
3714 case ARM_t2LDRHi8:
3715 MCInst_setOpcode(Inst, ARM_t2LDRHpci);
3716 break;
3717 case ARM_t2LDRSHi8:
3718 MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
3719 break;
3720 case ARM_t2PLDi8:
3721 MCInst_setOpcode(Inst, ARM_t2PLDpci);
3722 break;
3723 case ARM_t2PLIi8:
3724 MCInst_setOpcode(Inst, ARM_t2PLIpci);
3725 break;
3726 default:
3727 return MCDisassembler_Fail;
3728 }
3729
3730 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3731 }
3732
3733 if (Rt == 15) {
3734 switch (MCInst_getOpcode(Inst)) {
3735 case ARM_t2LDRSHi8:
3736 return MCDisassembler_Fail;
3737 case ARM_t2LDRHi8:
3738 if (!add)
3739 MCInst_setOpcode(Inst, ARM_t2PLDWi8);
3740 break;
3741 case ARM_t2LDRSBi8:
3742 MCInst_setOpcode(Inst, ARM_t2PLIi8);
3743 break;
3744 default:
3745 break;
3746 }
3747 }
3748
3749 switch (MCInst_getOpcode(Inst)) {
3750 case ARM_t2PLDi8:
3751 break;
3752 case ARM_t2PLIi8:
3753 if (!hasV7Ops)
3754 return MCDisassembler_Fail;
3755 break;
3756 case ARM_t2PLDWi8:
3757 if (!hasV7Ops || !hasMP)
3758 return MCDisassembler_Fail;
3759 break;
3760 default:
3761 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3762 return MCDisassembler_Fail;
3763 }
3764
3765 if (!Check(&S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3766 return MCDisassembler_Fail;
3767
3768 return S;
3769 }
3770
DecodeT2LoadImm12(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3771 static DecodeStatus DecodeT2LoadImm12(MCInst *Inst, unsigned Insn,
3772 uint64_t Address, const void* Decoder)
3773 {
3774 DecodeStatus S = MCDisassembler_Success;
3775 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
3776 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
3777 unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
3778 bool hasMP = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureMP);
3779 bool hasV7Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops);
3780
3781 imm |= (Rn << 13);
3782
3783 if (Rn == 15) {
3784 switch (MCInst_getOpcode(Inst)) {
3785 case ARM_t2LDRi12:
3786 MCInst_setOpcode(Inst, ARM_t2LDRpci);
3787 break;
3788 case ARM_t2LDRHi12:
3789 MCInst_setOpcode(Inst, ARM_t2LDRHpci);
3790 break;
3791 case ARM_t2LDRSHi12:
3792 MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
3793 break;
3794 case ARM_t2LDRBi12:
3795 MCInst_setOpcode(Inst, ARM_t2LDRBpci);
3796 break;
3797 case ARM_t2LDRSBi12:
3798 MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
3799 break;
3800 case ARM_t2PLDi12:
3801 MCInst_setOpcode(Inst, ARM_t2PLDpci);
3802 break;
3803 case ARM_t2PLIi12:
3804 MCInst_setOpcode(Inst, ARM_t2PLIpci);
3805 break;
3806 default:
3807 return MCDisassembler_Fail;
3808 }
3809 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3810 }
3811
3812 if (Rt == 15) {
3813 switch (MCInst_getOpcode(Inst)) {
3814 case ARM_t2LDRSHi12:
3815 return MCDisassembler_Fail;
3816 case ARM_t2LDRHi12:
3817 MCInst_setOpcode(Inst, ARM_t2PLDWi12);
3818 break;
3819 case ARM_t2LDRSBi12:
3820 MCInst_setOpcode(Inst, ARM_t2PLIi12);
3821 break;
3822 default:
3823 break;
3824 }
3825 }
3826
3827 switch (MCInst_getOpcode(Inst)) {
3828 case ARM_t2PLDi12:
3829 break;
3830 case ARM_t2PLIi12:
3831 if (!hasV7Ops)
3832 return MCDisassembler_Fail;
3833 break;
3834 case ARM_t2PLDWi12:
3835 if (!hasV7Ops || !hasMP)
3836 return MCDisassembler_Fail;
3837 break;
3838 default:
3839 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3840 return MCDisassembler_Fail;
3841 }
3842
3843 if (!Check(&S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
3844 return MCDisassembler_Fail;
3845
3846 return S;
3847 }
3848
DecodeT2LoadT(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3849 static DecodeStatus DecodeT2LoadT(MCInst *Inst, unsigned Insn,
3850 uint64_t Address, const void* Decoder)
3851 {
3852 DecodeStatus S = MCDisassembler_Success;
3853
3854 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
3855 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
3856 unsigned imm = fieldFromInstruction_4(Insn, 0, 8);
3857 imm |= (Rn << 9);
3858
3859 if (Rn == 15) {
3860 switch (MCInst_getOpcode(Inst)) {
3861 case ARM_t2LDRT:
3862 MCInst_setOpcode(Inst, ARM_t2LDRpci);
3863 break;
3864 case ARM_t2LDRBT:
3865 MCInst_setOpcode(Inst, ARM_t2LDRBpci);
3866 break;
3867 case ARM_t2LDRHT:
3868 MCInst_setOpcode(Inst, ARM_t2LDRHpci);
3869 break;
3870 case ARM_t2LDRSBT:
3871 MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
3872 break;
3873 case ARM_t2LDRSHT:
3874 MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
3875 break;
3876 default:
3877 return MCDisassembler_Fail;
3878 }
3879
3880 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3881 }
3882
3883 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3884 return MCDisassembler_Fail;
3885
3886 if (!Check(&S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3887 return MCDisassembler_Fail;
3888
3889 return S;
3890 }
3891
DecodeT2LoadLabel(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)3892 static DecodeStatus DecodeT2LoadLabel(MCInst *Inst, unsigned Insn,
3893 uint64_t Address, const void* Decoder)
3894 {
3895 DecodeStatus S = MCDisassembler_Success;
3896 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
3897 unsigned U = fieldFromInstruction_4(Insn, 23, 1);
3898 int imm = fieldFromInstruction_4(Insn, 0, 12);
3899 bool hasV7Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops);
3900
3901 if (Rt == 15) {
3902 switch (MCInst_getOpcode(Inst)) {
3903 case ARM_t2LDRBpci:
3904 case ARM_t2LDRHpci:
3905 MCInst_setOpcode(Inst, ARM_t2PLDpci);
3906 break;
3907 case ARM_t2LDRSBpci:
3908 MCInst_setOpcode(Inst, ARM_t2PLIpci);
3909 break;
3910 case ARM_t2LDRSHpci:
3911 return MCDisassembler_Fail;
3912 default:
3913 break;
3914 }
3915 }
3916
3917 switch(MCInst_getOpcode(Inst)) {
3918 case ARM_t2PLDpci:
3919 break;
3920 case ARM_t2PLIpci:
3921 if (!hasV7Ops)
3922 return MCDisassembler_Fail;
3923 break;
3924 default:
3925 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3926 return MCDisassembler_Fail;
3927 }
3928
3929 if (!U) {
3930 // Special case for #-0.
3931 if (imm == 0)
3932 imm = INT32_MIN;
3933 else
3934 imm = -imm;
3935 }
3936
3937 MCOperand_CreateImm0(Inst, imm);
3938
3939 return S;
3940 }
3941
DecodeT2Imm8S4(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3942 static DecodeStatus DecodeT2Imm8S4(MCInst *Inst, unsigned Val,
3943 uint64_t Address, const void *Decoder)
3944 {
3945 if (Val == 0)
3946 MCOperand_CreateImm0(Inst, INT32_MIN);
3947 else {
3948 int imm = Val & 0xFF;
3949
3950 if (!(Val & 0x100)) imm *= -1;
3951
3952 MCOperand_CreateImm0(Inst, imm * 4);
3953 }
3954
3955 return MCDisassembler_Success;
3956 }
3957
DecodeT2AddrModeImm8s4(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3958 static DecodeStatus DecodeT2AddrModeImm8s4(MCInst *Inst, unsigned Val,
3959 uint64_t Address, const void *Decoder)
3960 {
3961 DecodeStatus S = MCDisassembler_Success;
3962 unsigned Rn = fieldFromInstruction_4(Val, 9, 4);
3963 unsigned imm = fieldFromInstruction_4(Val, 0, 9);
3964
3965 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3966 return MCDisassembler_Fail;
3967
3968 if (!Check(&S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
3969 return MCDisassembler_Fail;
3970
3971 return S;
3972 }
3973
DecodeT2AddrModeImm0_1020s4(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3974 static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst *Inst,unsigned Val,
3975 uint64_t Address, const void *Decoder)
3976 {
3977 DecodeStatus S = MCDisassembler_Success;
3978 unsigned Rn = fieldFromInstruction_4(Val, 8, 4);
3979 unsigned imm = fieldFromInstruction_4(Val, 0, 8);
3980
3981 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
3982 return MCDisassembler_Fail;
3983
3984 MCOperand_CreateImm0(Inst, imm);
3985
3986 return S;
3987 }
3988
DecodeT2Imm8(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)3989 static DecodeStatus DecodeT2Imm8(MCInst *Inst, unsigned Val,
3990 uint64_t Address, const void *Decoder)
3991 {
3992 int imm = Val & 0xFF;
3993
3994 if (Val == 0)
3995 imm = INT32_MIN;
3996 else if (!(Val & 0x100))
3997 imm *= -1;
3998
3999 MCOperand_CreateImm0(Inst, imm);
4000
4001 return MCDisassembler_Success;
4002 }
4003
DecodeT2AddrModeImm8(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4004 static DecodeStatus DecodeT2AddrModeImm8(MCInst *Inst, unsigned Val,
4005 uint64_t Address, const void *Decoder)
4006 {
4007 DecodeStatus S = MCDisassembler_Success;
4008
4009 unsigned Rn = fieldFromInstruction_4(Val, 9, 4);
4010 unsigned imm = fieldFromInstruction_4(Val, 0, 9);
4011
4012 // Thumb stores cannot use PC as dest register.
4013 switch (MCInst_getOpcode(Inst)) {
4014 case ARM_t2STRT:
4015 case ARM_t2STRBT:
4016 case ARM_t2STRHT:
4017 case ARM_t2STRi8:
4018 case ARM_t2STRHi8:
4019 case ARM_t2STRBi8:
4020 if (Rn == 15)
4021 return MCDisassembler_Fail;
4022 break;
4023 default:
4024 break;
4025 }
4026
4027 // Some instructions always use an additive offset.
4028 switch (MCInst_getOpcode(Inst)) {
4029 case ARM_t2LDRT:
4030 case ARM_t2LDRBT:
4031 case ARM_t2LDRHT:
4032 case ARM_t2LDRSBT:
4033 case ARM_t2LDRSHT:
4034 case ARM_t2STRT:
4035 case ARM_t2STRBT:
4036 case ARM_t2STRHT:
4037 imm |= 0x100;
4038 break;
4039 default:
4040 break;
4041 }
4042
4043 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4044 return MCDisassembler_Fail;
4045
4046 if (!Check(&S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
4047 return MCDisassembler_Fail;
4048
4049 return S;
4050 }
4051
DecodeT2LdStPre(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4052 static DecodeStatus DecodeT2LdStPre(MCInst *Inst, unsigned Insn,
4053 uint64_t Address, const void *Decoder)
4054 {
4055 DecodeStatus S = MCDisassembler_Success;
4056 unsigned load;
4057 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
4058 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4059 unsigned addr = fieldFromInstruction_4(Insn, 0, 8);
4060 addr |= fieldFromInstruction_4(Insn, 9, 1) << 8;
4061 addr |= Rn << 9;
4062 load = fieldFromInstruction_4(Insn, 20, 1);
4063
4064 if (Rn == 15) {
4065 switch (MCInst_getOpcode(Inst)) {
4066 case ARM_t2LDR_PRE:
4067 case ARM_t2LDR_POST:
4068 MCInst_setOpcode(Inst, ARM_t2LDRpci);
4069 break;
4070 case ARM_t2LDRB_PRE:
4071 case ARM_t2LDRB_POST:
4072 MCInst_setOpcode(Inst, ARM_t2LDRBpci);
4073 break;
4074 case ARM_t2LDRH_PRE:
4075 case ARM_t2LDRH_POST:
4076 MCInst_setOpcode(Inst, ARM_t2LDRHpci);
4077 break;
4078 case ARM_t2LDRSB_PRE:
4079 case ARM_t2LDRSB_POST:
4080 if (Rt == 15)
4081 MCInst_setOpcode(Inst, ARM_t2PLIpci);
4082 else
4083 MCInst_setOpcode(Inst, ARM_t2LDRSBpci);
4084 break;
4085 case ARM_t2LDRSH_PRE:
4086 case ARM_t2LDRSH_POST:
4087 MCInst_setOpcode(Inst, ARM_t2LDRSHpci);
4088 break;
4089 default:
4090 return MCDisassembler_Fail;
4091 }
4092
4093 return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
4094 }
4095
4096 if (!load) {
4097 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4098 return MCDisassembler_Fail;
4099 }
4100
4101 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4102 return MCDisassembler_Fail;
4103
4104 if (load) {
4105 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4106 return MCDisassembler_Fail;
4107 }
4108
4109 if (!Check(&S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
4110 return MCDisassembler_Fail;
4111
4112 return S;
4113 }
4114
DecodeT2AddrModeImm12(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4115 static DecodeStatus DecodeT2AddrModeImm12(MCInst *Inst, unsigned Val,
4116 uint64_t Address, const void *Decoder)
4117 {
4118 DecodeStatus S = MCDisassembler_Success;
4119 unsigned Rn = fieldFromInstruction_4(Val, 13, 4);
4120 unsigned imm = fieldFromInstruction_4(Val, 0, 12);
4121
4122 // Thumb stores cannot use PC as dest register.
4123 switch (MCInst_getOpcode(Inst)) {
4124 case ARM_t2STRi12:
4125 case ARM_t2STRBi12:
4126 case ARM_t2STRHi12:
4127 if (Rn == 15)
4128 return MCDisassembler_Fail;
4129 default:
4130 break;
4131 }
4132
4133 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4134 return MCDisassembler_Fail;
4135
4136 MCOperand_CreateImm0(Inst, imm);
4137
4138 return S;
4139 }
4140
DecodeThumbAddSPImm(MCInst * Inst,uint16_t Insn,uint64_t Address,const void * Decoder)4141 static DecodeStatus DecodeThumbAddSPImm(MCInst *Inst, uint16_t Insn,
4142 uint64_t Address, const void *Decoder)
4143 {
4144 unsigned imm = fieldFromInstruction_2(Insn, 0, 7);
4145
4146 MCOperand_CreateReg0(Inst, ARM_SP);
4147 MCOperand_CreateReg0(Inst, ARM_SP);
4148 MCOperand_CreateImm0(Inst, imm);
4149
4150 return MCDisassembler_Success;
4151 }
4152
DecodeThumbAddSPReg(MCInst * Inst,uint16_t Insn,uint64_t Address,const void * Decoder)4153 static DecodeStatus DecodeThumbAddSPReg(MCInst *Inst, uint16_t Insn,
4154 uint64_t Address, const void *Decoder)
4155 {
4156 DecodeStatus S = MCDisassembler_Success;
4157
4158 if (MCInst_getOpcode(Inst) == ARM_tADDrSP) {
4159 unsigned Rdm = fieldFromInstruction_2(Insn, 0, 3);
4160 Rdm |= fieldFromInstruction_2(Insn, 7, 1) << 3;
4161
4162 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
4163 return MCDisassembler_Fail;
4164
4165 MCOperand_CreateReg0(Inst, ARM_SP);
4166
4167 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
4168 return MCDisassembler_Fail;
4169 } else if (MCInst_getOpcode(Inst) == ARM_tADDspr) {
4170 unsigned Rm = fieldFromInstruction_2(Insn, 3, 4);
4171
4172 MCOperand_CreateReg0(Inst, ARM_SP);
4173 MCOperand_CreateReg0(Inst, ARM_SP);
4174
4175 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4176 return MCDisassembler_Fail;
4177 }
4178
4179 return S;
4180 }
4181
DecodeThumbCPS(MCInst * Inst,uint16_t Insn,uint64_t Address,const void * Decoder)4182 static DecodeStatus DecodeThumbCPS(MCInst *Inst, uint16_t Insn,
4183 uint64_t Address, const void *Decoder)
4184 {
4185 unsigned imod = fieldFromInstruction_2(Insn, 4, 1) | 0x2;
4186 unsigned flags = fieldFromInstruction_2(Insn, 0, 3);
4187
4188 MCOperand_CreateImm0(Inst, imod);
4189 MCOperand_CreateImm0(Inst, flags);
4190
4191 return MCDisassembler_Success;
4192 }
4193
DecodePostIdxReg(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4194 static DecodeStatus DecodePostIdxReg(MCInst *Inst, unsigned Insn,
4195 uint64_t Address, const void *Decoder)
4196 {
4197 DecodeStatus S = MCDisassembler_Success;
4198 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
4199 unsigned add = fieldFromInstruction_4(Insn, 4, 1);
4200
4201 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
4202 return MCDisassembler_Fail;
4203
4204 MCOperand_CreateImm0(Inst, add);
4205
4206 return S;
4207 }
4208
DecodeThumbBLXOffset(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4209 static DecodeStatus DecodeThumbBLXOffset(MCInst *Inst, unsigned Val,
4210 uint64_t Address, const void *Decoder)
4211 {
4212 // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
4213 // Note only one trailing zero not two. Also the J1 and J2 values are from
4214 // the encoded instruction. So here change to I1 and I2 values via:
4215 // I1 = NOT(J1 EOR S);
4216 // I2 = NOT(J2 EOR S);
4217 // and build the imm32 with two trailing zeros as documented:
4218 // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
4219 unsigned S = (Val >> 23) & 1;
4220 unsigned J1 = (Val >> 22) & 1;
4221 unsigned J2 = (Val >> 21) & 1;
4222 unsigned I1 = !(J1 ^ S);
4223 unsigned I2 = !(J2 ^ S);
4224 unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
4225 int imm32 = SignExtend32(tmp << 1, 25);
4226
4227 MCOperand_CreateImm0(Inst, imm32);
4228
4229 return MCDisassembler_Success;
4230 }
4231
DecodeCoprocessor(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4232 static DecodeStatus DecodeCoprocessor(MCInst *Inst, unsigned Val,
4233 uint64_t Address, const void *Decoder)
4234 {
4235 if (Val == 0xA || Val == 0xB)
4236 return MCDisassembler_Fail;
4237
4238 if (ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops) && !(Val == 14 || Val == 15))
4239 return MCDisassembler_Fail;
4240
4241 MCOperand_CreateImm0(Inst, Val);
4242
4243 return MCDisassembler_Success;
4244 }
4245
DecodeThumbTableBranch(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4246 static DecodeStatus DecodeThumbTableBranch(MCInst *Inst, unsigned Insn,
4247 uint64_t Address, const void *Decoder)
4248 {
4249 DecodeStatus S = MCDisassembler_Success;
4250 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4251 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
4252
4253 if (Rn == ARM_SP) S = MCDisassembler_SoftFail;
4254
4255 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4256 return MCDisassembler_Fail;
4257
4258 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
4259 return MCDisassembler_Fail;
4260
4261 return S;
4262 }
4263
DecodeThumb2BCCInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4264 static DecodeStatus DecodeThumb2BCCInstruction(MCInst *Inst, unsigned Insn,
4265 uint64_t Address, const void *Decoder)
4266 {
4267 DecodeStatus S = MCDisassembler_Success;
4268 unsigned brtarget;
4269 unsigned pred = fieldFromInstruction_4(Insn, 22, 4);
4270
4271 if (pred == 0xE || pred == 0xF) {
4272 unsigned imm;
4273 unsigned opc = fieldFromInstruction_4(Insn, 4, 28);
4274 switch (opc) {
4275 default:
4276 return MCDisassembler_Fail;
4277 case 0xf3bf8f4:
4278 MCInst_setOpcode(Inst, ARM_t2DSB);
4279 break;
4280 case 0xf3bf8f5:
4281 MCInst_setOpcode(Inst, ARM_t2DMB);
4282 break;
4283 case 0xf3bf8f6:
4284 MCInst_setOpcode(Inst, ARM_t2ISB);
4285 break;
4286 }
4287
4288 imm = fieldFromInstruction_4(Insn, 0, 4);
4289 return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
4290 }
4291
4292 brtarget = fieldFromInstruction_4(Insn, 0, 11) << 1;
4293 brtarget |= fieldFromInstruction_4(Insn, 11, 1) << 19;
4294 brtarget |= fieldFromInstruction_4(Insn, 13, 1) << 18;
4295 brtarget |= fieldFromInstruction_4(Insn, 16, 6) << 12;
4296 brtarget |= fieldFromInstruction_4(Insn, 26, 1) << 20;
4297
4298 if (!Check(&S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
4299 return MCDisassembler_Fail;
4300
4301 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4302 return MCDisassembler_Fail;
4303
4304 return S;
4305 }
4306
4307 // Decode a shifted immediate operand. These basically consist
4308 // of an 8-bit value, and a 4-bit directive that specifies either
4309 // a splat operation or a rotation.
DecodeT2SOImm(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4310 static DecodeStatus DecodeT2SOImm(MCInst *Inst, unsigned Val,
4311 uint64_t Address, const void *Decoder)
4312 {
4313 unsigned ctrl = fieldFromInstruction_4(Val, 10, 2);
4314
4315 if (ctrl == 0) {
4316 unsigned byte = fieldFromInstruction_4(Val, 8, 2);
4317 unsigned imm = fieldFromInstruction_4(Val, 0, 8);
4318
4319 switch (byte) {
4320 case 0:
4321 MCOperand_CreateImm0(Inst, imm);
4322 break;
4323 case 1:
4324 MCOperand_CreateImm0(Inst, (imm << 16) | imm);
4325 break;
4326 case 2:
4327 MCOperand_CreateImm0(Inst, (imm << 24) | (imm << 8));
4328 break;
4329 case 3:
4330 MCOperand_CreateImm0(Inst, (imm << 24) | (imm << 16) | (imm << 8) | imm);
4331 break;
4332 }
4333 } else {
4334 unsigned unrot = fieldFromInstruction_4(Val, 0, 7) | 0x80;
4335 unsigned rot = fieldFromInstruction_4(Val, 7, 5);
4336 unsigned imm = (unrot >> rot) | (unrot << ((32 - rot) & 31));
4337
4338 MCOperand_CreateImm0(Inst, imm);
4339 }
4340
4341 return MCDisassembler_Success;
4342 }
4343
DecodeThumbBCCTargetOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4344 static DecodeStatus DecodeThumbBCCTargetOperand(MCInst *Inst, unsigned Val,
4345 uint64_t Address, const void *Decoder)
4346 {
4347 MCOperand_CreateImm0(Inst, SignExtend32(Val << 1, 9));
4348
4349 return MCDisassembler_Success;
4350 }
4351
DecodeThumbBLTargetOperand(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4352 static DecodeStatus DecodeThumbBLTargetOperand(MCInst *Inst, unsigned Val,
4353 uint64_t Address, const void *Decoder)
4354 {
4355 // Val is passed in as S:J1:J2:imm10:imm11
4356 // Note no trailing zero after imm11. Also the J1 and J2 values are from
4357 // the encoded instruction. So here change to I1 and I2 values via:
4358 // I1 = NOT(J1 EOR S);
4359 // I2 = NOT(J2 EOR S);
4360 // and build the imm32 with one trailing zero as documented:
4361 // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
4362 unsigned S = (Val >> 23) & 1;
4363 unsigned J1 = (Val >> 22) & 1;
4364 unsigned J2 = (Val >> 21) & 1;
4365 unsigned I1 = !(J1 ^ S);
4366 unsigned I2 = !(J2 ^ S);
4367 unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
4368 int imm32 = SignExtend32(tmp << 1, 25);
4369
4370 MCOperand_CreateImm0(Inst, imm32);
4371
4372 return MCDisassembler_Success;
4373 }
4374
DecodeMemBarrierOption(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4375 static DecodeStatus DecodeMemBarrierOption(MCInst *Inst, unsigned Val,
4376 uint64_t Address, const void *Decoder)
4377 {
4378 if (Val & ~0xf)
4379 return MCDisassembler_Fail;
4380
4381 MCOperand_CreateImm0(Inst, Val);
4382
4383 return MCDisassembler_Success;
4384 }
4385
DecodeInstSyncBarrierOption(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4386 static DecodeStatus DecodeInstSyncBarrierOption(MCInst *Inst, unsigned Val,
4387 uint64_t Address, const void *Decoder)
4388 {
4389 if (Val & ~0xf)
4390 return MCDisassembler_Fail;
4391
4392 MCOperand_CreateImm0(Inst, Val);
4393
4394 return MCDisassembler_Success;
4395 }
4396
DecodeMSRMask(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4397 static DecodeStatus DecodeMSRMask(MCInst *Inst, unsigned Val,
4398 uint64_t Address, const void *Decoder)
4399 {
4400 DecodeStatus S = MCDisassembler_Success;
4401
4402 if (ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureMClass)) {
4403 unsigned ValLow = Val & 0xff;
4404
4405 // Validate the SYSm value first.
4406 switch (ValLow) {
4407 case 0: // apsr
4408 case 1: // iapsr
4409 case 2: // eapsr
4410 case 3: // xpsr
4411 case 5: // ipsr
4412 case 6: // epsr
4413 case 7: // iepsr
4414 case 8: // msp
4415 case 9: // psp
4416 case 16: // primask
4417 case 20: // control
4418 break;
4419 case 17: // basepri
4420 case 18: // basepri_max
4421 case 19: // faultmask
4422 if (!ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops))
4423 // Values basepri, basepri_max and faultmask are only valid for v7m.
4424 return MCDisassembler_Fail;
4425 break;
4426 case 0x8a: // msplim_ns
4427 case 0x8b: // psplim_ns
4428 case 0x91: // basepri_ns
4429 case 0x93: // faultmask_ns
4430 if (!ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8MMainlineOps))
4431 return MCDisassembler_Fail;
4432 // LLVM_FALLTHROUGH;
4433 case 10: // msplim
4434 case 11: // psplim
4435 case 0x88: // msp_ns
4436 case 0x89: // psp_ns
4437 case 0x90: // primask_ns
4438 case 0x94: // control_ns
4439 case 0x98: // sp_ns
4440 if (!ARM_getFeatureBits(Inst->csh->mode, ARM_Feature8MSecExt))
4441 return MCDisassembler_Fail;
4442 break;
4443 default:
4444 return MCDisassembler_SoftFail;
4445 }
4446
4447 if (MCInst_getOpcode(Inst) == ARM_t2MSR_M) {
4448 unsigned Mask = fieldFromInstruction_4(Val, 10, 2);
4449 if (!ARM_getFeatureBits(Inst->csh->mode, ARM_HasV7Ops)) {
4450 // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
4451 // unpredictable.
4452 if (Mask != 2)
4453 S = MCDisassembler_SoftFail;
4454 } else {
4455 // The ARMv7-M architecture stores an additional 2-bit mask value in
4456 // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
4457 // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
4458 // the NZCVQ bits should be moved by the instruction. Bit mask{0}
4459 // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
4460 // only if the processor includes the DSP extension.
4461 if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
4462 (!ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureDSP) && (Mask & 1)))
4463 S = MCDisassembler_SoftFail;
4464 }
4465 }
4466 } else {
4467 // A/R class
4468 if (Val == 0)
4469 return MCDisassembler_Fail;
4470 }
4471
4472 MCOperand_CreateImm0(Inst, Val);
4473 return S;
4474 }
4475
DecodeBankedReg(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)4476 static DecodeStatus DecodeBankedReg(MCInst *Inst, unsigned Val,
4477 uint64_t Address, const void *Decoder)
4478 {
4479 unsigned R = fieldFromInstruction_4(Val, 5, 1);
4480 unsigned SysM = fieldFromInstruction_4(Val, 0, 5);
4481
4482 // The table of encodings for these banked registers comes from B9.2.3 of the
4483 // ARM ARM. There are patterns, but nothing regular enough to make this logic
4484 // neater. So by fiat, these values are UNPREDICTABLE:
4485 if (!lookupBankedRegByEncoding((R << 5) | SysM))
4486 return MCDisassembler_Fail;
4487
4488 MCOperand_CreateImm0(Inst, Val);
4489
4490 return MCDisassembler_Success;
4491 }
4492
DecodeDoubleRegLoad(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4493 static DecodeStatus DecodeDoubleRegLoad(MCInst *Inst, unsigned Insn,
4494 uint64_t Address, const void *Decoder)
4495 {
4496 DecodeStatus S = MCDisassembler_Success;
4497 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
4498 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4499 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
4500
4501 if (Rn == 0xF)
4502 S = MCDisassembler_SoftFail;
4503
4504 if (!Check(&S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
4505 return MCDisassembler_Fail;
4506
4507 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4508 return MCDisassembler_Fail;
4509
4510 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4511 return MCDisassembler_Fail;
4512
4513 return S;
4514 }
4515
DecodeDoubleRegStore(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4516 static DecodeStatus DecodeDoubleRegStore(MCInst *Inst, unsigned Insn,
4517 uint64_t Address, const void *Decoder)
4518 {
4519 DecodeStatus S = MCDisassembler_Success;
4520 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
4521 unsigned Rt = fieldFromInstruction_4(Insn, 0, 4);
4522 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4523 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
4524
4525 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
4526 return MCDisassembler_Fail;
4527
4528 if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt + 1)
4529 S = MCDisassembler_SoftFail;
4530
4531 if (!Check(&S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
4532 return MCDisassembler_Fail;
4533
4534 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4535 return MCDisassembler_Fail;
4536
4537 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4538 return MCDisassembler_Fail;
4539
4540 return S;
4541 }
4542
DecodeLDRPreImm(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4543 static DecodeStatus DecodeLDRPreImm(MCInst *Inst, unsigned Insn,
4544 uint64_t Address, const void *Decoder)
4545 {
4546 DecodeStatus S = MCDisassembler_Success;
4547 unsigned pred;
4548 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4549 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
4550 unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
4551 imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;
4552 imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;
4553 pred = fieldFromInstruction_4(Insn, 28, 4);
4554
4555 if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;
4556
4557 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4558 return MCDisassembler_Fail;
4559
4560 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4561 return MCDisassembler_Fail;
4562
4563 if (!Check(&S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4564 return MCDisassembler_Fail;
4565
4566 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4567 return MCDisassembler_Fail;
4568
4569 return S;
4570 }
4571
DecodeLDRPreReg(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4572 static DecodeStatus DecodeLDRPreReg(MCInst *Inst, unsigned Insn,
4573 uint64_t Address, const void *Decoder)
4574 {
4575 DecodeStatus S = MCDisassembler_Success;
4576 unsigned pred, Rm;
4577 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4578 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
4579 unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
4580 imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;
4581 imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;
4582 pred = fieldFromInstruction_4(Insn, 28, 4);
4583 Rm = fieldFromInstruction_4(Insn, 0, 4);
4584
4585 if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;
4586 if (Rm == 0xF) S = MCDisassembler_SoftFail;
4587
4588 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4589 return MCDisassembler_Fail;
4590
4591 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4592 return MCDisassembler_Fail;
4593
4594 if (!Check(&S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4595 return MCDisassembler_Fail;
4596
4597 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4598 return MCDisassembler_Fail;
4599
4600 return S;
4601 }
4602
DecodeSTRPreImm(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4603 static DecodeStatus DecodeSTRPreImm(MCInst *Inst, unsigned Insn,
4604 uint64_t Address, const void *Decoder)
4605 {
4606 DecodeStatus S = MCDisassembler_Success;
4607 unsigned pred;
4608 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4609 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
4610 unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
4611 imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;
4612 imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;
4613 pred = fieldFromInstruction_4(Insn, 28, 4);
4614
4615 if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;
4616
4617 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4618 return MCDisassembler_Fail;
4619
4620 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4621 return MCDisassembler_Fail;
4622
4623 if (!Check(&S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4624 return MCDisassembler_Fail;
4625
4626 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4627 return MCDisassembler_Fail;
4628
4629 return S;
4630 }
4631
DecodeSTRPreReg(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4632 static DecodeStatus DecodeSTRPreReg(MCInst *Inst, unsigned Insn,
4633 uint64_t Address, const void *Decoder)
4634 {
4635 DecodeStatus S = MCDisassembler_Success;
4636 unsigned pred;
4637 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4638 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
4639 unsigned imm = fieldFromInstruction_4(Insn, 0, 12);
4640 imm |= fieldFromInstruction_4(Insn, 16, 4) << 13;
4641 imm |= fieldFromInstruction_4(Insn, 23, 1) << 12;
4642 pred = fieldFromInstruction_4(Insn, 28, 4);
4643
4644 if (Rn == 0xF || Rn == Rt) S = MCDisassembler_SoftFail;
4645
4646 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4647 return MCDisassembler_Fail;
4648
4649 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4650 return MCDisassembler_Fail;
4651
4652 if (!Check(&S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4653 return MCDisassembler_Fail;
4654
4655 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4656 return MCDisassembler_Fail;
4657
4658 return S;
4659 }
4660
DecodeVLD1LN(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4661 static DecodeStatus DecodeVLD1LN(MCInst *Inst, unsigned Insn,
4662 uint64_t Address, const void *Decoder)
4663 {
4664 DecodeStatus S = MCDisassembler_Success;
4665 unsigned size, align = 0, index = 0;
4666 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4667 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
4668 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
4669 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
4670 size = fieldFromInstruction_4(Insn, 10, 2);
4671
4672 switch (size) {
4673 default:
4674 return MCDisassembler_Fail;
4675 case 0:
4676 if (fieldFromInstruction_4(Insn, 4, 1))
4677 return MCDisassembler_Fail; // UNDEFINED
4678 index = fieldFromInstruction_4(Insn, 5, 3);
4679 break;
4680 case 1:
4681 if (fieldFromInstruction_4(Insn, 5, 1))
4682 return MCDisassembler_Fail; // UNDEFINED
4683 index = fieldFromInstruction_4(Insn, 6, 2);
4684 if (fieldFromInstruction_4(Insn, 4, 1))
4685 align = 2;
4686 break;
4687 case 2:
4688 if (fieldFromInstruction_4(Insn, 6, 1))
4689 return MCDisassembler_Fail; // UNDEFINED
4690
4691 index = fieldFromInstruction_4(Insn, 7, 1);
4692
4693 switch (fieldFromInstruction_4(Insn, 4, 2)) {
4694 case 0 :
4695 align = 0; break;
4696 case 3:
4697 align = 4; break;
4698 default:
4699 return MCDisassembler_Fail;
4700 }
4701 break;
4702 }
4703
4704 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4705 return MCDisassembler_Fail;
4706
4707 if (Rm != 0xF) { // Writeback
4708 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4709 return MCDisassembler_Fail;
4710 }
4711
4712 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4713 return MCDisassembler_Fail;
4714
4715 MCOperand_CreateImm0(Inst, align);
4716
4717 if (Rm != 0xF) {
4718 if (Rm != 0xD) {
4719 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4720 return MCDisassembler_Fail;
4721 } else
4722 MCOperand_CreateReg0(Inst, 0);
4723 }
4724
4725 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4726 return MCDisassembler_Fail;
4727
4728 MCOperand_CreateImm0(Inst, index);
4729
4730 return S;
4731 }
4732
DecodeVST1LN(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4733 static DecodeStatus DecodeVST1LN(MCInst *Inst, unsigned Insn,
4734 uint64_t Address, const void *Decoder)
4735 {
4736 DecodeStatus S = MCDisassembler_Success;
4737 unsigned size, align = 0, index = 0;
4738 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4739 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
4740 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
4741 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
4742 size = fieldFromInstruction_4(Insn, 10, 2);
4743
4744 switch (size) {
4745 default:
4746 return MCDisassembler_Fail;
4747 case 0:
4748 if (fieldFromInstruction_4(Insn, 4, 1))
4749 return MCDisassembler_Fail; // UNDEFINED
4750
4751 index = fieldFromInstruction_4(Insn, 5, 3);
4752 break;
4753 case 1:
4754 if (fieldFromInstruction_4(Insn, 5, 1))
4755 return MCDisassembler_Fail; // UNDEFINED
4756
4757 index = fieldFromInstruction_4(Insn, 6, 2);
4758 if (fieldFromInstruction_4(Insn, 4, 1))
4759 align = 2;
4760 break;
4761 case 2:
4762 if (fieldFromInstruction_4(Insn, 6, 1))
4763 return MCDisassembler_Fail; // UNDEFINED
4764
4765 index = fieldFromInstruction_4(Insn, 7, 1);
4766
4767 switch (fieldFromInstruction_4(Insn, 4, 2)) {
4768 case 0:
4769 align = 0; break;
4770 case 3:
4771 align = 4; break;
4772 default:
4773 return MCDisassembler_Fail;
4774 }
4775 break;
4776 }
4777
4778 if (Rm != 0xF) { // Writeback
4779 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4780 return MCDisassembler_Fail;
4781 }
4782
4783 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4784 return MCDisassembler_Fail;
4785
4786 MCOperand_CreateImm0(Inst, align);
4787
4788 if (Rm != 0xF) {
4789 if (Rm != 0xD) {
4790 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4791 return MCDisassembler_Fail;
4792 } else
4793 MCOperand_CreateReg0(Inst, 0);
4794 }
4795
4796 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4797 return MCDisassembler_Fail;
4798
4799 MCOperand_CreateImm0(Inst, index);
4800
4801 return S;
4802 }
4803
DecodeVLD2LN(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4804 static DecodeStatus DecodeVLD2LN(MCInst *Inst, unsigned Insn,
4805 uint64_t Address, const void *Decoder)
4806 {
4807 DecodeStatus S = MCDisassembler_Success;
4808 unsigned size, align = 0, index = 0, inc = 1;
4809 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4810 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
4811 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
4812 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
4813 size = fieldFromInstruction_4(Insn, 10, 2);
4814
4815 switch (size) {
4816 default:
4817 return MCDisassembler_Fail;
4818 case 0:
4819 index = fieldFromInstruction_4(Insn, 5, 3);
4820 if (fieldFromInstruction_4(Insn, 4, 1))
4821 align = 2;
4822 break;
4823 case 1:
4824 index = fieldFromInstruction_4(Insn, 6, 2);
4825 if (fieldFromInstruction_4(Insn, 4, 1))
4826 align = 4;
4827 if (fieldFromInstruction_4(Insn, 5, 1))
4828 inc = 2;
4829 break;
4830 case 2:
4831 if (fieldFromInstruction_4(Insn, 5, 1))
4832 return MCDisassembler_Fail; // UNDEFINED
4833
4834 index = fieldFromInstruction_4(Insn, 7, 1);
4835 if (fieldFromInstruction_4(Insn, 4, 1) != 0)
4836 align = 8;
4837 if (fieldFromInstruction_4(Insn, 6, 1))
4838 inc = 2;
4839 break;
4840 }
4841
4842 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4843 return MCDisassembler_Fail;
4844
4845 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))
4846 return MCDisassembler_Fail;
4847
4848 if (Rm != 0xF) { // Writeback
4849 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4850 return MCDisassembler_Fail;
4851 }
4852
4853 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4854 return MCDisassembler_Fail;
4855
4856 MCOperand_CreateImm0(Inst, align);
4857
4858 if (Rm != 0xF) {
4859 if (Rm != 0xD) {
4860 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4861 return MCDisassembler_Fail;
4862 } else
4863 MCOperand_CreateReg0(Inst, 0);
4864 }
4865
4866 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4867 return MCDisassembler_Fail;
4868
4869 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))
4870 return MCDisassembler_Fail;
4871
4872 MCOperand_CreateImm0(Inst, index);
4873
4874 return S;
4875 }
4876
DecodeVST2LN(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4877 static DecodeStatus DecodeVST2LN(MCInst *Inst, unsigned Insn,
4878 uint64_t Address, const void *Decoder)
4879 {
4880 DecodeStatus S = MCDisassembler_Success;
4881 unsigned size, align = 0, index = 0, inc = 1;
4882 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4883 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
4884 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
4885 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
4886 size = fieldFromInstruction_4(Insn, 10, 2);
4887
4888 switch (size) {
4889 default:
4890 return MCDisassembler_Fail;
4891 case 0:
4892 index = fieldFromInstruction_4(Insn, 5, 3);
4893 if (fieldFromInstruction_4(Insn, 4, 1))
4894 align = 2;
4895 break;
4896 case 1:
4897 index = fieldFromInstruction_4(Insn, 6, 2);
4898 if (fieldFromInstruction_4(Insn, 4, 1))
4899 align = 4;
4900 if (fieldFromInstruction_4(Insn, 5, 1))
4901 inc = 2;
4902 break;
4903 case 2:
4904 if (fieldFromInstruction_4(Insn, 5, 1))
4905 return MCDisassembler_Fail; // UNDEFINED
4906
4907 index = fieldFromInstruction_4(Insn, 7, 1);
4908 if (fieldFromInstruction_4(Insn, 4, 1) != 0)
4909 align = 8;
4910 if (fieldFromInstruction_4(Insn, 6, 1))
4911 inc = 2;
4912 break;
4913 }
4914
4915 if (Rm != 0xF) { // Writeback
4916 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4917 return MCDisassembler_Fail;
4918 }
4919
4920 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4921 return MCDisassembler_Fail;
4922
4923 MCOperand_CreateImm0(Inst, align);
4924
4925 if (Rm != 0xF) {
4926 if (Rm != 0xD) {
4927 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4928 return MCDisassembler_Fail;
4929 } else
4930 MCOperand_CreateReg0(Inst, 0);
4931 }
4932
4933 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4934 return MCDisassembler_Fail;
4935
4936 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))
4937 return MCDisassembler_Fail;
4938
4939 MCOperand_CreateImm0(Inst, index);
4940
4941 return S;
4942 }
4943
DecodeVLD3LN(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)4944 static DecodeStatus DecodeVLD3LN(MCInst *Inst, unsigned Insn,
4945 uint64_t Address, const void *Decoder)
4946 {
4947 DecodeStatus S = MCDisassembler_Success;
4948 unsigned size, align = 0, index = 0, inc = 1;
4949 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
4950 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
4951 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
4952 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
4953 size = fieldFromInstruction_4(Insn, 10, 2);
4954
4955 switch (size) {
4956 default:
4957 return MCDisassembler_Fail;
4958 case 0:
4959 if (fieldFromInstruction_4(Insn, 4, 1))
4960 return MCDisassembler_Fail; // UNDEFINED
4961 index = fieldFromInstruction_4(Insn, 5, 3);
4962 break;
4963 case 1:
4964 if (fieldFromInstruction_4(Insn, 4, 1))
4965 return MCDisassembler_Fail; // UNDEFINED
4966 index = fieldFromInstruction_4(Insn, 6, 2);
4967 if (fieldFromInstruction_4(Insn, 5, 1))
4968 inc = 2;
4969 break;
4970 case 2:
4971 if (fieldFromInstruction_4(Insn, 4, 2))
4972 return MCDisassembler_Fail; // UNDEFINED
4973 index = fieldFromInstruction_4(Insn, 7, 1);
4974 if (fieldFromInstruction_4(Insn, 6, 1))
4975 inc = 2;
4976 break;
4977 }
4978
4979 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4980 return MCDisassembler_Fail;
4981 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))
4982 return MCDisassembler_Fail;
4983 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))
4984 return MCDisassembler_Fail;
4985
4986 if (Rm != 0xF) { // Writeback
4987 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4988 return MCDisassembler_Fail;
4989 }
4990
4991 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4992 return MCDisassembler_Fail;
4993
4994 MCOperand_CreateImm0(Inst, align);
4995
4996 if (Rm != 0xF) {
4997 if (Rm != 0xD) {
4998 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4999 return MCDisassembler_Fail;
5000 } else
5001 MCOperand_CreateReg0(Inst, 0);
5002 }
5003
5004 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5005 return MCDisassembler_Fail;
5006
5007 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))
5008 return MCDisassembler_Fail;
5009
5010 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))
5011 return MCDisassembler_Fail;
5012
5013 MCOperand_CreateImm0(Inst, index);
5014
5015 return S;
5016 }
5017
DecodeVST3LN(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5018 static DecodeStatus DecodeVST3LN(MCInst *Inst, unsigned Insn,
5019 uint64_t Address, const void *Decoder)
5020 {
5021 DecodeStatus S = MCDisassembler_Success;
5022 unsigned size, align = 0, index = 0, inc = 1;
5023 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
5024 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
5025 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
5026 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
5027 size = fieldFromInstruction_4(Insn, 10, 2);
5028
5029 switch (size) {
5030 default:
5031 return MCDisassembler_Fail;
5032 case 0:
5033 if (fieldFromInstruction_4(Insn, 4, 1))
5034 return MCDisassembler_Fail; // UNDEFINED
5035 index = fieldFromInstruction_4(Insn, 5, 3);
5036 break;
5037 case 1:
5038 if (fieldFromInstruction_4(Insn, 4, 1))
5039 return MCDisassembler_Fail; // UNDEFINED
5040 index = fieldFromInstruction_4(Insn, 6, 2);
5041 if (fieldFromInstruction_4(Insn, 5, 1))
5042 inc = 2;
5043 break;
5044 case 2:
5045 if (fieldFromInstruction_4(Insn, 4, 2))
5046 return MCDisassembler_Fail; // UNDEFINED
5047 index = fieldFromInstruction_4(Insn, 7, 1);
5048 if (fieldFromInstruction_4(Insn, 6, 1))
5049 inc = 2;
5050 break;
5051 }
5052
5053 if (Rm != 0xF) { // Writeback
5054 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5055 return MCDisassembler_Fail;
5056 }
5057
5058 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5059 return MCDisassembler_Fail;
5060
5061 MCOperand_CreateImm0(Inst, align);
5062
5063 if (Rm != 0xF) {
5064 if (Rm != 0xD) {
5065 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5066 return MCDisassembler_Fail;
5067 } else
5068 MCOperand_CreateReg0(Inst, 0);
5069 }
5070
5071 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5072 return MCDisassembler_Fail;
5073
5074 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))
5075 return MCDisassembler_Fail;
5076
5077 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))
5078 return MCDisassembler_Fail;
5079
5080 MCOperand_CreateImm0(Inst, index);
5081
5082 return S;
5083 }
5084
DecodeVLD4LN(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5085 static DecodeStatus DecodeVLD4LN(MCInst *Inst, unsigned Insn,
5086 uint64_t Address, const void *Decoder)
5087 {
5088 DecodeStatus S = MCDisassembler_Success;
5089 unsigned size, align = 0, index = 0, inc = 1;
5090 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
5091 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
5092 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
5093 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
5094 size = fieldFromInstruction_4(Insn, 10, 2);
5095
5096 switch (size) {
5097 default:
5098 return MCDisassembler_Fail;
5099 case 0:
5100 if (fieldFromInstruction_4(Insn, 4, 1))
5101 align = 4;
5102 index = fieldFromInstruction_4(Insn, 5, 3);
5103 break;
5104 case 1:
5105 if (fieldFromInstruction_4(Insn, 4, 1))
5106 align = 8;
5107 index = fieldFromInstruction_4(Insn, 6, 2);
5108 if (fieldFromInstruction_4(Insn, 5, 1))
5109 inc = 2;
5110 break;
5111 case 2:
5112 switch (fieldFromInstruction_4(Insn, 4, 2)) {
5113 case 0:
5114 align = 0; break;
5115 case 3:
5116 return MCDisassembler_Fail;
5117 default:
5118 align = 4 << fieldFromInstruction_4(Insn, 4, 2); break;
5119 }
5120
5121 index = fieldFromInstruction_4(Insn, 7, 1);
5122 if (fieldFromInstruction_4(Insn, 6, 1))
5123 inc = 2;
5124 break;
5125 }
5126
5127 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5128 return MCDisassembler_Fail;
5129
5130 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))
5131 return MCDisassembler_Fail;
5132
5133 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))
5134 return MCDisassembler_Fail;
5135
5136 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 3*inc, Address, Decoder)))
5137 return MCDisassembler_Fail;
5138
5139 if (Rm != 0xF) { // Writeback
5140 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5141 return MCDisassembler_Fail;
5142 }
5143
5144 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5145 return MCDisassembler_Fail;
5146
5147 MCOperand_CreateImm0(Inst, align);
5148
5149 if (Rm != 0xF) {
5150 if (Rm != 0xD) {
5151 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5152 return MCDisassembler_Fail;
5153 } else
5154 MCOperand_CreateReg0(Inst, 0);
5155 }
5156
5157 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5158 return MCDisassembler_Fail;
5159
5160 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))
5161 return MCDisassembler_Fail;
5162
5163 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))
5164 return MCDisassembler_Fail;
5165
5166 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 3*inc, Address, Decoder)))
5167 return MCDisassembler_Fail;
5168
5169 MCOperand_CreateImm0(Inst, index);
5170
5171 return S;
5172 }
5173
DecodeVST4LN(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5174 static DecodeStatus DecodeVST4LN(MCInst *Inst, unsigned Insn,
5175 uint64_t Address, const void *Decoder)
5176 {
5177 DecodeStatus S = MCDisassembler_Success;
5178 unsigned size, align = 0, index = 0, inc = 1;
5179 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
5180 unsigned Rm = fieldFromInstruction_4(Insn, 0, 4);
5181 unsigned Rd = fieldFromInstruction_4(Insn, 12, 4);
5182 Rd |= fieldFromInstruction_4(Insn, 22, 1) << 4;
5183 size = fieldFromInstruction_4(Insn, 10, 2);
5184
5185 switch (size) {
5186 default:
5187 return MCDisassembler_Fail;
5188 case 0:
5189 if (fieldFromInstruction_4(Insn, 4, 1))
5190 align = 4;
5191 index = fieldFromInstruction_4(Insn, 5, 3);
5192 break;
5193 case 1:
5194 if (fieldFromInstruction_4(Insn, 4, 1))
5195 align = 8;
5196 index = fieldFromInstruction_4(Insn, 6, 2);
5197 if (fieldFromInstruction_4(Insn, 5, 1))
5198 inc = 2;
5199 break;
5200 case 2:
5201 switch (fieldFromInstruction_4(Insn, 4, 2)) {
5202 case 0:
5203 align = 0; break;
5204 case 3:
5205 return MCDisassembler_Fail;
5206 default:
5207 align = 4 << fieldFromInstruction_4(Insn, 4, 2); break;
5208 }
5209
5210 index = fieldFromInstruction_4(Insn, 7, 1);
5211 if (fieldFromInstruction_4(Insn, 6, 1))
5212 inc = 2;
5213 break;
5214 }
5215
5216 if (Rm != 0xF) { // Writeback
5217 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5218 return MCDisassembler_Fail;
5219 }
5220
5221 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
5222 return MCDisassembler_Fail;
5223
5224 MCOperand_CreateImm0(Inst, align);
5225
5226 if (Rm != 0xF) {
5227 if (Rm != 0xD) {
5228 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
5229 return MCDisassembler_Fail;
5230 } else
5231 MCOperand_CreateReg0(Inst, 0);
5232 }
5233
5234 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
5235 return MCDisassembler_Fail;
5236
5237 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + inc, Address, Decoder)))
5238 return MCDisassembler_Fail;
5239
5240 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 2*inc, Address, Decoder)))
5241 return MCDisassembler_Fail;
5242
5243 if (!Check(&S, DecodeDPRRegisterClass(Inst, Rd + 3*inc, Address, Decoder)))
5244 return MCDisassembler_Fail;
5245
5246 MCOperand_CreateImm0(Inst, index);
5247
5248 return S;
5249 }
5250
DecodeVMOVSRR(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5251 static DecodeStatus DecodeVMOVSRR(MCInst *Inst, unsigned Insn,
5252 uint64_t Address, const void *Decoder)
5253 {
5254 DecodeStatus S = MCDisassembler_Success;
5255 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
5256 unsigned Rt2 = fieldFromInstruction_4(Insn, 16, 4);
5257 unsigned Rm = fieldFromInstruction_4(Insn, 5, 1);
5258 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
5259 Rm |= fieldFromInstruction_4(Insn, 0, 4) << 1;
5260
5261 if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
5262 S = MCDisassembler_SoftFail;
5263
5264 if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)))
5265 return MCDisassembler_Fail;
5266
5267 if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm + 1, Address, Decoder)))
5268 return MCDisassembler_Fail;
5269
5270 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)))
5271 return MCDisassembler_Fail;
5272
5273 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
5274 return MCDisassembler_Fail;
5275
5276 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5277 return MCDisassembler_Fail;
5278
5279 return S;
5280 }
5281
DecodeVMOVRRS(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5282 static DecodeStatus DecodeVMOVRRS(MCInst *Inst, unsigned Insn,
5283 uint64_t Address, const void *Decoder)
5284 {
5285 DecodeStatus S = MCDisassembler_Success;
5286 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
5287 unsigned Rt2 = fieldFromInstruction_4(Insn, 16, 4);
5288 unsigned Rm = fieldFromInstruction_4(Insn, 5, 1);
5289 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
5290 Rm |= fieldFromInstruction_4(Insn, 0, 4) << 1;
5291
5292 if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
5293 S = MCDisassembler_SoftFail;
5294
5295 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)))
5296 return MCDisassembler_Fail;
5297
5298 if (!Check(&S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
5299 return MCDisassembler_Fail;
5300
5301 if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)))
5302 return MCDisassembler_Fail;
5303
5304 if (!Check(&S, DecodeSPRRegisterClass(Inst, Rm + 1, Address, Decoder)))
5305 return MCDisassembler_Fail;
5306
5307 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5308 return MCDisassembler_Fail;
5309
5310 return S;
5311 }
5312
DecodeIT(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5313 static DecodeStatus DecodeIT(MCInst *Inst, unsigned Insn,
5314 uint64_t Address, const void *Decoder)
5315 {
5316 DecodeStatus S = MCDisassembler_Success;
5317 unsigned pred = fieldFromInstruction_4(Insn, 4, 4);
5318 unsigned mask = fieldFromInstruction_4(Insn, 0, 4);
5319
5320 if (pred == 0xF) {
5321 pred = 0xE;
5322 S = MCDisassembler_SoftFail;
5323 }
5324
5325 if (mask == 0x0)
5326 return MCDisassembler_Fail;
5327
5328 MCOperand_CreateImm0(Inst, pred);
5329 MCOperand_CreateImm0(Inst, mask);
5330
5331 return S;
5332 }
5333
DecodeT2LDRDPreInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5334 static DecodeStatus DecodeT2LDRDPreInstruction(MCInst *Inst, unsigned Insn,
5335 uint64_t Address, const void *Decoder)
5336 {
5337 DecodeStatus S = MCDisassembler_Success;
5338 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
5339 unsigned Rt2 = fieldFromInstruction_4(Insn, 8, 4);
5340 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
5341 unsigned addr = fieldFromInstruction_4(Insn, 0, 8);
5342 unsigned W = fieldFromInstruction_4(Insn, 21, 1);
5343 unsigned U = fieldFromInstruction_4(Insn, 23, 1);
5344 unsigned P = fieldFromInstruction_4(Insn, 24, 1);
5345 bool writeback = (W == 1) | (P == 0);
5346
5347 addr |= (U << 8) | (Rn << 9);
5348
5349 if (writeback && (Rn == Rt || Rn == Rt2))
5350 Check(&S, MCDisassembler_SoftFail);
5351
5352 if (Rt == Rt2)
5353 Check(&S, MCDisassembler_SoftFail);
5354
5355 // Rt
5356 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
5357 return MCDisassembler_Fail;
5358
5359 // Rt2
5360 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
5361 return MCDisassembler_Fail;
5362
5363 // Writeback operand
5364 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
5365 return MCDisassembler_Fail;
5366
5367 // addr
5368 if (!Check(&S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
5369 return MCDisassembler_Fail;
5370
5371 return S;
5372 }
5373
DecodeT2STRDPreInstruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5374 static DecodeStatus DecodeT2STRDPreInstruction(MCInst *Inst, unsigned Insn,
5375 uint64_t Address, const void *Decoder)
5376 {
5377 DecodeStatus S = MCDisassembler_Success;
5378 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
5379 unsigned Rt2 = fieldFromInstruction_4(Insn, 8, 4);
5380 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
5381 unsigned addr = fieldFromInstruction_4(Insn, 0, 8);
5382 unsigned W = fieldFromInstruction_4(Insn, 21, 1);
5383 unsigned U = fieldFromInstruction_4(Insn, 23, 1);
5384 unsigned P = fieldFromInstruction_4(Insn, 24, 1);
5385 bool writeback = (W == 1) | (P == 0);
5386
5387 addr |= (U << 8) | (Rn << 9);
5388
5389 if (writeback && (Rn == Rt || Rn == Rt2))
5390 Check(&S, MCDisassembler_SoftFail);
5391
5392 // Writeback operand
5393 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
5394 return MCDisassembler_Fail;
5395
5396 // Rt
5397 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
5398 return MCDisassembler_Fail;
5399
5400 // Rt2
5401 if (!Check(&S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
5402 return MCDisassembler_Fail;
5403
5404 // addr
5405 if (!Check(&S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
5406 return MCDisassembler_Fail;
5407
5408 return S;
5409 }
5410
DecodeT2Adr(MCInst * Inst,uint32_t Insn,uint64_t Address,const void * Decoder)5411 static DecodeStatus DecodeT2Adr(MCInst *Inst, uint32_t Insn,
5412 uint64_t Address, const void *Decoder)
5413 {
5414 unsigned Val;
5415 unsigned sign1 = fieldFromInstruction_4(Insn, 21, 1);
5416 unsigned sign2 = fieldFromInstruction_4(Insn, 23, 1);
5417
5418 if (sign1 != sign2) return MCDisassembler_Fail;
5419
5420 Val = fieldFromInstruction_4(Insn, 0, 8);
5421 Val |= fieldFromInstruction_4(Insn, 12, 3) << 8;
5422 Val |= fieldFromInstruction_4(Insn, 26, 1) << 11;
5423 Val |= sign1 << 12;
5424
5425 MCOperand_CreateImm0(Inst, SignExtend32(Val, 13));
5426
5427 return MCDisassembler_Success;
5428 }
5429
DecodeT2ShifterImmOperand(MCInst * Inst,uint32_t Val,uint64_t Address,const void * Decoder)5430 static DecodeStatus DecodeT2ShifterImmOperand(MCInst *Inst, uint32_t Val,
5431 uint64_t Address, const void *Decoder)
5432 {
5433 // Shift of "asr #32" is not allowed in Thumb2 mode.
5434 if (Val == 0x20)
5435 return MCDisassembler_Fail;
5436
5437 MCOperand_CreateImm0(Inst, Val);
5438
5439 return MCDisassembler_Success;
5440 }
5441
DecodeSwap(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5442 static DecodeStatus DecodeSwap(MCInst *Inst, unsigned Insn,
5443 uint64_t Address, const void *Decoder)
5444 {
5445 DecodeStatus S;
5446 unsigned Rt = fieldFromInstruction_4(Insn, 12, 4);
5447 unsigned Rt2 = fieldFromInstruction_4(Insn, 0, 4);
5448 unsigned Rn = fieldFromInstruction_4(Insn, 16, 4);
5449 unsigned pred = fieldFromInstruction_4(Insn, 28, 4);
5450
5451 if (pred == 0xF)
5452 return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
5453
5454 S = MCDisassembler_Success;
5455
5456 if (Rt == Rn || Rn == Rt2)
5457 S = MCDisassembler_SoftFail;
5458
5459 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5460 return MCDisassembler_Fail;
5461
5462 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5463 return MCDisassembler_Fail;
5464
5465 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
5466 return MCDisassembler_Fail;
5467
5468 if (!Check(&S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5469 return MCDisassembler_Fail;
5470
5471 return S;
5472 }
5473
DecodeVCVTD(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5474 static DecodeStatus DecodeVCVTD(MCInst *Inst, unsigned Insn,
5475 uint64_t Address, const void *Decoder)
5476 {
5477 DecodeStatus S = MCDisassembler_Success;
5478 bool hasFullFP16 = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureFullFP16);
5479 unsigned Vm, imm, cmode, op;
5480 unsigned Vd = (fieldFromInstruction_4(Insn, 12, 4) << 0);
5481
5482 Vd |= (fieldFromInstruction_4(Insn, 22, 1) << 4);
5483 Vm = (fieldFromInstruction_4(Insn, 0, 4) << 0);
5484 Vm |= (fieldFromInstruction_4(Insn, 5, 1) << 4);
5485 imm = fieldFromInstruction_4(Insn, 16, 6);
5486 cmode = fieldFromInstruction_4(Insn, 8, 4);
5487 op = fieldFromInstruction_4(Insn, 5, 1);
5488
5489 // If the top 3 bits of imm are clear, this is a VMOV (immediate)
5490 if (!(imm & 0x38)) {
5491 if (cmode == 0xF) {
5492 if (op == 1) return MCDisassembler_Fail;
5493 MCInst_setOpcode(Inst, ARM_VMOVv2f32);
5494 }
5495
5496 if (hasFullFP16) {
5497 if (cmode == 0xE) {
5498 if (op == 1) {
5499 MCInst_setOpcode(Inst, ARM_VMOVv1i64);
5500 } else {
5501 MCInst_setOpcode(Inst, ARM_VMOVv8i8);
5502 }
5503 }
5504
5505 if (cmode == 0xD) {
5506 if (op == 1) {
5507 MCInst_setOpcode(Inst, ARM_VMVNv2i32);
5508 } else {
5509 MCInst_setOpcode(Inst, ARM_VMOVv2i32);
5510 }
5511 }
5512
5513 if (cmode == 0xC) {
5514 if (op == 1) {
5515 MCInst_setOpcode(Inst, ARM_VMVNv2i32);
5516 } else {
5517 MCInst_setOpcode(Inst, ARM_VMOVv2i32);
5518 }
5519 }
5520 }
5521
5522 return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
5523 }
5524
5525 if (!(imm & 0x20)) return MCDisassembler_Fail;
5526
5527 if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
5528 return MCDisassembler_Fail;
5529
5530 if (!Check(&S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
5531 return MCDisassembler_Fail;
5532
5533 MCOperand_CreateImm0(Inst, 64 - imm);
5534
5535 return S;
5536 }
5537
DecodeVCVTQ(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5538 static DecodeStatus DecodeVCVTQ(MCInst *Inst, unsigned Insn,
5539 uint64_t Address, const void *Decoder)
5540 {
5541 DecodeStatus S = MCDisassembler_Success;
5542 bool hasFullFP16 = ARM_getFeatureBits(Inst->csh->mode, ARM_FeatureFullFP16);
5543 unsigned Vm, imm, cmode, op;
5544 unsigned Vd = (fieldFromInstruction_4(Insn, 12, 4) << 0);
5545
5546 Vd |= (fieldFromInstruction_4(Insn, 22, 1) << 4);
5547 Vm = (fieldFromInstruction_4(Insn, 0, 4) << 0);
5548 Vm |= (fieldFromInstruction_4(Insn, 5, 1) << 4);
5549 imm = fieldFromInstruction_4(Insn, 16, 6);
5550 cmode = fieldFromInstruction_4(Insn, 8, 4);
5551 op = fieldFromInstruction_4(Insn, 5, 1);
5552
5553 // VMOVv4f32 is ambiguous with these decodings.
5554 if (!(imm & 0x38) && cmode == 0xF) {
5555 if (op == 1) return MCDisassembler_Fail;
5556 MCInst_setOpcode(Inst, ARM_VMOVv4f32);
5557 return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
5558 }
5559
5560 // If the top 3 bits of imm are clear, this is a VMOV (immediate)
5561 if (!(imm & 0x38)) {
5562 if (cmode == 0xF) {
5563 if (op == 1) return MCDisassembler_Fail;
5564 MCInst_setOpcode(Inst, ARM_VMOVv4f32);
5565 }
5566
5567 if (hasFullFP16) {
5568 if (cmode == 0xE) {
5569 if (op == 1) {
5570 MCInst_setOpcode(Inst, ARM_VMOVv2i64);
5571 } else {
5572 MCInst_setOpcode(Inst, ARM_VMOVv16i8);
5573 }
5574 }
5575
5576 if (cmode == 0xD) {
5577 if (op == 1) {
5578 MCInst_setOpcode(Inst, ARM_VMVNv4i32);
5579 } else {
5580 MCInst_setOpcode(Inst, ARM_VMOVv4i32);
5581 }
5582 }
5583
5584 if (cmode == 0xC) {
5585 if (op == 1) {
5586 MCInst_setOpcode(Inst, ARM_VMVNv4i32);
5587 } else {
5588 MCInst_setOpcode(Inst, ARM_VMOVv4i32);
5589 }
5590 }
5591 }
5592
5593 return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
5594 }
5595
5596 if (!(imm & 0x20)) return MCDisassembler_Fail;
5597
5598 if (!Check(&S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
5599 return MCDisassembler_Fail;
5600
5601 if (!Check(&S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
5602 return MCDisassembler_Fail;
5603
5604 MCOperand_CreateImm0(Inst, 64 - imm);
5605
5606 return S;
5607 }
5608
DecodeNEONComplexLane64Instruction(MCInst * Inst,unsigned Insn,uint64_t Address,const void * Decoder)5609 static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst *Inst, unsigned Insn,
5610 uint64_t Address, const void *Decoder)
5611 {
5612 DecodeStatus S = MCDisassembler_Success;
5613 unsigned Vd = (fieldFromInstruction_4(Insn, 12, 4) << 0);
5614 unsigned Vn = (fieldFromInstruction_4(Insn, 16, 4) << 0);
5615 unsigned Vm = (fieldFromInstruction_4(Insn, 0, 4) << 0);
5616 unsigned q = (fieldFromInstruction_4(Insn, 6, 1) << 0);
5617 unsigned rotate = (fieldFromInstruction_4(Insn, 20, 2) << 0);
5618
5619 Vd |= (fieldFromInstruction_4(Insn, 22, 1) << 4);
5620 Vn |= (fieldFromInstruction_4(Insn, 7, 1) << 4);
5621 Vm |= (fieldFromInstruction_4(Insn, 5, 1) << 4);
5622
5623 if (q) {
5624 if (!Check(&S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
5625 return MCDisassembler_Fail;
5626
5627 if (!Check(&S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
5628 return MCDisassembler_Fail;
5629
5630 if (!Check(&S, DecodeQPRRegisterClass(Inst, Vn, Address, Decoder)))
5631 return MCDisassembler_Fail;
5632 } else {
5633 if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
5634 return MCDisassembler_Fail;
5635
5636 if (!Check(&S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
5637 return MCDisassembler_Fail;
5638
5639 if (!Check(&S, DecodeDPRRegisterClass(Inst, Vn, Address, Decoder)))
5640 return MCDisassembler_Fail;
5641 }
5642
5643 if (!Check(&S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
5644 return MCDisassembler_Fail;
5645
5646 // The lane index does not have any bits in the encoding, because it can only
5647 // be 0.
5648 MCOperand_CreateImm0(Inst, 0);
5649 MCOperand_CreateImm0(Inst, rotate);
5650
5651 return S;
5652 }
5653
DecodeLDR(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)5654 static DecodeStatus DecodeLDR(MCInst *Inst, unsigned Val,
5655 uint64_t Address, const void *Decoder)
5656 {
5657 DecodeStatus S = MCDisassembler_Success;
5658 unsigned Cond;
5659 unsigned Rn = fieldFromInstruction_4(Val, 16, 4);
5660 unsigned Rt = fieldFromInstruction_4(Val, 12, 4);
5661 unsigned Rm = fieldFromInstruction_4(Val, 0, 4);
5662
5663 Rm |= (fieldFromInstruction_4(Val, 23, 1) << 4);
5664 Cond = fieldFromInstruction_4(Val, 28, 4);
5665
5666 if (fieldFromInstruction_4(Val, 8, 4) != 0 || Rn == Rt)
5667 S = MCDisassembler_SoftFail;
5668
5669 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5670 return MCDisassembler_Fail;
5671
5672 if (!Check(&S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
5673 return MCDisassembler_Fail;
5674
5675 if (!Check(&S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
5676 return MCDisassembler_Fail;
5677
5678 if (!Check(&S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
5679 return MCDisassembler_Fail;
5680
5681 if (!Check(&S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
5682 return MCDisassembler_Fail;
5683
5684 return S;
5685 }
5686
DecoderForMRRC2AndMCRR2(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)5687 static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst *Inst, unsigned Val,
5688 uint64_t Address, const void *Decoder)
5689 {
5690 DecodeStatus result = MCDisassembler_Success;
5691 unsigned CRm = fieldFromInstruction_4(Val, 0, 4);
5692 unsigned opc1 = fieldFromInstruction_4(Val, 4, 4);
5693 unsigned cop = fieldFromInstruction_4(Val, 8, 4);
5694 unsigned Rt = fieldFromInstruction_4(Val, 12, 4);
5695 unsigned Rt2 = fieldFromInstruction_4(Val, 16, 4);
5696
5697 if ((cop & ~0x1) == 0xa)
5698 return MCDisassembler_Fail;
5699
5700 if (Rt == Rt2)
5701 result = MCDisassembler_SoftFail;
5702
5703 // We have to check if the instruction is MRRC2
5704 // or MCRR2 when constructing the operands for
5705 // Inst. Reason is because MRRC2 stores to two
5706 // registers so it's tablegen desc has has two
5707 // outputs whereas MCRR doesn't store to any
5708 // registers so all of it's operands are listed
5709 // as inputs, therefore the operand order for
5710 // MRRC2 needs to be [Rt, Rt2, cop, opc1, CRm]
5711 // and MCRR2 operand order is [cop, opc1, Rt, Rt2, CRm]
5712
5713 if (MCInst_getOpcode(Inst) == ARM_MRRC2) {
5714 if (!Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5715 return MCDisassembler_Fail;
5716
5717 if (!Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5718 return MCDisassembler_Fail;
5719 }
5720
5721 MCOperand_CreateImm0(Inst, cop);
5722 MCOperand_CreateImm0(Inst, opc1);
5723
5724 if (MCInst_getOpcode(Inst) == ARM_MCRR2) {
5725 if (!Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5726 return MCDisassembler_Fail;
5727
5728 if (!Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5729 return MCDisassembler_Fail;
5730 }
5731
5732 MCOperand_CreateImm0(Inst, CRm);
5733
5734 return result;
5735 }
5736
DecodeForVMRSandVMSR(MCInst * Inst,unsigned Val,uint64_t Address,const void * Decoder)5737 static DecodeStatus DecodeForVMRSandVMSR(MCInst *Inst, unsigned Val,
5738 uint64_t Address, const void *Decoder)
5739 {
5740 DecodeStatus result = MCDisassembler_Success;
5741 bool HasV8Ops = ARM_getFeatureBits(Inst->csh->mode, ARM_HasV8Ops);
5742 unsigned Rt = fieldFromInstruction_4(Val, 12, 4);
5743
5744 if ((Inst->csh->mode & CS_MODE_THUMB) && !HasV8Ops) {
5745 if (Rt == 13 || Rt == 15)
5746 result = MCDisassembler_SoftFail;
5747
5748 Check(&result, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder));
5749 } else
5750 Check(&result, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder));
5751
5752 if (Inst->csh->mode & CS_MODE_THUMB) {
5753 MCOperand_CreateImm0(Inst, ARMCC_AL);
5754 MCOperand_CreateReg0(Inst, 0);
5755 } else {
5756 unsigned pred = fieldFromInstruction_4(Val, 28, 4);
5757 if (!Check(&result, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5758 return MCDisassembler_Fail;
5759 }
5760
5761 return result;
5762 }
5763
5764 #endif
5765