blob: 438693e2fa366d01680ca972ff20e5eb1fe78664 [file] [log] [blame]
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001//===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
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// This class prints an ARM MCInst to a .s file.
11//
12//===----------------------------------------------------------------------===//
13
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +080014/* Capstone Disassembly Engine */
Nguyen Anh Quynhbfcaba52015-03-04 17:45:23 +080015/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +080016
17#ifdef CAPSTONE_HAS_ARM
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080018
19#include <stdio.h> // DEBUG
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080020#include <stdlib.h>
21#include <string.h>
Cr4sh19ee2d12015-03-29 18:29:06 +080022#include "../../myinttypes.h"
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080023
24#include "ARMInstPrinter.h"
25#include "ARMAddressingModes.h"
26#include "ARMBaseInfo.h"
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +080027#include "ARMDisassembler.h"
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080028#include "../../MCInst.h"
29#include "../../SStream.h"
30#include "../../MCRegisterInfo.h"
31#include "../../utils.h"
Nguyen Anh Quynh37327252014-01-20 09:47:21 +080032#include "ARMMapping.h"
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080033
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +080034#define GET_SUBTARGETINFO_ENUM
35#include "ARMGenSubtargetInfo.inc"
36
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +080037static void printRegName(cs_struct *h, SStream *OS, unsigned RegNo);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080038
39// Autogenerated by tblgen.
40static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI);
41static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
42static void printSORegRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
43static void printSORegImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
44
45static void printAddrModeTBB(MCInst *MI, unsigned OpNum, SStream *O);
46static void printAddrModeTBH(MCInst *MI, unsigned OpNum, SStream *O);
47static void printAddrMode2Operand(MCInst *MI, unsigned OpNum, SStream *O);
48static void printAM2PreOrOffsetIndexOp(MCInst *MI, unsigned OpNum, SStream *O);
49static void printAddrMode2OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
50static void printAddrMode3Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
51static void printAddrMode3OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080052static void printAM3PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O, bool AlwaysPrintImm0);
53static void printPostIdxImm8Operand(MCInst *MI, unsigned OpNum, SStream *O);
54static void printPostIdxRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
55static void printPostIdxImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O);
56static void printAddrMode5Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
57static void printAddrMode6Operand(MCInst *MI, unsigned OpNum, SStream *O);
58static void printAddrMode7Operand(MCInst *MI, unsigned OpNum, SStream *O);
59static void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
60
61static void printBitfieldInvMaskImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
62static void printMemBOption(MCInst *MI, unsigned OpNum, SStream *O);
63static void printShiftImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
64static void printPKHLSLShiftImm(MCInst *MI, unsigned OpNum, SStream *O);
65static void printPKHASRShiftImm(MCInst *MI, unsigned OpNum, SStream *O);
66static void printAdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned);
67static void printThumbS4ImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
68static void printThumbSRImm(MCInst *MI, unsigned OpNum, SStream *O);
69static void printThumbITMask(MCInst *MI, unsigned OpNum, SStream *O);
70static void printThumbAddrModeRROperand(MCInst *MI, unsigned OpNum, SStream *O);
71static void printThumbAddrModeImm5SOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned Scale);
72static void printThumbAddrModeImm5S1Operand(MCInst *MI, unsigned OpNum, SStream *O);
73static void printThumbAddrModeImm5S2Operand(MCInst *MI, unsigned OpNum, SStream *O);
74static void printThumbAddrModeImm5S4Operand(MCInst *MI, unsigned OpNum, SStream *O);
75static void printThumbAddrModeSPOperand(MCInst *MI, unsigned OpNum, SStream *O);
76static void printT2SOOperand(MCInst *MI, unsigned OpNum, SStream *O);
77static void printAddrModeImm12Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
78static void printT2AddrModeImm8Operand(MCInst *MI, unsigned OpNum, SStream *O, bool);
79static void printT2AddrModeImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O, bool);
80static void printT2AddrModeImm0_1020s4Operand(MCInst *MI, unsigned OpNum, SStream *O);
81static void printT2AddrModeImm8OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
82static void printT2AddrModeImm8s4OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
83static void printT2AddrModeSoRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
84static void printSetendOperand(MCInst *MI, unsigned OpNum, SStream *O);
85static void printCPSIMod(MCInst *MI, unsigned OpNum, SStream *O);
86static void printCPSIFlag(MCInst *MI, unsigned OpNum, SStream *O);
87static void printMSRMaskOperand(MCInst *MI, unsigned OpNum, SStream *O);
88static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O);
89static void printMandatoryPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O);
90static void printSBitModifierOperand(MCInst *MI, unsigned OpNum, SStream *O);
91static void printRegisterList(MCInst *MI, unsigned OpNum, SStream *O);
92static void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O);
93static void printPImmediate(MCInst *MI, unsigned OpNum, SStream *O);
94static void printCImmediate(MCInst *MI, unsigned OpNum, SStream *O);
95static void printCoprocOptionImm(MCInst *MI, unsigned OpNum, SStream *O);
96static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
97static void printNEONModImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
98static void printImmPlusOneOperand(MCInst *MI, unsigned OpNum, SStream *O);
99static void printRotImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
100static void printGPRPairOperand(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *MRI);
101static void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O);
102static void printFBits16(MCInst *MI, unsigned OpNum, SStream *O);
103static void printFBits32(MCInst *MI, unsigned OpNum, SStream *O);
104static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O);
105static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O);
106static void printVectorListTwo(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *MRI);
107static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *RI);
108static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O);
109static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O);
110static void printVectorListOneAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
111static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *RI);
112static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
113static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
114static void printVectorListTwoSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *MRI);
115static void printVectorListThreeSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
116static void printVectorListFourSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
117static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O);
118static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O);
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +0800119static void printBankedRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
120static void printModImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800121
122static void printInstSyncBOption(MCInst *MI, unsigned OpNum, SStream *O);
123
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800124// copy & normalize access info
125static uint8_t get_op_access(cs_struct *h, unsigned int id, unsigned int index)
126{
127#ifndef CAPSTONE_DIET
128 uint8_t *arr = ARM_get_op_access(h, id);
129
130 if (arr[index] == CS_AC_IGNORE)
131 return 0;
132
133 return arr[index];
134#else
135 return 0;
136#endif
137}
138
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800139static void set_mem_access(MCInst *MI, bool status)
140{
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800141 if (MI->csh->detail != CS_OPT_ON)
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800142 return;
143
Nguyen Anh Quynh19b0de32013-12-31 22:40:04 +0800144 MI->csh->doing_mem = status;
145 if (status) {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800146#ifndef CAPSTONE_DIET
147 uint8_t access;
148#endif
149
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700150 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
151 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = ARM_REG_INVALID;
152 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
153 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
154 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800155
156#ifndef CAPSTONE_DIET
157 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
158 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
159 MI->ac_idx++;
160#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800161 } else {
162 // done, create the next operand slot
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700163 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800164 }
165}
166
Nguyen Anh Quynhebe24432014-06-17 13:56:01 +0800167static void op_addImm(MCInst *MI, int v)
168{
Nguyen Anh Quynh73eb5d52014-06-17 18:08:29 +0800169 if (MI->csh->detail) {
170 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
171 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = v;
172 MI->flat_insn->detail->arm.op_count++;
173 }
Nguyen Anh Quynhebe24432014-06-17 13:56:01 +0800174}
175
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800176#define GET_INSTRINFO_ENUM
177#include "ARMGenInstrInfo.inc"
178
179//#define PRINT_ALIAS_INSTR
180#include "ARMGenAsmWriter.inc"
181
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800182void ARM_getRegName(cs_struct *handle, int value)
183{
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800184 if (value == CS_OPT_SYNTAX_NOREGNAME) {
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800185 handle->get_regname = getRegisterName2;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800186 handle->reg_name = ARM_reg_name2;;
187 } else {
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800188 handle->get_regname = getRegisterName;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800189 handle->reg_name = ARM_reg_name;;
190 }
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800191}
192
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800193/// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
194///
195/// getSORegOffset returns an integer from 0-31, representing '32' as 0.
196static unsigned translateShiftImm(unsigned imm)
197{
198 // lsr #32 and asr #32 exist, but should be encoded as a 0.
199 //assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
200 if (imm == 0)
201 return 32;
202 return imm;
203}
204
205/// Prints the shift value with an immediate value.
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +0700206static void printRegImmShift(MCInst *MI, SStream *O, ARM_AM_ShiftOpc ShOpc, unsigned ShImm)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800207{
208 if (ShOpc == ARM_AM_no_shift || (ShOpc == ARM_AM_lsl && !ShImm))
209 return;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700210 SStream_concat0(O, ", ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800211
212 //assert (!(ShOpc == ARM_AM_ror && !ShImm) && "Cannot have ror #0");
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700213 SStream_concat0(O, ARM_AM_getShiftOpcStr(ShOpc));
Nguyen Anh Quynhc70442e2014-06-01 11:35:34 +0700214 if (MI->csh->detail) {
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800215 if (MI->csh->doing_mem)
216 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (arm_shifter)ShOpc;
217 else
218 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = (arm_shifter)ShOpc;
Nguyen Anh Quynhc70442e2014-06-01 11:35:34 +0700219 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800220
221 if (ShOpc != ARM_AM_rrx) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700222 SStream_concat0(O, " ");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800223 SStream_concat(O, "#%u", translateShiftImm(ShImm));
Nguyen Anh Quynhc70442e2014-06-01 11:35:34 +0700224 if (MI->csh->detail) {
225 if (MI->csh->doing_mem)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700226 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = translateShiftImm(ShImm);
Nguyen Anh Quynhc70442e2014-06-01 11:35:34 +0700227 else
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700228 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = translateShiftImm(ShImm);
Nguyen Anh Quynhc70442e2014-06-01 11:35:34 +0700229 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800230 }
231}
232
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800233static void printRegName(cs_struct *h, SStream *OS, unsigned RegNo)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800234{
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800235#ifndef CAPSTONE_DIET
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700236 SStream_concat0(OS, h->get_regname(RegNo));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800237#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800238}
239
240static name_map insn_update_flgs[] = {
241 { ARM_INS_CMN, "cmn" },
242 { ARM_INS_CMP, "cmp" },
243 { ARM_INS_TEQ, "teq" },
244 { ARM_INS_TST, "tst" },
245
246 { ARM_INS_ADC, "adcs" },
247 { ARM_INS_ADD, "adds" },
248 { ARM_INS_AND, "ands" },
249 { ARM_INS_ASR, "asrs" },
250 { ARM_INS_BIC, "bics" },
251 { ARM_INS_EOR, "eors" },
252 { ARM_INS_LSL, "lsls" },
253 { ARM_INS_LSR, "lsrs" },
254 { ARM_INS_MLA, "mlas" },
255 { ARM_INS_MOV, "movs" },
256 { ARM_INS_MUL, "muls" },
257 { ARM_INS_MVN, "mvns" },
258 { ARM_INS_ORN, "orns" },
259 { ARM_INS_ORR, "orrs" },
260 { ARM_INS_ROR, "rors" },
261 { ARM_INS_RRX, "rrxs" },
262 { ARM_INS_RSB, "rsbs" },
263 { ARM_INS_RSC, "rscs" },
264 { ARM_INS_SBC, "sbcs" },
265 { ARM_INS_SMLAL, "smlals" },
266 { ARM_INS_SMULL, "smulls" },
267 { ARM_INS_SUB, "subs" },
268 { ARM_INS_UMLAL, "umlals" },
269 { ARM_INS_UMULL, "umulls" },
270};
271
Nguyen Anh Quynh64564812014-05-19 16:46:31 +0800272void ARM_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800273{
Nguyen Anh Quynh5ef633c2014-01-04 10:41:17 +0800274 if (((cs_struct *)ud)->detail != CS_OPT_ON)
275 return;
276
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800277 // check if this insn requests write-back
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800278 if (mci->writeback || (strrchr(insn_asm, '!')) != NULL) {
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800279 insn->detail->arm.writeback = true;
Nguyen Anh Quynh5719eb52015-01-21 12:16:15 +0800280 } else if (mci->csh->mode & CS_MODE_THUMB) {
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800281 // handle some special instructions with writeback
282 switch(mci->Opcode) {
283 default:
284 break;
285 case ARM_t2LDC2L_PRE:
286 case ARM_t2LDC2_PRE:
287 case ARM_t2LDCL_PRE:
288 case ARM_t2LDC_PRE:
289
290 case ARM_t2LDRB_PRE:
291 case ARM_t2LDRD_PRE:
292 case ARM_t2LDRH_PRE:
293 case ARM_t2LDRSB_PRE:
294 case ARM_t2LDRSH_PRE:
295 case ARM_t2LDR_PRE:
296
297 case ARM_t2STC2L_PRE:
298 case ARM_t2STC2_PRE:
299 case ARM_t2STCL_PRE:
300 case ARM_t2STC_PRE:
301
302 case ARM_t2STRB_PRE:
303 case ARM_t2STRD_PRE:
304 case ARM_t2STRH_PRE:
305 case ARM_t2STR_PRE:
306
307 case ARM_t2LDC2L_POST:
308 case ARM_t2LDC2_POST:
309 case ARM_t2LDCL_POST:
310 case ARM_t2LDC_POST:
311
312 case ARM_t2LDRB_POST:
313 case ARM_t2LDRD_POST:
314 case ARM_t2LDRH_POST:
315 case ARM_t2LDRSB_POST:
316 case ARM_t2LDRSH_POST:
317 case ARM_t2LDR_POST:
318
319 case ARM_t2STC2L_POST:
320 case ARM_t2STC2_POST:
321 case ARM_t2STCL_POST:
322 case ARM_t2STC_POST:
323
324 case ARM_t2STRB_POST:
325 case ARM_t2STRD_POST:
326 case ARM_t2STRH_POST:
327 case ARM_t2STR_POST:
328 insn->detail->arm.writeback = true;
329 break;
330 }
331 } else { // ARM mode
332 // handle some special instructions with writeback
333 switch(mci->Opcode) {
334 default:
335 break;
336 case ARM_LDC2L_PRE:
337 case ARM_LDC2_PRE:
338 case ARM_LDCL_PRE:
339 case ARM_LDC_PRE:
340
341 case ARM_LDRD_PRE:
342 case ARM_LDRH_PRE:
343 case ARM_LDRSB_PRE:
344 case ARM_LDRSH_PRE:
345
346 case ARM_STC2L_PRE:
347 case ARM_STC2_PRE:
348 case ARM_STCL_PRE:
349 case ARM_STC_PRE:
350
351 case ARM_STRD_PRE:
352 case ARM_STRH_PRE:
353
354 case ARM_LDC2L_POST:
355 case ARM_LDC2_POST:
356 case ARM_LDCL_POST:
357 case ARM_LDC_POST:
358
359 case ARM_LDRBT_POST:
360 case ARM_LDRD_POST:
361 case ARM_LDRH_POST:
362 case ARM_LDRSB_POST:
363 case ARM_LDRSH_POST:
364
365 case ARM_STC2L_POST:
366 case ARM_STC2_POST:
367 case ARM_STCL_POST:
368 case ARM_STC_POST:
369
370 case ARM_STRBT_POST:
371 case ARM_STRD_POST:
372 case ARM_STRH_POST:
Nguyen Anh Quynh58fbf2f2015-01-21 12:25:36 +0800373
374 case ARM_LDRB_POST_IMM:
375 case ARM_LDR_POST_IMM:
376 case ARM_STRB_POST_IMM:
377 case ARM_STR_POST_IMM:
378
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800379 insn->detail->arm.writeback = true;
380 break;
381 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800382 }
383
384 // check if this insn requests update flags
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800385 if (insn->detail->arm.update_flags == false) {
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800386 // some insn still update flags, regardless of tabgen info
Nguyen Anh Quynhf6c7cbc2014-03-12 12:50:54 +0800387 unsigned int i, j;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800388
389 for (i = 0; i < ARR_SIZE(insn_update_flgs); i++) {
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800390 if (insn->id == insn_update_flgs[i].id &&
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800391 !strncmp(insn_asm, insn_update_flgs[i].name,
392 strlen(insn_update_flgs[i].name))) {
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800393 insn->detail->arm.update_flags = true;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800394 // we have to update regs_write array as well
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800395 for (j = 0; j < ARR_SIZE(insn->detail->regs_write); j++) {
396 if (insn->detail->regs_write[j] == 0) {
397 insn->detail->regs_write[j] = ARM_REG_CPSR;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800398 break;
399 }
400 }
401 break;
402 }
403 }
404 }
Nguyen Anh Quynh48b6cb42014-06-01 09:45:19 +0700405
406 // instruction should not have invalid CC
407 if (insn->detail->arm.cc == ARM_CC_INVALID) {
408 insn->detail->arm.cc = ARM_CC_AL;
409 }
410
Nguyen Anh Quynh6eb55cf2014-06-01 10:03:14 +0700411 // manual fix for some special instructions
412 // printf(">>> id: %u, mcid: %u\n", insn->id, mci->Opcode);
413 switch(mci->Opcode) {
414 default:
415 break;
416 case ARM_MOVPCLR:
417 insn->detail->arm.operands[0].type = ARM_OP_REG;
418 insn->detail->arm.operands[0].reg = ARM_REG_PC;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800419 insn->detail->arm.operands[0].access = CS_AC_READ;
Nguyen Anh Quynh6eb55cf2014-06-01 10:03:14 +0700420 insn->detail->arm.operands[1].type = ARM_OP_REG;
421 insn->detail->arm.operands[1].reg = ARM_REG_LR;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800422 insn->detail->arm.operands[1].access = CS_AC_WRITE;
Nguyen Anh Quynh6eb55cf2014-06-01 10:03:14 +0700423 insn->detail->arm.op_count = 2;
424 break;
425 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800426}
427
428void ARM_printInst(MCInst *MI, SStream *O, void *Info)
429{
430 MCRegisterInfo *MRI = (MCRegisterInfo *)Info;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800431 unsigned Opcode = MCInst_getOpcode(MI), tmp, i, pubOpcode;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800432
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800433
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800434 switch(Opcode) {
435 // Check for HINT instructions w/ canonical names.
436 case ARM_HINT:
437 case ARM_tHINT:
438 case ARM_t2HINT:
439 switch (MCOperand_getImm(MCInst_getOperand(MI, 0))) {
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800440 case 0: SStream_concat0(O, "nop"); pubOpcode = ARM_INS_NOP; break;
441 case 1: SStream_concat0(O, "yield"); pubOpcode = ARM_INS_YIELD; break;
442 case 2: SStream_concat0(O, "wfe"); pubOpcode = ARM_INS_WFE; break;
443 case 3: SStream_concat0(O, "wfi"); pubOpcode = ARM_INS_WFI; break;
444 case 4: SStream_concat0(O, "sev"); pubOpcode = ARM_INS_SEV; break;
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800445 case 5:
Nguyen Anh Quynh2593e222014-11-10 16:35:38 +0800446 if ((ARM_getFeatureBits(MI->csh->mode) & ARM_HasV8Ops)) {
447 SStream_concat0(O, "sevl");
448 pubOpcode = ARM_INS_SEVL;
449 break;
450 }
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800451 // Fallthrough for non-v8
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800452 default:
453 // Anything else should just print normally.
454 printInstruction(MI, O, MRI);
455 return;
456 }
457 printPredicateOperand(MI, 1, O);
458 if (Opcode == ARM_t2HINT)
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800459 SStream_concat0(O, ".w");
460
461 MCInst_setOpcodePub(MI, pubOpcode);
462
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800463 return;
464
465 // Check for MOVs and print canonical forms, instead.
466 case ARM_MOVsr: {
467 // FIXME: Thumb variants?
468 MCOperand *Dst = MCInst_getOperand(MI, 0);
469 MCOperand *MO1 = MCInst_getOperand(MI, 1);
470 MCOperand *MO2 = MCInst_getOperand(MI, 2);
471 MCOperand *MO3 = MCInst_getOperand(MI, 3);
472
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700473 SStream_concat0(O, ARM_AM_getShiftOpcStr(ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO3))));
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800474 printSBitModifierOperand(MI, 6, O);
475 printPredicateOperand(MI, 4, O);
476
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700477 SStream_concat0(O, "\t");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800478 printRegName(MI->csh, O, MCOperand_getReg(Dst));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800479 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700480 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
481 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(Dst);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800482 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_WRITE;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700483 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800484 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800485
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700486 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800487 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800488
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800489 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700490 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
491 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800492 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700493 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800494 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800495
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700496 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800497 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800498 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700499 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
500 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO2);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800501 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700502 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800503 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800504 //assert(ARM_AM_getSORegOffset(MO3.getImm()) == 0);
505 return;
506 }
507
508 case ARM_MOVsi: {
509 // FIXME: Thumb variants?
510 MCOperand *Dst = MCInst_getOperand(MI, 0);
511 MCOperand *MO1 = MCInst_getOperand(MI, 1);
512 MCOperand *MO2 = MCInst_getOperand(MI, 2);
513
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700514 SStream_concat0(O, ARM_AM_getShiftOpcStr(ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2))));
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800515 printSBitModifierOperand(MI, 5, O);
516 printPredicateOperand(MI, 3, O);
517
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700518 SStream_concat0(O, "\t");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800519 printRegName(MI->csh, O, MCOperand_getReg(Dst));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800520 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700521 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
522 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(Dst);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800523 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_WRITE;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700524 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800525 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800526
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700527 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800528 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800529 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700530 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
531 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800532 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700533 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800534 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800535
Alex Ionescu46018db2014-01-22 09:45:00 -0800536 if (ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2)) == ARM_AM_rrx) {
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800537 //printAnnotation(O, Annot);
538 return;
539 }
540
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700541 SStream_concat0(O, ", ");
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100542 tmp = translateShiftImm(getSORegOffset((unsigned int)MCOperand_getImm(MO2)));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800543 if (tmp > HEX_THRESHOLD)
544 SStream_concat(O, "#0x%x", tmp);
545 else
546 SStream_concat(O, "#%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800547 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700548 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type =
Alex Ionescu46018db2014-01-22 09:45:00 -0800549 (arm_shifter)ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700550 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = tmp;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800551 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800552 return;
553 }
554
555 // A8.6.123 PUSH
556 case ARM_STMDB_UPD:
557 case ARM_t2STMDB_UPD:
558 if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP &&
559 MCInst_getNumOperands(MI) > 5) {
560 // Should only print PUSH if there are at least two registers in the list.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700561 SStream_concat0(O, "push");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800562 MCInst_setOpcodePub(MI, ARM_INS_PUSH);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800563 printPredicateOperand(MI, 2, O);
564 if (Opcode == ARM_t2STMDB_UPD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700565 SStream_concat0(O, ".w");
566 SStream_concat0(O, "\t");
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800567 printRegisterList(MI, 4, O);
568 return;
569 }
570 break;
571
572 case ARM_STR_PRE_IMM:
573 if (MCOperand_getReg(MCInst_getOperand(MI, 2)) == ARM_SP &&
574 MCOperand_getImm(MCInst_getOperand(MI, 3)) == -4) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700575 SStream_concat0(O, "push");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800576 MCInst_setOpcodePub(MI, ARM_INS_PUSH);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800577 printPredicateOperand(MI, 4, O);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700578 SStream_concat0(O, "\t{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800579 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 1)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800580 if (MI->csh->detail) {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800581#ifndef CAPSTONE_DIET
582 uint8_t access;
583#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700584 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
585 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 1));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800586#ifndef CAPSTONE_DIET
587 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
588 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
589 MI->ac_idx++;
590#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700591 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800592 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700593 SStream_concat0(O, "}");
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800594 return;
595 }
596 break;
597
598 // A8.6.122 POP
599 case ARM_LDMIA_UPD:
600 case ARM_t2LDMIA_UPD:
601 if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP &&
602 MCInst_getNumOperands(MI) > 5) {
603 // Should only print POP if there are at least two registers in the list.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700604 SStream_concat0(O, "pop");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800605 MCInst_setOpcodePub(MI, ARM_INS_POP);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800606 printPredicateOperand(MI, 2, O);
607 if (Opcode == ARM_t2LDMIA_UPD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700608 SStream_concat0(O, ".w");
609 SStream_concat0(O, "\t");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800610 if (MI->csh->detail) {
611 MI->flat_insn->detail->regs_read[MI->flat_insn->detail->regs_read_count] = ARM_REG_SP;
612 MI->flat_insn->detail->regs_read_count++;
613 MI->flat_insn->detail->regs_write[MI->flat_insn->detail->regs_write_count] = ARM_REG_SP;
614 MI->flat_insn->detail->regs_write_count++;
615 }
616
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800617 printRegisterList(MI, 4, O);
618 return;
619 }
620 break;
621
622 case ARM_LDR_POST_IMM:
Nguyen Anh Quynh3caf8372014-11-27 14:34:40 +0800623 if (MCOperand_getReg(MCInst_getOperand(MI, 2)) == ARM_SP) {
624 MCOperand *MO2 = MCInst_getOperand(MI, 4);
625 if ((getAM2Op((unsigned int)MCOperand_getImm(MO2)) == ARM_AM_add &&
626 getAM2Offset((unsigned int)MCOperand_getImm(MO2)) == 4) ||
627 MCOperand_getImm(MO2) == 4) {
628 SStream_concat0(O, "pop");
629 MCInst_setOpcodePub(MI, ARM_INS_POP);
630 printPredicateOperand(MI, 5, O);
631 SStream_concat0(O, "\t{");
632 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 0)));
633 if (MI->csh->detail) {
634 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
635 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800636 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh3caf8372014-11-27 14:34:40 +0800637 MI->flat_insn->detail->arm.op_count++;
638 }
639 SStream_concat0(O, "}");
640 return;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800641 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800642 }
643 break;
644
645 // A8.6.355 VPUSH
646 case ARM_VSTMSDB_UPD:
647 case ARM_VSTMDDB_UPD:
648 if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700649 SStream_concat0(O, "vpush");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800650 MCInst_setOpcodePub(MI, ARM_INS_VPUSH);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800651 printPredicateOperand(MI, 2, O);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700652 SStream_concat0(O, "\t");
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800653 printRegisterList(MI, 4, O);
654 return;
655 }
656 break;
657
658 // A8.6.354 VPOP
659 case ARM_VLDMSIA_UPD:
660 case ARM_VLDMDIA_UPD:
661 if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700662 SStream_concat0(O, "vpop");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800663 MCInst_setOpcodePub(MI, ARM_INS_VPOP);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800664 printPredicateOperand(MI, 2, O);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700665 SStream_concat0(O, "\t");
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800666 printRegisterList(MI, 4, O);
667 return;
668 }
669 break;
670
671 case ARM_tLDMIA: {
Nguyen Anh Quynh8cdafda2014-11-11 22:30:30 +0800672 bool Writeback = true;
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800673 unsigned BaseReg = MCOperand_getReg(MCInst_getOperand(MI, 0));
674 unsigned i;
675 for (i = 3; i < MCInst_getNumOperands(MI); ++i) {
676 if (MCOperand_getReg(MCInst_getOperand(MI, i)) == BaseReg)
677 Writeback = false;
678 }
679
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700680 SStream_concat0(O, "ldm");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800681 MCInst_setOpcodePub(MI, ARM_INS_LDM);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800682
683 printPredicateOperand(MI, 1, O);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700684 SStream_concat0(O, "\t");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800685 printRegName(MI->csh, O, BaseReg);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800686 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700687 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
688 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = BaseReg;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800689 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700690 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800691 }
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800692 if (Writeback) {
693 MI->writeback = true;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700694 SStream_concat0(O, "!");
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800695 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700696 SStream_concat0(O, ", ");
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800697 printRegisterList(MI, 3, O);
698 return;
699 }
700
701 // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
702 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
703 // a single GPRPair reg operand is used in the .td file to replace the two
704 // GPRs. However, when decoding them, the two GRPs cannot be automatically
705 // expressed as a GPRPair, so we have to manually merge them.
706 // FIXME: We would really like to be able to tablegen'erate this.
707 case ARM_LDREXD:
708 case ARM_STREXD:
709 case ARM_LDAEXD:
710 case ARM_STLEXD: {
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800711 MCRegisterClass* MRC = MCRegisterInfo_getRegClass(MRI, ARM_GPRRegClassID);
712 bool isStore = Opcode == ARM_STREXD || Opcode == ARM_STLEXD;
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800713 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, isStore ? 1 : 0));
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +0800714
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800715 if (MCRegisterClass_contains(MRC, Reg)) {
716 MCInst NewMI;
Nguyen Anh Quynh5e2e6602014-05-30 17:43:36 +0800717
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800718 MCInst_Init(&NewMI);
719 MCInst_setOpcode(&NewMI, Opcode);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800720
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800721 if (isStore)
722 MCInst_addOperand2(&NewMI, MCInst_getOperand(MI, 0));
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800723
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800724 MCOperand_CreateReg0(&NewMI, MCRegisterInfo_getMatchingSuperReg(MRI, Reg, ARM_gsub_0,
725 MCRegisterInfo_getRegClass(MRI, ARM_GPRPairRegClassID)));
Nguyen Anh Quynh96787052014-06-10 13:59:55 +0700726
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800727 // Copy the rest operands into NewMI.
728 for(i = isStore ? 3 : 2; i < MCInst_getNumOperands(MI); ++i)
729 MCInst_addOperand2(&NewMI, MCInst_getOperand(MI, i));
Nguyen Anh Quynh96787052014-06-10 13:59:55 +0700730
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800731 printInstruction(&NewMI, O, MRI);
732 return;
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800733 }
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +0800734 break;
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800735 }
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +0800736 // B9.3.3 ERET (Thumb)
737 // For a target that has Virtualization Extensions, ERET is the preferred
738 // disassembly of SUBS PC, LR, #0
739 case ARM_t2SUBS_PC_LR: {
740 MCOperand *opc = MCInst_getOperand(MI, 0);
741 if (MCInst_getNumOperands(MI) == 3 &&
742 MCOperand_isImm(opc) &&
743 MCOperand_getImm(opc) == 0 &&
744 (ARM_getFeatureBits(MI->csh->mode) & ARM_FeatureVirtualization)) {
745 SStream_concat0(O, "eret");
746 MCInst_setOpcodePub(MI, ARM_INS_ERET);
747 printPredicateOperand(MI, 1, O);
748 return;
749 }
750 break;
751 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800752 }
753
754 //if (printAliasInstr(MI, O, MRI))
755 // printInstruction(MI, O, MRI);
756 printInstruction(MI, O, MRI);
757}
758
759static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
760{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800761 int32_t imm;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800762 MCOperand *Op = MCInst_getOperand(MI, OpNo);
763 if (MCOperand_isReg(Op)) {
764 unsigned Reg = MCOperand_getReg(Op);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800765 printRegName(MI->csh, O, Reg);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800766 if (MI->csh->detail) {
Nguyen Anh Quynh19b0de32013-12-31 22:40:04 +0800767 if (MI->csh->doing_mem) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700768 if (MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base == ARM_REG_INVALID)
769 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = Reg;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800770 else
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700771 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = Reg;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800772 } else {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800773#ifndef CAPSTONE_DIET
774 uint8_t access;
775#endif
776
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700777 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
778 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800779#ifndef CAPSTONE_DIET
780 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
781 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
782 MI->ac_idx++;
783#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700784 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800785 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800786 }
787 } else if (MCOperand_isImm(Op)) {
Nguyen Anh Quynh0c235e12014-07-31 21:16:54 +0800788 unsigned int opc = MCInst_getOpcode(MI);
flyingsymbols298d4132014-06-30 01:45:40 -0400789
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100790 imm = (int32_t)MCOperand_getImm(Op);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800791
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800792 // relative branch only has relative offset, so we have to update it
793 // to reflect absolute address.
794 // Note: in ARM, PC is always 2 instructions ahead, so we have to
795 // add 8 in ARM mode, or 4 in Thumb mode
Nguyen Anh Quynhbc80b3d2014-05-09 17:31:41 +0800796 // printf(">> opcode: %u\n", MCInst_getOpcode(MI));
flyingsymbols298d4132014-06-30 01:45:40 -0400797 if (ARM_rel_branch(MI->csh, opc)) {
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800798 // only do this for relative branch
flyingsymbols298d4132014-06-30 01:45:40 -0400799 if (MI->csh->mode & CS_MODE_THUMB) {
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800800 imm += (int32_t)MI->address + 4;
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800801 if (ARM_blx_to_arm_mode(MI->csh, opc)) {
Nguyen Anh Quynh0c235e12014-07-31 21:16:54 +0800802 // here need to align down to the nearest 4-byte address
flyingsymbols298d4132014-06-30 01:45:40 -0400803#define _ALIGN_DOWN(v, align_width) ((v/align_width)*align_width)
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800804 imm = _ALIGN_DOWN(imm, 4);
flyingsymbols298d4132014-06-30 01:45:40 -0400805#undef _ALIGN_DOWN
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800806 }
807 } else {
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800808 imm += (int32_t)MI->address + 8;
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800809 }
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800810
811 if (imm >= 0) {
812 if (imm > HEX_THRESHOLD)
813 SStream_concat(O, "#0x%x", imm);
814 else
815 SStream_concat(O, "#%u", imm);
816 } else {
Nguyen Anh Quynh4e876752014-09-23 16:49:12 +0800817 SStream_concat(O, "#0x%x", imm);
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800818 }
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +0800819 } else {
Nguyen Anh Quynh278e7272014-11-11 12:50:43 +0800820 switch(MI->flat_insn->id) {
821 default:
822 if (imm >= 0) {
823 if (imm > HEX_THRESHOLD)
824 SStream_concat(O, "#0x%x", imm);
825 else
826 SStream_concat(O, "#%u", imm);
827 } else {
828 if (imm < -HEX_THRESHOLD)
829 SStream_concat(O, "#-0x%x", -imm);
830 else
831 SStream_concat(O, "#-%u", -imm);
832 }
833 break;
834 case ARM_INS_AND:
835 case ARM_INS_ORR:
836 case ARM_INS_EOR:
837 case ARM_INS_BIC:
Nguyen Anh Quynha2934a72014-11-25 21:02:18 +0800838 case ARM_INS_MVN:
Nguyen Anh Quynh278e7272014-11-11 12:50:43 +0800839 // do not print number in negative form
840 if (imm >= 0 && imm <= HEX_THRESHOLD)
841 SStream_concat(O, "#%u", imm);
842 else
843 SStream_concat(O, "#0x%x", imm);
844 break;
845 }
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +0800846 }
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800847
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800848 if (MI->csh->detail) {
Nguyen Anh Quynh19b0de32013-12-31 22:40:04 +0800849 if (MI->csh->doing_mem)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700850 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = imm;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800851 else {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700852 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
853 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
854 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800855 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800856 }
857 }
858}
859
860static void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O)
861{
862 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800863 int32_t OffImm;
Nguyen Anh Quynh42706a32014-05-09 07:33:35 +0800864 bool isSub;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700865 SStream_concat0(O, "[pc, ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800866
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100867 OffImm = (int32_t)MCOperand_getImm(MO1);
868 isSub = OffImm < 0;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800869
870 // Special value for #-0. All others are normal.
871 if (OffImm == INT32_MIN)
872 OffImm = 0;
873 if (isSub) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700874 SStream_concat(O, "#-0x%x", -OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800875 } else {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800876 if (OffImm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700877 SStream_concat(O, "#0x%x", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800878 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700879 SStream_concat(O, "#%u", OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800880 }
881
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700882 SStream_concat0(O, "]");
Nguyen Anh Quynhbb71c132014-06-01 10:14:31 +0700883
884 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700885 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
886 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = ARM_REG_PC;
887 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
888 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
889 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800890 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700891 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynhbb71c132014-06-01 10:14:31 +0700892 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800893}
894
895// so_reg is a 4-operand unit corresponding to register forms of the A5.1
896// "Addressing Mode 1 - Data-processing operands" forms. This includes:
897// REG 0 0 - e.g. R5
898// REG REG 0,SH_OPC - e.g. R5, ROR R3
899// REG 0 IMM,SH_OPC - e.g. R5, LSL #3
900static void printSORegRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
901{
902 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
903 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
904 MCOperand *MO3 = MCInst_getOperand(MI, OpNum+2);
Nguyen Anh Quynh42706a32014-05-09 07:33:35 +0800905 ARM_AM_ShiftOpc ShOpc;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800906
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800907 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800908
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800909 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700910 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
911 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800912 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800913
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700914 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (MCOperand_getImm(MO3) & 7) + ARM_SFT_ASR_REG - 1;
915 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800916 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800917
918 // Print the shift opc.
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100919 ShOpc = ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700920 SStream_concat0(O, ", ");
921 SStream_concat0(O, ARM_AM_getShiftOpcStr(ShOpc));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800922 if (ShOpc == ARM_AM_rrx)
923 return;
924
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700925 SStream_concat0(O, " ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800926 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800927 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700928 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = MCOperand_getReg(MO2);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800929 //assert(ARM_AM_getSORegOffset(MO3.getImm()) == 0);
930}
931
932static void printSORegImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
933{
934 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
935 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
936
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800937 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800938 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700939 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
940 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800941 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700942 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = MCOperand_getImm(MO2) & 7;
943 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = (unsigned int)MCOperand_getImm(MO2) >> 3;
944 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800945 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800946
947 // Print the shift opc.
Alex Ionescu46018db2014-01-22 09:45:00 -0800948 printRegImmShift(MI, O, ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2)),
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +0700949 getSORegOffset((unsigned int)MCOperand_getImm(MO2)));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800950}
951
952//===--------------------------------------------------------------------===//
953// Addressing Mode #2
954//===--------------------------------------------------------------------===//
955
956static void printAM2PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O)
957{
958 MCOperand *MO1 = MCInst_getOperand(MI, Op);
959 MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
960 MCOperand *MO3 = MCInst_getOperand(MI, Op + 2);
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +0800961 ARM_AM_AddrOpc subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800962
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700963 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800964 set_mem_access(MI, true);
965
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800966 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800967 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700968 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800969 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800970
971 if (!MCOperand_getReg(MO2)) {
Alex Ionescu46018db2014-01-22 09:45:00 -0800972 unsigned tmp = getAM2Offset((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800973 if (tmp) { // Don't print +0.
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +0800974 subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO3));
975
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700976 SStream_concat0(O, ", ");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800977 if (tmp > HEX_THRESHOLD)
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +0800978 SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(subtracted), tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800979 else
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +0800980 SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(subtracted), tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800981 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700982 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (arm_shifter)getAM2Op((unsigned int)MCOperand_getImm(MO3));
983 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = tmp;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +0800984 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800985 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800986 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700987 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800988 set_mem_access(MI, false);
989 return;
990 }
991
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700992 SStream_concat0(O, ", ");
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +0800993 SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800994 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800995 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700996 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +0800997 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800998 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800999
Alex Ionescu46018db2014-01-22 09:45:00 -08001000 printRegImmShift(MI, O, getAM2ShiftOpc((unsigned int)MCOperand_getImm(MO3)),
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +07001001 getAM2Offset((unsigned int)MCOperand_getImm(MO3)));
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001002 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001003 set_mem_access(MI, false);
1004}
1005
1006static void printAddrModeTBB(MCInst *MI, unsigned Op, SStream *O)
1007{
1008 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1009 MCOperand *MO2 = MCInst_getOperand(MI, Op+1);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001010 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001011 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001012 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001013 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001014 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001015 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001016 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001017 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001018 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001019 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001020 set_mem_access(MI, false);
1021}
1022
1023static void printAddrModeTBH(MCInst *MI, unsigned Op, SStream *O)
1024{
1025 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1026 MCOperand *MO2 = MCInst_getOperand(MI, Op+1);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001027 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001028 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001029 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001030 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001031 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001032 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001033 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001034 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001035 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001036 SStream_concat0(O, ", lsl #1]");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001037 if (MI->csh->detail) {
Nguyen Anh Quynh706b8082015-01-12 15:27:29 +08001038 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.lshift = 1;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001039 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001040 set_mem_access(MI, false);
1041}
1042
1043static void printAddrMode2Operand(MCInst *MI, unsigned Op, SStream *O)
1044{
1045 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1046
1047 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
1048 printOperand(MI, Op, O);
1049 return;
1050 }
1051
1052 printAM2PreOrOffsetIndexOp(MI, Op, O);
1053}
1054
1055static void printAddrMode2OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
1056{
1057 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1058 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001059 ARM_AM_AddrOpc subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001060
1061 if (!MCOperand_getReg(MO1)) {
Alex Ionescu46018db2014-01-22 09:45:00 -08001062 unsigned ImmOffs = getAM2Offset((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001063 if (ImmOffs > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001064 SStream_concat(O, "#%s0x%x",
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001065 ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001066 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001067 SStream_concat(O, "#%s%u",
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001068 ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001069 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001070 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1071 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = ImmOffs;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001072 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001073 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001074 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001075 return;
1076 }
1077
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001078 SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001079 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001080 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001081 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1082 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001083 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001084 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001085 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001086 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001087
Alex Ionescu46018db2014-01-22 09:45:00 -08001088 printRegImmShift(MI, O, getAM2ShiftOpc((unsigned int)MCOperand_getImm(MO2)),
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +07001089 getAM2Offset((unsigned int)MCOperand_getImm(MO2)));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001090}
1091
1092//===--------------------------------------------------------------------===//
1093// Addressing Mode #3
1094//===--------------------------------------------------------------------===//
1095
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001096static void printAM3PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O,
1097 bool AlwaysPrintImm0)
1098{
1099 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1100 MCOperand *MO2 = MCInst_getOperand(MI, Op+1);
1101 MCOperand *MO3 = MCInst_getOperand(MI, Op+2);
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001102 ARM_AM_AddrOpc subtracted = getAM3Op((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001103 unsigned ImmOffs;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001104
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001105 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001106 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001107 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001108 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001109 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001110
1111 if (MCOperand_getReg(MO2)) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001112 SStream_concat0(O, ", ");
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001113 SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001114 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001115 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001116 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001117 if (subtracted) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001118 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = -1;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001119 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
1120 }
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001121 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001122 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001123 set_mem_access(MI, false);
1124 return;
1125 }
1126
1127 //If the op is sub we have to print the immediate even if it is 0
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001128 ImmOffs = getAM3Offset((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001129
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001130 if (AlwaysPrintImm0 || ImmOffs || (subtracted == ARM_AM_sub)) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001131 if (ImmOffs > HEX_THRESHOLD)
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001132 SStream_concat(O, ", #%s0x%x", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001133 else
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001134 SStream_concat(O, ", #%s%u", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001135 }
Nguyen Anh Quynh6677b992013-12-08 22:20:35 +08001136
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001137 if (MI->csh->detail) {
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001138 if (subtracted) {
pzreadced9a6e2015-02-15 18:22:51 +09001139 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = (int)ImmOffs;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001140 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
1141 } else
Nguyen Anh Quynh4b68d952015-02-25 18:01:02 +08001142 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = -(int)ImmOffs;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001143 }
Nguyen Anh Quynh6677b992013-12-08 22:20:35 +08001144
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001145 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001146 set_mem_access(MI, false);
1147}
1148
1149static void printAddrMode3Operand(MCInst *MI, unsigned Op, SStream *O,
1150 bool AlwaysPrintImm0)
1151{
1152 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1153 if (!MCOperand_isReg(MO1)) { // For label symbolic references.
1154 printOperand(MI, Op, O);
1155 return;
1156 }
1157
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001158 printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
1159}
1160
1161static void printAddrMode3OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
1162{
1163 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1164 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001165 ARM_AM_AddrOpc subtracted = getAM3Op((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001166 unsigned ImmOffs;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001167
1168 if (MCOperand_getReg(MO1)) {
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001169 SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001170 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001171 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001172 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
Nguyen Anh Quynh8693fcd2014-06-17 13:28:33 +08001173 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001174 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001175 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001176 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001177 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001178 return;
1179 }
1180
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001181 ImmOffs = getAM3Offset((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001182 if (ImmOffs > HEX_THRESHOLD)
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001183 SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001184 else
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001185 SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001186 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001187 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
Nguyen Anh Quynh6677b992013-12-08 22:20:35 +08001188
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001189 if (subtracted) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001190 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = ImmOffs;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001191 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
1192 } else
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001193 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = -(int)ImmOffs;
Nguyen Anh Quynh6677b992013-12-08 22:20:35 +08001194
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001195 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001196 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001197}
1198
1199static void printPostIdxImm8Operand(MCInst *MI, unsigned OpNum, SStream *O)
1200{
1201 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Alex Ionescu46018db2014-01-22 09:45:00 -08001202 unsigned Imm = (unsigned int)MCOperand_getImm(MO);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001203 if ((Imm & 0xff) > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001204 SStream_concat(O, "#%s0x%x", ((Imm & 256) ? "" : "-"), (Imm & 0xff));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001205 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001206 SStream_concat(O, "#%s%u", ((Imm & 256) ? "" : "-"), (Imm & 0xff));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001207 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001208 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1209 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Imm & 0xff;
1210 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001211 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001212}
1213
1214static void printPostIdxRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
1215{
1216 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1217 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
1218
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001219 SStream_concat0(O, (MCOperand_getImm(MO2) ? "" : "-"));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001220 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001221 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001222 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1223 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001224 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001225 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001226 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001227}
1228
1229static void printPostIdxImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O)
1230{
1231 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Alex Ionescu46018db2014-01-22 09:45:00 -08001232 unsigned Imm = (unsigned int)MCOperand_getImm(MO);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001233 if (((Imm & 0xff) << 2) > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001234 SStream_concat(O, "#%s0x%x", ((Imm & 256) ? "" : "-"), ((Imm & 0xff) << 2));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001235 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001236 SStream_concat(O, "#%s%u", ((Imm & 256) ? "" : "-"), ((Imm & 0xff) << 2));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001237}
1238
1239static void printAddrMode5Operand(MCInst *MI, unsigned OpNum, SStream *O,
1240 bool AlwaysPrintImm0)
1241{
Nguyen Anh Quynh6acaaa52014-11-10 17:41:05 +08001242 unsigned ImmOffs;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001243 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1244 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynh6acaaa52014-11-10 17:41:05 +08001245 ARM_AM_AddrOpc subtracted = ARM_AM_getAM5Op((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001246
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001247 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
1248 printOperand(MI, OpNum, O);
1249 return;
1250 }
1251
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001252 SStream_concat0(O, "[");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001253 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001254
Nguyen Anh Quynhb79d9152014-06-01 10:48:55 +07001255 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001256 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
1257 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
1258 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
1259 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
1260 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001261 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynhb79d9152014-06-01 10:48:55 +07001262 }
1263
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001264 ImmOffs = ARM_AM_getAM5Offset((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh6acaaa52014-11-10 17:41:05 +08001265 if (AlwaysPrintImm0 || ImmOffs || subtracted == ARM_AM_sub) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001266 if (ImmOffs * 4 > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001267 SStream_concat(O, ", #%s0x%x",
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001268 ARM_AM_getAddrOpcStr(subtracted),
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001269 ImmOffs * 4);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001270 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001271 SStream_concat(O, ", #%s%u",
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001272 ARM_AM_getAddrOpcStr(subtracted),
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001273 ImmOffs * 4);
Nguyen Anh Quynha04ee4f2014-06-01 10:52:01 +07001274 if (MI->csh->detail) {
Nguyen Anh Quynh6acaaa52014-11-10 17:41:05 +08001275 if (subtracted)
1276 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = ImmOffs * 4;
1277 else
Nguyen Anh Quynh51888c32014-11-11 23:59:23 +08001278 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = -(int)ImmOffs * 4;
Nguyen Anh Quynha04ee4f2014-06-01 10:52:01 +07001279 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001280 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001281 SStream_concat0(O, "]");
Nguyen Anh Quynhb79d9152014-06-01 10:48:55 +07001282
1283 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001284 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynhb79d9152014-06-01 10:48:55 +07001285 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001286}
1287
1288static void printAddrMode6Operand(MCInst *MI, unsigned OpNum, SStream *O)
1289{
1290 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1291 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001292 unsigned tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001293
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001294 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001295 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001296 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001297 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001298 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001299 tmp = (unsigned int)MCOperand_getImm(MO2);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001300 if (tmp) {
1301 if (tmp << 3 > HEX_THRESHOLD)
1302 SStream_concat(O, ":0x%x", (tmp << 3));
1303 else
1304 SStream_concat(O, ":%u", (tmp << 3));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001305 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001306 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp << 3;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001307 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001308 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001309 set_mem_access(MI, false);
1310}
1311
1312static void printAddrMode7Operand(MCInst *MI, unsigned OpNum, SStream *O)
1313{
1314 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001315 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001316 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001317 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001318 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001319 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001320 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001321 set_mem_access(MI, false);
1322}
1323
1324static void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
1325{
1326 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +08001327 if (MCOperand_getReg(MO) == 0) {
1328 MI->writeback = true;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001329 SStream_concat0(O, "!");
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +08001330 } else {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001331 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001332 printRegName(MI->csh, O, MCOperand_getReg(MO));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001333 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001334 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1335 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001336 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001337 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001338 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001339 }
1340}
1341
1342static void printBitfieldInvMaskImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1343{
1344 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Alex Ionescu46018db2014-01-22 09:45:00 -08001345 uint32_t v = ~(uint32_t)MCOperand_getImm(MO);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001346 int32_t lsb = CountTrailingZeros_32(v);
1347 int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001348
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001349 //assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001350 if (lsb > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001351 SStream_concat(O, "#0x%x", lsb);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001352 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001353 SStream_concat(O, "#%u", lsb);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001354
1355 if (width > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001356 SStream_concat(O, ", #0x%x", width);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001357 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001358 SStream_concat(O, ", #%u", width);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001359
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001360 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001361 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1362 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = lsb;
1363 MI->flat_insn->detail->arm.op_count++;
1364 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1365 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = width;
1366 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001367 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001368}
1369
1370static void printMemBOption(MCInst *MI, unsigned OpNum, SStream *O)
1371{
Alex Ionescu46018db2014-01-22 09:45:00 -08001372 unsigned val = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh8cdafda2014-11-11 22:30:30 +08001373 SStream_concat0(O, ARM_MB_MemBOptToString(val + 1,
Nguyen Anh Quynh1ffc1b22014-11-12 13:33:15 +08001374 (ARM_getFeatureBits(MI->csh->mode) & ARM_HasV8Ops)));
Nguyen Anh Quynh8cdafda2014-11-11 22:30:30 +08001375
1376 if (MI->csh->detail) {
Nguyen Anh Quynh51888c32014-11-11 23:59:23 +08001377 MI->flat_insn->detail->arm.mem_barrier = (arm_mem_barrier)(val + 1);
Nguyen Anh Quynh8cdafda2014-11-11 22:30:30 +08001378 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001379}
1380
1381void printInstSyncBOption(MCInst *MI, unsigned OpNum, SStream *O)
1382{
Alex Ionescu46018db2014-01-22 09:45:00 -08001383 unsigned val = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001384 SStream_concat0(O, ARM_ISB_InstSyncBOptToString(val));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001385}
1386
1387static void printShiftImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1388{
Alex Ionescu46018db2014-01-22 09:45:00 -08001389 unsigned ShiftOp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001390 bool isASR = (ShiftOp & (1 << 5)) != 0;
1391 unsigned Amt = ShiftOp & 0x1f;
1392 if (isASR) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001393 unsigned tmp = Amt == 0 ? 32 : Amt;
1394 if (tmp > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001395 SStream_concat(O, ", asr #0x%x", tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001396 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001397 SStream_concat(O, ", asr #%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001398 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001399 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_ASR;
1400 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = tmp;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001401 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001402 } else if (Amt) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001403 if (Amt > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001404 SStream_concat(O, ", lsl #0x%x", Amt);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001405 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001406 SStream_concat(O, ", lsl #%u", Amt);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001407 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001408 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_LSL;
1409 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = Amt;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001410 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001411 }
1412}
1413
1414static void printPKHLSLShiftImm(MCInst *MI, unsigned OpNum, SStream *O)
1415{
Alex Ionescu46018db2014-01-22 09:45:00 -08001416 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001417 if (Imm == 0)
1418 return;
1419 //assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001420 if (Imm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001421 SStream_concat(O, ", lsl #0x%x", Imm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001422 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001423 SStream_concat(O, ", lsl #%u", Imm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001424 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001425 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_LSL;
1426 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = Imm;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001427 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001428}
1429
1430static void printPKHASRShiftImm(MCInst *MI, unsigned OpNum, SStream *O)
1431{
Alex Ionescu46018db2014-01-22 09:45:00 -08001432 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001433 // A shift amount of 32 is encoded as 0.
1434 if (Imm == 0)
1435 Imm = 32;
1436 //assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001437 if (Imm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001438 SStream_concat(O, ", asr #0x%x", Imm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001439 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001440 SStream_concat(O, ", asr #%u", Imm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001441 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001442 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_ASR;
1443 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = Imm;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001444 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001445}
1446
1447// FIXME: push {r1, r2, r3, ...} can exceed the number of operands in MCInst struct
1448static void printRegisterList(MCInst *MI, unsigned OpNum, SStream *O)
1449{
Nguyen Anh Quynh42706a32014-05-09 07:33:35 +08001450 unsigned i, e;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001451#ifndef CAPSTONE_DIET
Ole André Vadla Ravnåsd2e6b5a2015-04-23 12:19:38 +02001452 uint8_t access = 0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001453#endif
1454
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001455 SStream_concat0(O, "{");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001456
1457#ifndef CAPSTONE_DIET
1458 if (MI->csh->detail) {
1459 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1460 }
1461#endif
1462
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001463 for (i = OpNum, e = MCInst_getNumOperands(MI); i != e; ++i) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001464 if (i != OpNum) SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001465 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, i)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001466 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001467 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1468 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, i));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001469#ifndef CAPSTONE_DIET
1470 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
1471#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001472 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001473 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001474 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001475 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001476
1477#ifndef CAPSTONE_DIET
1478 if (MI->csh->detail) {
1479 MI->ac_idx++;
1480 }
1481#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001482}
1483
1484static void printGPRPairOperand(MCInst *MI, unsigned OpNum, SStream *O,
1485 MCRegisterInfo *MRI)
1486{
1487 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001488 printRegName(MI->csh, O, MCRegisterInfo_getSubReg(MRI, Reg, ARM_gsub_0));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001489 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001490 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1491 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCRegisterInfo_getSubReg(MRI, Reg, ARM_gsub_0);
1492 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001493 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001494 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001495 printRegName(MI->csh, O, MCRegisterInfo_getSubReg(MRI, Reg, ARM_gsub_1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001496 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001497 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1498 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCRegisterInfo_getSubReg(MRI, Reg, ARM_gsub_1);
1499 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001500 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001501}
1502
1503// SETEND BE/LE
1504static void printSetendOperand(MCInst *MI, unsigned OpNum, SStream *O)
1505{
1506 MCOperand *Op = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001507 if (MCOperand_getImm(Op)) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001508 SStream_concat0(O, "be");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001509 if (MI->csh->detail) {
1510 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SETEND;
1511 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].setend = ARM_SETEND_BE;
1512 MI->flat_insn->detail->arm.op_count++;
1513 }
1514 } else {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001515 SStream_concat0(O, "le");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001516 if (MI->csh->detail) {
1517 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SETEND;
1518 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].setend = ARM_SETEND_LE;
1519 MI->flat_insn->detail->arm.op_count++;
1520 }
1521 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001522}
1523
1524static void printCPSIMod(MCInst *MI, unsigned OpNum, SStream *O)
1525{
1526 MCOperand *Op = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001527 unsigned int mode = (unsigned int)MCOperand_getImm(Op);
1528
1529 SStream_concat0(O, ARM_PROC_IModToString(mode));
1530
1531 if (MI->csh->detail) {
1532 MI->flat_insn->detail->arm.cps_mode = mode;
1533 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001534}
1535
1536static void printCPSIFlag(MCInst *MI, unsigned OpNum, SStream *O)
1537{
1538 MCOperand *Op = MCInst_getOperand(MI, OpNum);
Alex Ionescu46018db2014-01-22 09:45:00 -08001539 unsigned IFlags = (unsigned int)MCOperand_getImm(Op);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001540 int i;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001541
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001542 for (i = 2; i >= 0; --i)
1543 if (IFlags & (1 << i)) {
1544 SStream_concat0(O, ARM_PROC_IFlagsToString(1 << i));
1545 }
1546
1547 if (IFlags == 0) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001548 SStream_concat0(O, "none");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001549 IFlags = ARM_CPSFLAG_NONE;
1550 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001551
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001552 if (MI->csh->detail) {
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001553 MI->flat_insn->detail->arm.cps_flag = IFlags;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001554 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001555}
1556
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001557static void printMSRMaskOperand(MCInst *MI, unsigned OpNum, SStream *O)
1558{
1559 MCOperand *Op = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh07c92ec2014-08-26 15:35:11 +08001560 unsigned SpecRegRBit = (unsigned)MCOperand_getImm(Op) >> 4;
Nguyen Anh Quynhb52f11f2014-08-13 22:38:15 +08001561 unsigned Mask = MCOperand_getImm(Op) & 0xf;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001562 unsigned reg;
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001563 uint64_t FeatureBits = ARM_getFeatureBits(MI->csh->mode);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001564
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001565 if (FeatureBits & ARM_FeatureMClass) {
Nguyen Anh Quynh07c92ec2014-08-26 15:35:11 +08001566 unsigned SYSm = (unsigned)MCOperand_getImm(Op);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001567 unsigned Opcode = MCInst_getOpcode(MI);
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001568
1569 // For writes, handle extended mask bits if the DSP extension is present.
1570 if (Opcode == ARM_t2MSR_M && (FeatureBits & ARM_FeatureDSPThumb2)) {
1571 switch (SYSm) {
1572 case 0x400: SStream_concat0(O, "apsr_g"); ARM_addSysReg(MI, ARM_SYSREG_APSR_G); return;
1573 case 0xc00: SStream_concat0(O, "apsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQG); return;
1574 case 0x401: SStream_concat0(O, "iapsr_g"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR_G); return;
1575 case 0xc01: SStream_concat0(O, "iapsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR_NZCVQG); return;
1576 case 0x402: SStream_concat0(O, "eapsr_g"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR_G); return;
1577 case 0xc02: SStream_concat0(O, "eapsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR_NZCVQG); return;
1578 case 0x403: SStream_concat0(O, "xpsr_g"); ARM_addSysReg(MI, ARM_SYSREG_XPSR_G); return;
1579 case 0xc03: SStream_concat0(O, "xpsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_XPSR_NZCVQG); return;
1580 }
1581 }
1582
1583 // Handle the basic 8-bit mask.
1584 SYSm &= 0xff;
1585
1586 if (Opcode == ARM_t2MSR_M && (FeatureBits & ARM_HasV7Ops)) {
1587 // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
1588 // alias for MSR APSR_nzcvq.
1589 switch (SYSm) {
1590 case 0: SStream_concat0(O, "apsr_nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQ); return;
1591 case 1: SStream_concat0(O, "iapsr_nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR_NZCVQ); return;
1592 case 2: SStream_concat0(O, "eapsr_nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR_NZCVQ); return;
1593 case 3: SStream_concat0(O, "xpsr_nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_XPSR_NZCVQ); return;
1594 }
1595 }
1596
1597
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001598 switch (SYSm) {
Nguyen Anh Quynhb52f11f2014-08-13 22:38:15 +08001599 default: //llvm_unreachable("Unexpected mask value!");
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08001600 case 0: SStream_concat0(O, "apsr"); ARM_addSysReg(MI, ARM_SYSREG_APSR); return;
1601 case 1: SStream_concat0(O, "iapsr"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR); return;
1602 case 2: SStream_concat0(O, "eapsr"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR); return;
1603 case 3: SStream_concat0(O, "xpsr"); ARM_addSysReg(MI, ARM_SYSREG_XPSR); return;
1604 case 5: SStream_concat0(O, "ipsr"); ARM_addSysReg(MI, ARM_SYSREG_IPSR); return;
1605 case 6: SStream_concat0(O, "epsr"); ARM_addSysReg(MI, ARM_SYSREG_EPSR); return;
1606 case 7: SStream_concat0(O, "iepsr"); ARM_addSysReg(MI, ARM_SYSREG_IEPSR); return;
1607 case 8: SStream_concat0(O, "msp"); ARM_addSysReg(MI, ARM_SYSREG_MSP); return;
1608 case 9: SStream_concat0(O, "psp"); ARM_addSysReg(MI, ARM_SYSREG_PSP); return;
1609 case 16: SStream_concat0(O, "primask"); ARM_addSysReg(MI, ARM_SYSREG_PRIMASK); return;
1610 case 17: SStream_concat0(O, "basepri"); ARM_addSysReg(MI, ARM_SYSREG_BASEPRI); return;
1611 case 18: SStream_concat0(O, "basepri_max"); ARM_addSysReg(MI, ARM_SYSREG_BASEPRI_MAX); return;
1612 case 19: SStream_concat0(O, "faultmask"); ARM_addSysReg(MI, ARM_SYSREG_FAULTMASK); return;
1613 case 20: SStream_concat0(O, "control"); ARM_addSysReg(MI, ARM_SYSREG_CONTROL); return;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001614 }
1615 }
Nguyen Anh Quynhb52f11f2014-08-13 22:38:15 +08001616
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001617 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
1618 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
1619 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
Nguyen Anh Quynhd865f392014-11-10 16:38:17 +08001620 SStream_concat0(O, "apsr_");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001621 switch (Mask) {
Nguyen Anh Quynhb52f11f2014-08-13 22:38:15 +08001622 default: // llvm_unreachable("Unexpected mask value!");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001623 case 4: SStream_concat0(O, "g"); ARM_addSysReg(MI, ARM_SYSREG_APSR_G); return;
1624 case 8: SStream_concat0(O, "nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQ); return;
1625 case 12: SStream_concat0(O, "nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQG); return;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001626 }
1627 }
1628
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001629 reg = 0;
1630 if (SpecRegRBit) {
Nguyen Anh Quynhd865f392014-11-10 16:38:17 +08001631 SStream_concat0(O, "spsr");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001632 if (Mask) {
1633 SStream_concat0(O, "_");
1634 if (Mask & 8) {
1635 SStream_concat0(O, "f");
1636 reg += ARM_SYSREG_SPSR_F;
1637 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001638
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001639 if (Mask & 4) {
1640 SStream_concat0(O, "s");
1641 reg += ARM_SYSREG_SPSR_S;
1642 }
1643
1644 if (Mask & 2) {
1645 SStream_concat0(O, "x");
1646 reg += ARM_SYSREG_SPSR_X;
1647 }
1648
1649 if (Mask & 1) {
1650 SStream_concat0(O, "c");
1651 reg += ARM_SYSREG_SPSR_C;
1652 }
1653 ARM_addSysReg(MI, reg);
1654 }
1655 } else {
Nguyen Anh Quynhd865f392014-11-10 16:38:17 +08001656 SStream_concat0(O, "cpsr");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001657 if (Mask) {
1658 SStream_concat0(O, "_");
1659 if (Mask & 8) {
1660 SStream_concat0(O, "f");
1661 reg += ARM_SYSREG_CPSR_F;
1662 }
1663
1664 if (Mask & 4) {
1665 SStream_concat0(O, "s");
1666 reg += ARM_SYSREG_CPSR_S;
1667 }
1668
1669 if (Mask & 2) {
1670 SStream_concat0(O, "x");
1671 reg += ARM_SYSREG_CPSR_X;
1672 }
1673
1674 if (Mask & 1) {
1675 SStream_concat0(O, "c");
1676 reg += ARM_SYSREG_CPSR_C;
1677 }
1678 ARM_addSysReg(MI, reg);
1679 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001680 }
1681}
1682
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001683static void printBankedRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
1684{
1685 uint32_t Banked = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1686 uint32_t R = (Banked & 0x20) >> 5;
1687 uint32_t SysM = Banked & 0x1f;
1688 char *RegNames[] = {
1689 "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "sp_usr", "lr_usr", "",
1690 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq", "lr_fiq", "",
1691 "lr_irq", "sp_irq", "lr_svc", "sp_svc", "lr_abt", "sp_abt", "lr_und", "sp_und",
1692 "", "", "", "", "lr_mon", "sp_mon", "elr_hyp", "sp_hyp"
1693 };
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08001694 arm_sysreg RegIds[] = {
1695 ARM_SYSREG_R8_USR, ARM_SYSREG_R9_USR, ARM_SYSREG_R10_USR,
1696 ARM_SYSREG_R11_USR, ARM_SYSREG_R12_USR, ARM_SYSREG_SP_USR,
1697 ARM_SYSREG_LR_USR, 0, ARM_SYSREG_R8_FIQ, ARM_SYSREG_R9_FIQ,
1698 ARM_SYSREG_R10_FIQ, ARM_SYSREG_R11_FIQ, ARM_SYSREG_R12_FIQ,
1699 ARM_SYSREG_SP_FIQ, ARM_SYSREG_LR_FIQ, 0, ARM_SYSREG_LR_IRQ,
1700 ARM_SYSREG_SP_IRQ, ARM_SYSREG_LR_SVC, ARM_SYSREG_SP_SVC,
1701 ARM_SYSREG_LR_ABT, ARM_SYSREG_SP_ABT, ARM_SYSREG_LR_UND,
1702 ARM_SYSREG_SP_UND, 0, 0, 0, 0, ARM_SYSREG_LR_MON, ARM_SYSREG_SP_MON,
1703 ARM_SYSREG_ELR_HYP, ARM_SYSREG_SP_HYP,
1704 };
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001705 char *Name = RegNames[SysM];
1706
1707 // Nothing much we can do about this, the encodings are specified in B9.2.3 of
1708 // the ARM ARM v7C, and are all over the shop.
1709 if (R) {
1710 SStream_concat0(O, "SPSR_");
1711
1712 switch(SysM) {
1713 default: // llvm_unreachable("Invalid banked SPSR register");
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08001714 case 0x0e: SStream_concat0(O, "fiq"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_FIQ); return;
1715 case 0x10: SStream_concat0(O, "irq"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_IRQ); return;
1716 case 0x12: SStream_concat0(O, "svc"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_SVC); return;
1717 case 0x14: SStream_concat0(O, "abt"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_ABT); return;
1718 case 0x16: SStream_concat0(O, "und"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_UND); return;
1719 case 0x1c: SStream_concat0(O, "mon"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_MON); return;
1720 case 0x1e: SStream_concat0(O, "hyp"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_HYP); return;
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001721 }
1722 }
1723
1724 //assert(!R && "should have dealt with SPSR regs");
1725 //assert(Name[0] && "invalid banked register operand");
1726
1727 SStream_concat0(O, Name);
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08001728 ARM_addSysReg(MI, RegIds[SysM]);
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001729}
1730
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001731static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O)
1732{
1733 ARMCC_CondCodes CC = (ARMCC_CondCodes)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1734 // Handle the undefined 15 CC value here for printing so we don't abort().
1735 if ((unsigned)CC == 15) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001736 SStream_concat0(O, "<und>");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001737 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001738 MI->flat_insn->detail->arm.cc = ARM_CC_INVALID;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001739 } else {
1740 if (CC != ARMCC_AL) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001741 SStream_concat0(O, ARMCC_ARMCondCodeToString(CC));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001742 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001743 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001744 MI->flat_insn->detail->arm.cc = CC + 1;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001745 }
1746}
1747
1748// TODO: test this
1749static void printMandatoryPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O)
1750{
1751 ARMCC_CondCodes CC = (ARMCC_CondCodes)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001752 SStream_concat0(O, ARMCC_ARMCondCodeToString(CC));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001753 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001754 MI->flat_insn->detail->arm.cc = CC + 1;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001755}
1756
1757static void printSBitModifierOperand(MCInst *MI, unsigned OpNum, SStream *O)
1758{
1759 if (MCOperand_getReg(MCInst_getOperand(MI, OpNum))) {
1760 //assert(MCOperand_getReg(MCInst_getOperand(MI, OpNum)) == ARM_CPSR &&
1761 // "Expect ARM CPSR register!");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001762 SStream_concat0(O, "s");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001763 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001764 MI->flat_insn->detail->arm.update_flags = true;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001765 }
1766}
1767
1768static void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O)
1769{
Alex Ionescu46018db2014-01-22 09:45:00 -08001770 unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001771 if (tmp > HEX_THRESHOLD)
1772 SStream_concat(O, "0x%x", tmp);
1773 else
1774 SStream_concat(O, "%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001775 if (MI->csh->detail) {
Nguyen Anh Quynh19b0de32013-12-31 22:40:04 +08001776 if (MI->csh->doing_mem) {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001777 MI->flat_insn->detail->arm.op_count--;
1778 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].neon_lane = tmp;
1779 MI->ac_idx--; // consecutive operands share the same access right
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001780 } else {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001781 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1782 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
1783 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001784 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001785 }
1786}
1787
1788static void printPImmediate(MCInst *MI, unsigned OpNum, SStream *O)
1789{
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001790 unsigned imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1791
1792 SStream_concat(O, "p%u", imm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001793 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001794 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_PIMM;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001795 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001796 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001797 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001798}
1799
1800static void printCImmediate(MCInst *MI, unsigned OpNum, SStream *O)
1801{
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001802 unsigned imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1803
1804 SStream_concat(O, "c%u", imm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001805 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001806 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_CIMM;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001807 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001808 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001809 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001810}
1811
1812static void printCoprocOptionImm(MCInst *MI, unsigned OpNum, SStream *O)
1813{
Alex Ionescu46018db2014-01-22 09:45:00 -08001814 unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001815 if (tmp > HEX_THRESHOLD)
1816 SStream_concat(O, "{0x%x}", tmp);
1817 else
1818 SStream_concat(O, "{%u}", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001819 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001820 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1821 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
1822 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001823 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001824}
1825
1826static void printAdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned scale)
1827{
1828 MCOperand *MO = MCInst_getOperand(MI, OpNum);
1829
1830 int32_t OffImm = (int32_t)MCOperand_getImm(MO) << scale;
1831
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001832 if (OffImm == INT32_MIN) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001833 SStream_concat0(O, "#-0");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001834 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001835 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1836 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = 0;
1837 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001838 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001839 } else {
1840 if (OffImm < 0)
Nguyen Anh Quynh741a9de2013-11-28 16:02:08 +08001841 SStream_concat(O, "#-0x%x", -OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001842 else {
1843 if (OffImm > HEX_THRESHOLD)
1844 SStream_concat(O, "#0x%x", OffImm);
1845 else
1846 SStream_concat(O, "#%u", OffImm);
1847 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001848 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001849 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1850 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
1851 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001852 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001853 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001854}
1855
1856static void printThumbS4ImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1857{
Alex Ionescu46018db2014-01-22 09:45:00 -08001858 unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)) * 4;
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001859 if (tmp > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001860 SStream_concat(O, "#0x%x", tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001861 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001862 SStream_concat(O, "#%u", tmp);
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08001863 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001864 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1865 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
1866 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08001867 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001868}
1869
1870static void printThumbSRImm(MCInst *MI, unsigned OpNum, SStream *O)
1871{
Alex Ionescu46018db2014-01-22 09:45:00 -08001872 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001873 unsigned tmp = Imm == 0 ? 32 : Imm;
1874 if (tmp > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001875 SStream_concat(O, "#0x%x", tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001876 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001877 SStream_concat(O, "#%u", tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001878
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001879 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001880 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1881 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
1882 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001883 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001884}
1885
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001886static void printThumbITMask(MCInst *MI, unsigned OpNum, SStream *O)
1887{
1888 // (3 - the number of trailing zeros) is the number of then / else.
Alex Ionescu46018db2014-01-22 09:45:00 -08001889 unsigned Mask = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1890 unsigned Firstcond = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum-1));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001891 unsigned CondBit0 = Firstcond & 1;
1892 unsigned NumTZ = CountTrailingZeros_32(Mask);
1893 //assert(NumTZ <= 3 && "Invalid IT mask!");
1894 unsigned Pos, e;
1895 for (Pos = 3, e = NumTZ; Pos > e; --Pos) {
1896 bool T = ((Mask >> Pos) & 1) == CondBit0;
1897 if (T)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001898 SStream_concat0(O, "t");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001899 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001900 SStream_concat0(O, "e");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001901 }
1902}
1903
1904static void printThumbAddrModeRROperand(MCInst *MI, unsigned Op, SStream *O)
1905{
1906 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1907 MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001908 unsigned RegNum;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001909
1910 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
1911 printOperand(MI, Op, O);
1912 return;
1913 }
1914
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001915 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001916 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001917 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001918 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001919 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001920 RegNum = MCOperand_getReg(MO2);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001921 if (RegNum) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001922 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001923 printRegName(MI->csh, O, RegNum);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001924 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001925 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = RegNum;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001926 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001927 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001928 set_mem_access(MI, false);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001929}
1930
1931static void printThumbAddrModeImm5SOperand(MCInst *MI, unsigned Op, SStream *O,
1932 unsigned Scale)
1933{
1934 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1935 MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001936 unsigned ImmOffs, tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001937
1938 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
1939 printOperand(MI, Op, O);
1940 return;
1941 }
1942
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001943 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001944 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001945 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001946 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001947 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001948 ImmOffs = (unsigned int)MCOperand_getImm(MO2);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001949 if (ImmOffs) {
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001950 tmp = ImmOffs * Scale;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001951 SStream_concat0(O, ", ");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001952 if (tmp > HEX_THRESHOLD)
1953 SStream_concat(O, "#0x%x", tmp);
1954 else
1955 SStream_concat(O, "#%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001956 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001957 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001958 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001959 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001960 set_mem_access(MI, false);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001961}
1962
1963static void printThumbAddrModeImm5S1Operand(MCInst *MI, unsigned Op, SStream *O)
1964{
1965 printThumbAddrModeImm5SOperand(MI, Op, O, 1);
1966}
1967
1968static void printThumbAddrModeImm5S2Operand(MCInst *MI, unsigned Op, SStream *O)
1969{
1970 printThumbAddrModeImm5SOperand(MI, Op, O, 2);
1971}
1972
1973static void printThumbAddrModeImm5S4Operand(MCInst *MI, unsigned Op, SStream *O)
1974{
1975 printThumbAddrModeImm5SOperand(MI, Op, O, 4);
1976}
1977
1978static void printThumbAddrModeSPOperand(MCInst *MI, unsigned Op, SStream *O)
1979{
1980 printThumbAddrModeImm5SOperand(MI, Op, O, 4);
1981}
1982
1983// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1984// register with shift forms.
1985// REG 0 0 - e.g. R5
1986// REG IMM, SH_OPC - e.g. R5, LSL #3
1987static void printT2SOOperand(MCInst *MI, unsigned OpNum, SStream *O)
1988{
1989 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1990 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
1991
1992 unsigned Reg = MCOperand_getReg(MO1);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001993 printRegName(MI->csh, O, Reg);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001994 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001995 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1996 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001997 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001998 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001999 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002000
2001 // Print the shift opc.
2002 //assert(MO2.isImm() && "Not a valid t2_so_reg value!");
Alex Ionescu46018db2014-01-22 09:45:00 -08002003 printRegImmShift(MI, O, ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2)),
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +07002004 getSORegOffset((unsigned int)MCOperand_getImm(MO2)));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002005}
2006
2007static void printAddrModeImm12Operand(MCInst *MI, unsigned OpNum,
2008 SStream *O, bool AlwaysPrintImm0)
2009{
2010 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2011 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08002012 int32_t OffImm;
2013 bool isSub;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002014
2015 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
2016 printOperand(MI, OpNum, O);
2017 return;
2018 }
2019
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002020 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002021 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002022 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002023
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002024 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002025 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002026
Alex Ionescu46018db2014-01-22 09:45:00 -08002027 OffImm = (int32_t)MCOperand_getImm(MO2);
2028 isSub = OffImm < 0;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002029 // Special value for #-0. All others are normal.
2030 if (OffImm == INT32_MIN)
2031 OffImm = 0;
2032 if (isSub) {
Nguyen Anh Quynha247dc12014-04-12 00:19:42 +08002033 if (OffImm < -HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002034 SStream_concat(O, ", #-0x%x", -OffImm);
Nguyen Anh Quynha247dc12014-04-12 00:19:42 +08002035 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002036 SStream_concat(O, ", #-%u", -OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002037 } else if (AlwaysPrintImm0 || OffImm > 0) {
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002038 if (OffImm >= 0) {
2039 if (OffImm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002040 SStream_concat(O, ", #0x%x", OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002041 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002042 SStream_concat(O, ", #%u", OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002043 } else {
2044 if (OffImm < -HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002045 SStream_concat(O, ", #-0x%x", -OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002046 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002047 SStream_concat(O, ", #-%u", -OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002048 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002049 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002050 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002051 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002052 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002053 set_mem_access(MI, false);
2054}
2055
2056static void printT2AddrModeImm8Operand(MCInst *MI, unsigned OpNum, SStream *O,
2057 bool AlwaysPrintImm0)
2058{
2059 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2060 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08002061 int32_t OffImm;
2062 bool isSub;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002063
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002064 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002065 set_mem_access(MI, true);
2066
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002067 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002068 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002069 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002070
Alex Ionescu46018db2014-01-22 09:45:00 -08002071 OffImm = (int32_t)MCOperand_getImm(MO2);
2072 isSub = OffImm < 0;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002073 // Don't print +0.
2074 if (OffImm == INT32_MIN)
2075 OffImm = 0;
2076
2077 if (isSub)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002078 SStream_concat(O, ", #-0x%x", -OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002079 else if (AlwaysPrintImm0 || OffImm > 0) {
2080 if (OffImm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002081 SStream_concat(O, ", #0x%x", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002082 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002083 SStream_concat(O, ", #%u", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002084 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002085
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002086 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002087 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002088 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002089 set_mem_access(MI, false);
2090}
2091
2092static void printT2AddrModeImm8s4Operand(MCInst *MI,
2093 unsigned OpNum, SStream *O, bool AlwaysPrintImm0)
2094{
2095 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2096 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08002097 int32_t OffImm;
2098 bool isSub;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002099
2100 if (!MCOperand_isReg(MO1)) { // For label symbolic references.
2101 printOperand(MI, OpNum, O);
2102 return;
2103 }
2104
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002105 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002106 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002107 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002108 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002109 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002110
Alex Ionescu46018db2014-01-22 09:45:00 -08002111 OffImm = (int32_t)MCOperand_getImm(MO2);
2112 isSub = OffImm < 0;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002113
2114 //assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
2115
2116 // Don't print +0.
2117 if (OffImm == INT32_MIN)
2118 OffImm = 0;
2119 if (isSub) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002120 SStream_concat(O, ", #-0x%x", -OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002121 } else if (AlwaysPrintImm0 || OffImm > 0) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002122 if (OffImm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002123 SStream_concat(O, ", #0x%x", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002124 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002125 SStream_concat(O, ", #%u", OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002126 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002127 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002128 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002129
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002130 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002131 set_mem_access(MI, false);
2132}
2133
2134static void printT2AddrModeImm0_1020s4Operand(MCInst *MI, unsigned OpNum, SStream *O)
2135{
2136 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2137 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08002138 unsigned tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002139
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002140 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002141 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002142 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002143 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002144 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002145 if (MCOperand_getImm(MO2)) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002146 SStream_concat0(O, ", ");
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01002147 tmp = (unsigned int)MCOperand_getImm(MO2) * 4;
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002148 if (tmp > HEX_THRESHOLD)
2149 SStream_concat(O, "#0x%x", tmp);
2150 else
2151 SStream_concat(O, "#%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002152 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002153 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002154 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002155 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002156 set_mem_access(MI, false);
2157}
2158
2159static void printT2AddrModeImm8OffsetOperand(MCInst *MI,
2160 unsigned OpNum, SStream *O)
2161{
2162 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2163 int32_t OffImm = (int32_t)MCOperand_getImm(MO1);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002164 SStream_concat0(O, ", ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002165 if (OffImm == INT32_MIN) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002166 SStream_concat0(O, "#-0");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002167 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002168 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2169 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = 0;
2170 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002171 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002172 } else {
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002173 if (OffImm < 0) {
2174 if (OffImm < -HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002175 SStream_concat(O, "#-0x%x", -OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002176 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002177 SStream_concat(O, "#-%u", -OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002178 } else {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002179 if (OffImm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002180 SStream_concat(O, "#0x%x", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002181 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002182 SStream_concat(O, "#%u", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002183 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002184 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002185 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2186 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
2187 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002188 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002189 }
2190}
2191
2192static void printT2AddrModeImm8s4OffsetOperand(MCInst *MI,
2193 unsigned OpNum, SStream *O)
2194{
2195 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2196 int32_t OffImm = (int32_t)MCOperand_getImm(MO1);
2197
2198 //assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
2199
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002200 SStream_concat0(O, ", ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002201 if (OffImm == INT32_MIN) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002202 SStream_concat0(O, "#-0");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002203 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002204 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2205 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = 0;
2206 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002207 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002208 } else {
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002209 if (OffImm < 0) {
2210 if (OffImm < -HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002211 SStream_concat(O, "#-0x%x", -OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002212 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002213 SStream_concat(O, "#-%u", -OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002214 } else {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002215 if (OffImm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002216 SStream_concat(O, "#0x%x", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002217 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002218 SStream_concat(O, "#%u", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002219 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002220 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002221 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2222 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
2223 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002224 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002225 }
2226}
2227
2228static void printT2AddrModeSoRegOperand(MCInst *MI,
2229 unsigned OpNum, SStream *O)
2230{
2231 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2232 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
2233 MCOperand *MO3 = MCInst_getOperand(MI, OpNum+2);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08002234 unsigned ShAmt;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002235
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002236 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002237 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002238 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002239 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002240 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002241
2242 //assert(MCOperand_getReg(MO2.getReg() && "Invalid so_reg load / store address!");
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002243 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002244 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002245 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002246 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002247
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01002248 ShAmt = (unsigned int)MCOperand_getImm(MO3);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002249 if (ShAmt) {
2250 //assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002251 SStream_concat0(O, ", lsl ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002252 SStream_concat(O, "#%d", ShAmt);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002253 if (MI->csh->detail) {
Nguyen Anh Quynh706b8082015-01-12 15:27:29 +08002254 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.lshift = ShAmt;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002255 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002256 }
2257
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002258 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002259 set_mem_access(MI, false);
2260}
2261
2262static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
2263{
2264 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh2ac5d792014-11-10 21:46:34 +08002265 SStream_concat(O, "#%e", getFPImmFloat((unsigned int)MCOperand_getImm(MO)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002266 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002267 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_FP;
2268 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].fp = getFPImmFloat((unsigned int)MCOperand_getImm(MO));
2269 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002270 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002271}
2272
2273static void printNEONModImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
2274{
Alex Ionescu46018db2014-01-22 09:45:00 -08002275 unsigned EncodedImm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002276 unsigned EltBits;
2277 uint64_t Val = ARM_AM_decodeNEONModImm(EncodedImm, &EltBits);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002278 if (Val > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002279 SStream_concat(O, "#0x%"PRIx64, Val);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002280 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002281 SStream_concat(O, "#%"PRIu64, Val);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002282 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002283 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2284 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = (unsigned int)Val;
2285 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002286 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002287}
2288
2289static void printImmPlusOneOperand(MCInst *MI, unsigned OpNum, SStream *O)
2290{
Alex Ionescu46018db2014-01-22 09:45:00 -08002291 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002292 if (Imm + 1 > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002293 SStream_concat(O, "#0x%x", Imm + 1);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002294 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002295 SStream_concat(O, "#%u", Imm + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002296 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002297 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2298 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Imm + 1;
2299 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002300 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002301}
2302
2303static void printRotImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
2304{
Alex Ionescu46018db2014-01-22 09:45:00 -08002305 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002306 if (Imm == 0)
2307 return;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002308 SStream_concat0(O, ", ror #");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002309 switch (Imm) {
2310 default: //assert (0 && "illegal ror immediate!");
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002311 case 1: SStream_concat0(O, "8"); break;
2312 case 2: SStream_concat0(O, "16"); break;
2313 case 3: SStream_concat0(O, "24"); break;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002314 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002315 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002316 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_ROR;
2317 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = Imm * 8;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002318 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002319}
2320
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08002321static void printModImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
2322{
2323 MCOperand *Op = MCInst_getOperand(MI, OpNum);
2324 unsigned Bits = MCOperand_getImm(Op) & 0xFF;
2325 unsigned Rot = (MCOperand_getImm(Op) & 0xF00) >> 7;
2326 int32_t Rotated;
2327
2328 bool PrintUnsigned = false;
2329 switch (MCInst_getOpcode(MI)) {
2330 case ARM_MOVi:
2331 // Movs to PC should be treated unsigned
2332 PrintUnsigned = (MCOperand_getReg(MCInst_getOperand(MI, OpNum - 1)) == ARM_PC);
2333 break;
2334 case ARM_MSRi:
2335 // Movs to special registers should be treated unsigned
2336 PrintUnsigned = true;
2337 break;
2338 }
2339
2340 Rotated = rotr32(Bits, Rot);
2341 if (getSOImmVal(Rotated) == MCOperand_getImm(Op)) {
2342 // #rot has the least possible value
Nguyen Anh Quynhe0329dd2015-03-08 00:29:20 +08002343 if (PrintUnsigned) {
2344 if (Rotated > HEX_THRESHOLD || Rotated < -HEX_THRESHOLD)
2345 SStream_concat(O, "#0x%x", Rotated);
2346 else
2347 SStream_concat(O, "#%u", Rotated);
2348 } else if (Rotated >= 0) {
Nguyen Anh Quynhb8b83482015-03-07 00:26:24 +08002349 if (Rotated > HEX_THRESHOLD)
2350 SStream_concat(O, "#0x%x", Rotated);
2351 else
2352 SStream_concat(O, "#%u", Rotated);
2353 } else {
2354 SStream_concat(O, "#0x%x", Rotated);
2355 }
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08002356 if (MI->csh->detail) {
2357 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2358 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Rotated;
2359 MI->flat_insn->detail->arm.op_count++;
2360 }
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08002361 return;
2362 }
2363
2364 // Explicit #bits, #rot implied
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08002365 SStream_concat(O, "#%u, #%u", Bits, Rot);
2366 if (MI->csh->detail) {
2367 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2368 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Bits;
2369 MI->flat_insn->detail->arm.op_count++;
2370 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2371 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Rot;
2372 MI->flat_insn->detail->arm.op_count++;
2373 }
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08002374}
2375
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002376static void printFBits16(MCInst *MI, unsigned OpNum, SStream *O)
2377{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08002378 unsigned tmp;
2379
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01002380 tmp = 16 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002381 if (tmp > HEX_THRESHOLD)
2382 SStream_concat(O, "#0x%x", tmp);
2383 else
2384 SStream_concat(O, "#%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002385 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002386 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2387 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
2388 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002389 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002390}
2391
2392static void printFBits32(MCInst *MI, unsigned OpNum, SStream *O)
2393{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08002394 unsigned tmp;
2395
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01002396 tmp = 32 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002397 if (tmp > HEX_THRESHOLD)
2398 SStream_concat(O, "#0x%x", tmp);
2399 else
2400 SStream_concat(O, "#%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002401 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002402 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2403 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
2404 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002405 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002406}
2407
2408static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O)
2409{
Alex Ionescu46018db2014-01-22 09:45:00 -08002410 unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002411 if (tmp > HEX_THRESHOLD)
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002412 SStream_concat(O, "[0x%x]", tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002413 else
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002414 SStream_concat(O, "[%u]", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002415 if (MI->csh->detail) {
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08002416 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].vector_index = tmp;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002417 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002418}
2419
2420static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O)
2421{
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002422 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002423 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002424 if (MI->csh->detail) {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002425#ifndef CAPSTONE_DIET
2426 uint8_t access;
2427
2428 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2429#endif
2430
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002431 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2432 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002433#ifndef CAPSTONE_DIET
2434 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2435#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002436 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002437
2438#ifndef CAPSTONE_DIET
2439 MI->ac_idx++;
2440#endif
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002441 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002442 SStream_concat0(O, "}");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002443}
2444
2445static void printVectorListTwo(MCInst *MI, unsigned OpNum,
2446 SStream *O, MCRegisterInfo *MRI)
2447{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002448#ifndef CAPSTONE_DIET
2449 uint8_t access;
2450#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002451 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2452 unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
2453 unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002454
2455#ifndef CAPSTONE_DIET
2456 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2457#endif
2458
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002459 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002460 printRegName(MI->csh, O, Reg0);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002461 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002462 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2463 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002464#ifndef CAPSTONE_DIET
2465 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2466#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002467 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002468 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002469 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002470 printRegName(MI->csh, O, Reg1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002471 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002472 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2473 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002474#ifndef CAPSTONE_DIET
2475 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2476#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002477 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002478 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002479 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002480
2481#ifndef CAPSTONE_DIET
2482 MI->ac_idx++;
2483#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002484}
2485
2486static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum,
2487 SStream *O, MCRegisterInfo *MRI)
2488{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002489#ifndef CAPSTONE_DIET
2490 uint8_t access;
2491#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002492 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2493 unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
2494 unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_2);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002495
2496#ifndef CAPSTONE_DIET
2497 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2498#endif
2499
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002500 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002501 printRegName(MI->csh, O, Reg0);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002502 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002503 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2504 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002505#ifndef CAPSTONE_DIET
2506 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2507#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002508 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002509 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002510 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002511 printRegName(MI->csh, O, Reg1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002512 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002513 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2514 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002515#ifndef CAPSTONE_DIET
2516 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2517#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002518 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002519 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002520 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002521
2522#ifndef CAPSTONE_DIET
2523 MI->ac_idx++;
2524#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002525}
2526
2527static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
2528{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002529#ifndef CAPSTONE_DIET
2530 uint8_t access;
2531
2532 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2533#endif
2534
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002535 // Normally, it's not safe to use register enum values directly with
2536 // addition to get the next register, but for VFP registers, the
2537 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002538 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002539 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002540 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002541 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2542 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002543#ifndef CAPSTONE_DIET
2544 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2545#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002546 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002547 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002548 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002549 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002550 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002551 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2552 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002553#ifndef CAPSTONE_DIET
2554 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2555#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002556 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002557 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002558 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002559 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002560 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002561 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2562 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002563#ifndef CAPSTONE_DIET
2564 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2565#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002566 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002567 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002568 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002569
2570#ifndef CAPSTONE_DIET
2571 MI->ac_idx++;
2572#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002573}
2574
2575static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
2576{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002577#ifndef CAPSTONE_DIET
2578 uint8_t access;
2579
2580 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2581#endif
2582
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002583 // Normally, it's not safe to use register enum values directly with
2584 // addition to get the next register, but for VFP registers, the
2585 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002586 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002587 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002588 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002589 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2590 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002591#ifndef CAPSTONE_DIET
2592 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2593#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002594 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002595 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002596 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002597 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002598 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002599 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2600 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002601#ifndef CAPSTONE_DIET
2602 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2603#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002604 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002605 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002606 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002607 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002608 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002609 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2610 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002611#ifndef CAPSTONE_DIET
2612 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2613#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002614 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002615 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002616 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002617 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002618 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002619 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2620 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002621#ifndef CAPSTONE_DIET
2622 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2623#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002624 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002625 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002626 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002627
2628#ifndef CAPSTONE_DIET
2629 MI->ac_idx++;
2630#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002631}
2632
2633static void printVectorListOneAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
2634{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002635#ifndef CAPSTONE_DIET
2636 uint8_t access;
2637
2638 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2639#endif
2640
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002641 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002642 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002643 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002644 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2645 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002646#ifndef CAPSTONE_DIET
2647 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2648#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002649 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002650 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002651 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002652
2653#ifndef CAPSTONE_DIET
2654 MI->ac_idx++;
2655#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002656}
2657
2658static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum,
2659 SStream *O, MCRegisterInfo *MRI)
2660{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002661#ifndef CAPSTONE_DIET
2662 uint8_t access;
2663#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002664 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2665 unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
2666 unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002667
2668#ifndef CAPSTONE_DIET
2669 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2670#endif
2671
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002672 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002673 printRegName(MI->csh, O, Reg0);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002674 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002675 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2676 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002677#ifndef CAPSTONE_DIET
2678 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2679#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002680 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002681 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002682 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002683 printRegName(MI->csh, O, Reg1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002684 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002685 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2686 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002687#ifndef CAPSTONE_DIET
2688 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2689#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002690 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002691 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002692 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002693
2694#ifndef CAPSTONE_DIET
2695 MI->ac_idx++;
2696#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002697}
2698
2699static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
2700{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002701#ifndef CAPSTONE_DIET
2702 uint8_t access;
2703
2704 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2705#endif
2706
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002707 // Normally, it's not safe to use register enum values directly with
2708 // addition to get the next register, but for VFP registers, the
2709 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002710 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002711 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002712 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002713 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2714 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002715#ifndef CAPSTONE_DIET
2716 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2717#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002718 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002719 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002720 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002721 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002722 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002723 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2724 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002725#ifndef CAPSTONE_DIET
2726 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2727#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002728 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002729 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002730 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002731 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002732 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002733 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2734 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002735#ifndef CAPSTONE_DIET
2736 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2737#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002738 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002739 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002740 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002741
2742#ifndef CAPSTONE_DIET
2743 MI->ac_idx++;
2744#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002745}
2746
2747static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
2748{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002749#ifndef CAPSTONE_DIET
2750 uint8_t access;
2751
2752 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2753#endif
2754
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002755 // Normally, it's not safe to use register enum values directly with
2756 // addition to get the next register, but for VFP registers, the
2757 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002758 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002759 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002760 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002761 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2762 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002763#ifndef CAPSTONE_DIET
2764 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2765#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002766 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002767 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002768 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002769 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002770 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002771 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2772 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002773#ifndef CAPSTONE_DIET
2774 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2775#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002776 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002777 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002778 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002779 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002780 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002781 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2782 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002783#ifndef CAPSTONE_DIET
2784 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2785#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002786 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002787 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002788 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002789 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002790 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002791 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2792 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002793#ifndef CAPSTONE_DIET
2794 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2795#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002796 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002797 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002798 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002799
2800#ifndef CAPSTONE_DIET
2801 MI->ac_idx++;
2802#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002803}
2804
2805static void printVectorListTwoSpacedAllLanes(MCInst *MI,
2806 unsigned OpNum, SStream *O, MCRegisterInfo *MRI)
2807{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002808#ifndef CAPSTONE_DIET
2809 uint8_t access;
2810#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002811 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2812 unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
2813 unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_2);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002814
2815#ifndef CAPSTONE_DIET
2816 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2817#endif
2818
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002819 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002820 printRegName(MI->csh, O, Reg0);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002821 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002822 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2823 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002824#ifndef CAPSTONE_DIET
2825 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2826#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002827 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002828 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002829 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002830 printRegName(MI->csh, O, Reg1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002831 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002832 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2833 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002834#ifndef CAPSTONE_DIET
2835 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2836#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002837 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002838 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002839 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002840
2841#ifndef CAPSTONE_DIET
2842 MI->ac_idx++;
2843#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002844}
2845
2846static void printVectorListThreeSpacedAllLanes(MCInst *MI,
2847 unsigned OpNum, SStream *O)
2848{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002849#ifndef CAPSTONE_DIET
2850 uint8_t access;
2851
2852 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2853#endif
2854
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002855 // Normally, it's not safe to use register enum values directly with
2856 // addition to get the next register, but for VFP registers, the
2857 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002858 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002859 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002860 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002861 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2862 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002863#ifndef CAPSTONE_DIET
2864 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2865#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002866 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002867 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002868 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002869 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002870 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002871 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2872 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002873#ifndef CAPSTONE_DIET
2874 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2875#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002876 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002877 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002878 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002879 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002880 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002881 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2882 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002883#ifndef CAPSTONE_DIET
2884 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2885#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002886 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002887 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002888 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002889
2890#ifndef CAPSTONE_DIET
2891 MI->ac_idx++;
2892#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002893}
2894
2895static void printVectorListFourSpacedAllLanes(MCInst *MI,
2896 unsigned OpNum, SStream *O)
2897{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002898#ifndef CAPSTONE_DIET
2899 uint8_t access;
2900
2901 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2902#endif
2903
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002904 // Normally, it's not safe to use register enum values directly with
2905 // addition to get the next register, but for VFP registers, the
2906 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002907 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002908 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002909 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002910 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2911 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002912#ifndef CAPSTONE_DIET
2913 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2914#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002915 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002916 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002917 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002918 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002919 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002920 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2921 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002922#ifndef CAPSTONE_DIET
2923 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2924#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002925 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002926 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002927 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002928 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002929 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002930 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2931 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002932#ifndef CAPSTONE_DIET
2933 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2934#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002935 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002936 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002937 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002938 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002939 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002940 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2941 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002942#ifndef CAPSTONE_DIET
2943 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2944#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002945 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002946 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002947 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002948
2949#ifndef CAPSTONE_DIET
2950 MI->ac_idx++;
2951#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002952}
2953
2954static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
2955{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002956#ifndef CAPSTONE_DIET
2957 uint8_t access;
2958
2959 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2960#endif
2961
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002962 // Normally, it's not safe to use register enum values directly with
2963 // addition to get the next register, but for VFP registers, the
2964 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002965 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002966 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002967 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002968 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2969 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002970#ifndef CAPSTONE_DIET
2971 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2972#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002973 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002974 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002975 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002976 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002977 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002978 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2979 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002980#ifndef CAPSTONE_DIET
2981 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2982#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002983 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002984 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002985 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002986 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002987 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002988 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2989 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002990#ifndef CAPSTONE_DIET
2991 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2992#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002993 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002994 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002995 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002996
2997#ifndef CAPSTONE_DIET
2998 MI->ac_idx++;
2999#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08003000}
3001
3002static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
3003{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08003004#ifndef CAPSTONE_DIET
3005 uint8_t access;
3006
3007 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
3008#endif
3009
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08003010 // Normally, it's not safe to use register enum values directly with
3011 // addition to get the next register, but for VFP registers, the
3012 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003013 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08003014 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08003015 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003016 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3017 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08003018#ifndef CAPSTONE_DIET
3019 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
3020#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003021 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08003022 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003023 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08003024 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08003025 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003026 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3027 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08003028#ifndef CAPSTONE_DIET
3029 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
3030#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003031 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08003032 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003033 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08003034 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08003035 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003036 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3037 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08003038#ifndef CAPSTONE_DIET
3039 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
3040#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003041 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08003042 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003043 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08003044 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08003045 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003046 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3047 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08003048#ifndef CAPSTONE_DIET
3049 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
3050#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003051 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08003052 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003053 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08003054
3055#ifndef CAPSTONE_DIET
3056 MI->ac_idx++;
3057#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08003058}
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +08003059
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08003060void ARM_addVectorDataType(MCInst *MI, arm_vectordata_type vd)
3061{
3062 if (MI->csh->detail) {
3063 MI->flat_insn->detail->arm.vector_data = vd;
3064 }
3065}
3066
3067void ARM_addVectorDataSize(MCInst *MI, int size)
3068{
3069 if (MI->csh->detail) {
3070 MI->flat_insn->detail->arm.vector_size = size;
3071 }
3072}
3073
3074void ARM_addReg(MCInst *MI, int reg)
3075{
3076 if (MI->csh->detail) {
3077 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3078 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = reg;
3079 MI->flat_insn->detail->arm.op_count++;
3080 }
3081}
3082
3083void ARM_addUserMode(MCInst *MI)
3084{
3085 if (MI->csh->detail) {
3086 MI->flat_insn->detail->arm.usermode = true;
3087 }
3088}
3089
3090void ARM_addSysReg(MCInst *MI, arm_sysreg reg)
3091{
3092 if (MI->csh->detail) {
3093 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SYSREG;
3094 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = reg;
3095 MI->flat_insn->detail->arm.op_count++;
3096 }
3097}
3098
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +08003099#endif