blob: 58f54d114a77eccbe4fc888ba44079144f1c637c [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>
tandasat45e5eab2016-05-11 21:48:32 -070022#include <capstone/platform.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 Quynh256090a2016-03-14 13:52:23 +080037
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +080038static void printRegName(cs_struct *h, SStream *OS, unsigned RegNo);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080039
40// Autogenerated by tblgen.
41static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI);
42static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
43static void printSORegRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
44static void printSORegImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
45
46static void printAddrModeTBB(MCInst *MI, unsigned OpNum, SStream *O);
47static void printAddrModeTBH(MCInst *MI, unsigned OpNum, SStream *O);
48static void printAddrMode2Operand(MCInst *MI, unsigned OpNum, SStream *O);
49static void printAM2PreOrOffsetIndexOp(MCInst *MI, unsigned OpNum, SStream *O);
50static void printAddrMode2OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
51static void printAddrMode3Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
52static void printAddrMode3OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080053static void printAM3PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O, bool AlwaysPrintImm0);
54static void printPostIdxImm8Operand(MCInst *MI, unsigned OpNum, SStream *O);
55static void printPostIdxRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
56static void printPostIdxImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O);
57static void printAddrMode5Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
58static void printAddrMode6Operand(MCInst *MI, unsigned OpNum, SStream *O);
59static void printAddrMode7Operand(MCInst *MI, unsigned OpNum, SStream *O);
60static void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
61
62static void printBitfieldInvMaskImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
63static void printMemBOption(MCInst *MI, unsigned OpNum, SStream *O);
64static void printShiftImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
65static void printPKHLSLShiftImm(MCInst *MI, unsigned OpNum, SStream *O);
66static void printPKHASRShiftImm(MCInst *MI, unsigned OpNum, SStream *O);
67static void printAdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned);
68static void printThumbS4ImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
69static void printThumbSRImm(MCInst *MI, unsigned OpNum, SStream *O);
70static void printThumbITMask(MCInst *MI, unsigned OpNum, SStream *O);
71static void printThumbAddrModeRROperand(MCInst *MI, unsigned OpNum, SStream *O);
72static void printThumbAddrModeImm5SOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned Scale);
73static void printThumbAddrModeImm5S1Operand(MCInst *MI, unsigned OpNum, SStream *O);
74static void printThumbAddrModeImm5S2Operand(MCInst *MI, unsigned OpNum, SStream *O);
75static void printThumbAddrModeImm5S4Operand(MCInst *MI, unsigned OpNum, SStream *O);
76static void printThumbAddrModeSPOperand(MCInst *MI, unsigned OpNum, SStream *O);
77static void printT2SOOperand(MCInst *MI, unsigned OpNum, SStream *O);
78static void printAddrModeImm12Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
79static void printT2AddrModeImm8Operand(MCInst *MI, unsigned OpNum, SStream *O, bool);
80static void printT2AddrModeImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O, bool);
81static void printT2AddrModeImm0_1020s4Operand(MCInst *MI, unsigned OpNum, SStream *O);
82static void printT2AddrModeImm8OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
83static void printT2AddrModeImm8s4OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
84static void printT2AddrModeSoRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
85static void printSetendOperand(MCInst *MI, unsigned OpNum, SStream *O);
86static void printCPSIMod(MCInst *MI, unsigned OpNum, SStream *O);
87static void printCPSIFlag(MCInst *MI, unsigned OpNum, SStream *O);
88static void printMSRMaskOperand(MCInst *MI, unsigned OpNum, SStream *O);
89static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O);
90static void printMandatoryPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O);
91static void printSBitModifierOperand(MCInst *MI, unsigned OpNum, SStream *O);
92static void printRegisterList(MCInst *MI, unsigned OpNum, SStream *O);
93static void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O);
94static void printPImmediate(MCInst *MI, unsigned OpNum, SStream *O);
95static void printCImmediate(MCInst *MI, unsigned OpNum, SStream *O);
96static void printCoprocOptionImm(MCInst *MI, unsigned OpNum, SStream *O);
97static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
98static void printNEONModImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
99static void printImmPlusOneOperand(MCInst *MI, unsigned OpNum, SStream *O);
100static void printRotImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
101static void printGPRPairOperand(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *MRI);
102static void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O);
103static void printFBits16(MCInst *MI, unsigned OpNum, SStream *O);
104static void printFBits32(MCInst *MI, unsigned OpNum, SStream *O);
105static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O);
106static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O);
107static void printVectorListTwo(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *MRI);
108static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *RI);
109static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O);
110static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O);
111static void printVectorListOneAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
112static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *RI);
113static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
114static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
115static void printVectorListTwoSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O, MCRegisterInfo *MRI);
116static void printVectorListThreeSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
117static void printVectorListFourSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
118static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O);
119static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O);
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +0800120static void printBankedRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
121static void printModImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800122
123static void printInstSyncBOption(MCInst *MI, unsigned OpNum, SStream *O);
124
Nguyen Anh Quynh53a059b2015-06-08 21:51:19 +0800125#ifndef CAPSTONE_DIET
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800126// copy & normalize access info
127static uint8_t get_op_access(cs_struct *h, unsigned int id, unsigned int index)
128{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800129 uint8_t *arr = ARM_get_op_access(h, id);
130
131 if (arr[index] == CS_AC_IGNORE)
132 return 0;
133
134 return arr[index];
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800135}
Nguyen Anh Quynh53a059b2015-06-08 21:51:19 +0800136#endif
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800137
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800138static void set_mem_access(MCInst *MI, bool status)
139{
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800140 if (MI->csh->detail != CS_OPT_ON)
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800141 return;
142
Nguyen Anh Quynh19b0de32013-12-31 22:40:04 +0800143 MI->csh->doing_mem = status;
144 if (status) {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800145#ifndef CAPSTONE_DIET
146 uint8_t access;
147#endif
148
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700149 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
150 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = ARM_REG_INVALID;
151 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
152 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
153 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800154
155#ifndef CAPSTONE_DIET
156 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
157 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
158 MI->ac_idx++;
159#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800160 } else {
161 // done, create the next operand slot
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700162 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800163 }
164}
165
Nguyen Anh Quynhebe24432014-06-17 13:56:01 +0800166static void op_addImm(MCInst *MI, int v)
167{
Nguyen Anh Quynh73eb5d52014-06-17 18:08:29 +0800168 if (MI->csh->detail) {
169 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
170 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = v;
171 MI->flat_insn->detail->arm.op_count++;
172 }
Nguyen Anh Quynhebe24432014-06-17 13:56:01 +0800173}
174
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800175#define GET_INSTRINFO_ENUM
176#include "ARMGenInstrInfo.inc"
177
178//#define PRINT_ALIAS_INSTR
179#include "ARMGenAsmWriter.inc"
180
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800181void ARM_getRegName(cs_struct *handle, int value)
182{
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800183 if (value == CS_OPT_SYNTAX_NOREGNAME) {
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800184 handle->get_regname = getRegisterName2;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800185 handle->reg_name = ARM_reg_name2;;
186 } else {
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800187 handle->get_regname = getRegisterName;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800188 handle->reg_name = ARM_reg_name;;
189 }
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800190}
191
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800192/// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
193///
194/// getSORegOffset returns an integer from 0-31, representing '32' as 0.
195static unsigned translateShiftImm(unsigned imm)
196{
197 // lsr #32 and asr #32 exist, but should be encoded as a 0.
198 //assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
199 if (imm == 0)
200 return 32;
201 return imm;
202}
203
204/// Prints the shift value with an immediate value.
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +0700205static void printRegImmShift(MCInst *MI, SStream *O, ARM_AM_ShiftOpc ShOpc, unsigned ShImm)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800206{
207 if (ShOpc == ARM_AM_no_shift || (ShOpc == ARM_AM_lsl && !ShImm))
208 return;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700209 SStream_concat0(O, ", ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800210
211 //assert (!(ShOpc == ARM_AM_ror && !ShImm) && "Cannot have ror #0");
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700212 SStream_concat0(O, ARM_AM_getShiftOpcStr(ShOpc));
Nguyen Anh Quynhc70442e2014-06-01 11:35:34 +0700213 if (MI->csh->detail) {
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800214 if (MI->csh->doing_mem)
215 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (arm_shifter)ShOpc;
216 else
217 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 +0700218 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800219
220 if (ShOpc != ARM_AM_rrx) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700221 SStream_concat0(O, " ");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800222 SStream_concat(O, "#%u", translateShiftImm(ShImm));
Nguyen Anh Quynhc70442e2014-06-01 11:35:34 +0700223 if (MI->csh->detail) {
224 if (MI->csh->doing_mem)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700225 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 +0700226 else
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700227 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 +0700228 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800229 }
230}
231
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800232static void printRegName(cs_struct *h, SStream *OS, unsigned RegNo)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800233{
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800234#ifndef CAPSTONE_DIET
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700235 SStream_concat0(OS, h->get_regname(RegNo));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800236#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800237}
238
239static name_map insn_update_flgs[] = {
240 { ARM_INS_CMN, "cmn" },
241 { ARM_INS_CMP, "cmp" },
242 { ARM_INS_TEQ, "teq" },
243 { ARM_INS_TST, "tst" },
244
245 { ARM_INS_ADC, "adcs" },
246 { ARM_INS_ADD, "adds" },
247 { ARM_INS_AND, "ands" },
248 { ARM_INS_ASR, "asrs" },
249 { ARM_INS_BIC, "bics" },
250 { ARM_INS_EOR, "eors" },
251 { ARM_INS_LSL, "lsls" },
252 { ARM_INS_LSR, "lsrs" },
253 { ARM_INS_MLA, "mlas" },
254 { ARM_INS_MOV, "movs" },
255 { ARM_INS_MUL, "muls" },
256 { ARM_INS_MVN, "mvns" },
257 { ARM_INS_ORN, "orns" },
258 { ARM_INS_ORR, "orrs" },
259 { ARM_INS_ROR, "rors" },
260 { ARM_INS_RRX, "rrxs" },
261 { ARM_INS_RSB, "rsbs" },
262 { ARM_INS_RSC, "rscs" },
263 { ARM_INS_SBC, "sbcs" },
264 { ARM_INS_SMLAL, "smlals" },
265 { ARM_INS_SMULL, "smulls" },
266 { ARM_INS_SUB, "subs" },
267 { ARM_INS_UMLAL, "umlals" },
268 { ARM_INS_UMULL, "umulls" },
269};
270
Nguyen Anh Quynh64564812014-05-19 16:46:31 +0800271void ARM_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800272{
Nguyen Anh Quynh5ef633c2014-01-04 10:41:17 +0800273 if (((cs_struct *)ud)->detail != CS_OPT_ON)
274 return;
275
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800276 // check if this insn requests write-back
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800277 if (mci->writeback || (strrchr(insn_asm, '!')) != NULL) {
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800278 insn->detail->arm.writeback = true;
Nguyen Anh Quynh5719eb52015-01-21 12:16:15 +0800279 } else if (mci->csh->mode & CS_MODE_THUMB) {
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800280 // handle some special instructions with writeback
Nguyen Anh Quynh483e1012016-08-09 23:19:04 +0800281 //printf(">> Opcode = %u\n", mci->Opcode);
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800282 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
Nguyen Anh Quynh483e1012016-08-09 23:19:04 +0800333 //printf(">> Opcode = %u\n", mci->Opcode);
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800334 switch(mci->Opcode) {
335 default:
336 break;
337 case ARM_LDC2L_PRE:
338 case ARM_LDC2_PRE:
339 case ARM_LDCL_PRE:
340 case ARM_LDC_PRE:
341
342 case ARM_LDRD_PRE:
343 case ARM_LDRH_PRE:
344 case ARM_LDRSB_PRE:
345 case ARM_LDRSH_PRE:
346
347 case ARM_STC2L_PRE:
348 case ARM_STC2_PRE:
349 case ARM_STCL_PRE:
350 case ARM_STC_PRE:
351
352 case ARM_STRD_PRE:
353 case ARM_STRH_PRE:
354
355 case ARM_LDC2L_POST:
356 case ARM_LDC2_POST:
357 case ARM_LDCL_POST:
358 case ARM_LDC_POST:
359
360 case ARM_LDRBT_POST:
361 case ARM_LDRD_POST:
362 case ARM_LDRH_POST:
363 case ARM_LDRSB_POST:
364 case ARM_LDRSH_POST:
365
366 case ARM_STC2L_POST:
367 case ARM_STC2_POST:
368 case ARM_STCL_POST:
369 case ARM_STC_POST:
370
371 case ARM_STRBT_POST:
372 case ARM_STRD_POST:
373 case ARM_STRH_POST:
Nguyen Anh Quynh58fbf2f2015-01-21 12:25:36 +0800374
375 case ARM_LDRB_POST_IMM:
376 case ARM_LDR_POST_IMM:
Nguyen Anh Quynh483e1012016-08-09 23:19:04 +0800377 case ARM_LDR_POST_REG:
Nguyen Anh Quynh58fbf2f2015-01-21 12:25:36 +0800378 case ARM_STRB_POST_IMM:
379 case ARM_STR_POST_IMM:
380
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800381 insn->detail->arm.writeback = true;
382 break;
383 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800384 }
385
386 // check if this insn requests update flags
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800387 if (insn->detail->arm.update_flags == false) {
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800388 // some insn still update flags, regardless of tabgen info
Nguyen Anh Quynhf6c7cbc2014-03-12 12:50:54 +0800389 unsigned int i, j;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800390
391 for (i = 0; i < ARR_SIZE(insn_update_flgs); i++) {
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800392 if (insn->id == insn_update_flgs[i].id &&
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800393 !strncmp(insn_asm, insn_update_flgs[i].name,
394 strlen(insn_update_flgs[i].name))) {
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800395 insn->detail->arm.update_flags = true;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800396 // we have to update regs_write array as well
Nguyen Anh Quynh4fe224b2013-12-24 16:49:36 +0800397 for (j = 0; j < ARR_SIZE(insn->detail->regs_write); j++) {
398 if (insn->detail->regs_write[j] == 0) {
399 insn->detail->regs_write[j] = ARM_REG_CPSR;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800400 break;
401 }
402 }
403 break;
404 }
405 }
406 }
Nguyen Anh Quynh48b6cb42014-06-01 09:45:19 +0700407
408 // instruction should not have invalid CC
409 if (insn->detail->arm.cc == ARM_CC_INVALID) {
410 insn->detail->arm.cc = ARM_CC_AL;
411 }
412
Nguyen Anh Quynh6eb55cf2014-06-01 10:03:14 +0700413 // manual fix for some special instructions
414 // printf(">>> id: %u, mcid: %u\n", insn->id, mci->Opcode);
415 switch(mci->Opcode) {
416 default:
417 break;
418 case ARM_MOVPCLR:
419 insn->detail->arm.operands[0].type = ARM_OP_REG;
420 insn->detail->arm.operands[0].reg = ARM_REG_PC;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800421 insn->detail->arm.operands[0].access = CS_AC_READ;
Nguyen Anh Quynh6eb55cf2014-06-01 10:03:14 +0700422 insn->detail->arm.operands[1].type = ARM_OP_REG;
423 insn->detail->arm.operands[1].reg = ARM_REG_LR;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800424 insn->detail->arm.operands[1].access = CS_AC_WRITE;
Nguyen Anh Quynh6eb55cf2014-06-01 10:03:14 +0700425 insn->detail->arm.op_count = 2;
426 break;
427 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800428}
429
430void ARM_printInst(MCInst *MI, SStream *O, void *Info)
431{
432 MCRegisterInfo *MRI = (MCRegisterInfo *)Info;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800433 unsigned Opcode = MCInst_getOpcode(MI), tmp, i, pubOpcode;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800434
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800435
Nguyen Anh Quynh91a1cb42015-05-02 11:38:34 +0800436 // printf(">>> Opcode 0: %u\n", MCInst_getOpcode(MI));
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800437 switch(Opcode) {
438 // Check for HINT instructions w/ canonical names.
439 case ARM_HINT:
440 case ARM_tHINT:
441 case ARM_t2HINT:
442 switch (MCOperand_getImm(MCInst_getOperand(MI, 0))) {
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800443 case 0: SStream_concat0(O, "nop"); pubOpcode = ARM_INS_NOP; break;
444 case 1: SStream_concat0(O, "yield"); pubOpcode = ARM_INS_YIELD; break;
445 case 2: SStream_concat0(O, "wfe"); pubOpcode = ARM_INS_WFE; break;
446 case 3: SStream_concat0(O, "wfi"); pubOpcode = ARM_INS_WFI; break;
447 case 4: SStream_concat0(O, "sev"); pubOpcode = ARM_INS_SEV; break;
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800448 case 5:
Nguyen Anh Quynh2593e222014-11-10 16:35:38 +0800449 if ((ARM_getFeatureBits(MI->csh->mode) & ARM_HasV8Ops)) {
450 SStream_concat0(O, "sevl");
451 pubOpcode = ARM_INS_SEVL;
452 break;
453 }
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800454 // Fallthrough for non-v8
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800455 default:
456 // Anything else should just print normally.
457 printInstruction(MI, O, MRI);
458 return;
459 }
460 printPredicateOperand(MI, 1, O);
461 if (Opcode == ARM_t2HINT)
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800462 SStream_concat0(O, ".w");
463
464 MCInst_setOpcodePub(MI, pubOpcode);
465
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800466 return;
467
468 // Check for MOVs and print canonical forms, instead.
469 case ARM_MOVsr: {
470 // FIXME: Thumb variants?
Nguyen Anh Quynh52a6b8b2015-05-02 11:46:53 +0800471 unsigned int opc;
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800472 MCOperand *Dst = MCInst_getOperand(MI, 0);
473 MCOperand *MO1 = MCInst_getOperand(MI, 1);
474 MCOperand *MO2 = MCInst_getOperand(MI, 2);
475 MCOperand *MO3 = MCInst_getOperand(MI, 3);
476
Nguyen Anh Quynh52a6b8b2015-05-02 11:46:53 +0800477 opc = ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO3));
478 SStream_concat0(O, ARM_AM_getShiftOpcStr(opc));
479 switch(opc) {
480 default:
481 break;
482 case ARM_AM_asr:
483 MCInst_setOpcodePub(MI, ARM_INS_ASR);
484 break;
485 case ARM_AM_lsl:
486 MCInst_setOpcodePub(MI, ARM_INS_LSL);
487 break;
488 case ARM_AM_lsr:
489 MCInst_setOpcodePub(MI, ARM_INS_LSR);
490 break;
491 case ARM_AM_ror:
492 MCInst_setOpcodePub(MI, ARM_INS_ROR);
493 break;
494 case ARM_AM_rrx:
495 MCInst_setOpcodePub(MI, ARM_INS_RRX);
496 break;
497 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800498 printSBitModifierOperand(MI, 6, O);
499 printPredicateOperand(MI, 4, O);
500
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700501 SStream_concat0(O, "\t");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800502 printRegName(MI->csh, O, MCOperand_getReg(Dst));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800503 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700504 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
505 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 +0800506 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 +0700507 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800508 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800509
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700510 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800511 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800512
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800513 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700514 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
515 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 +0800516 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 +0700517 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800518 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800519
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700520 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800521 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800522 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700523 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
524 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 +0800525 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 +0700526 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800527 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800528 //assert(ARM_AM_getSORegOffset(MO3.getImm()) == 0);
529 return;
530 }
531
532 case ARM_MOVsi: {
533 // FIXME: Thumb variants?
Nguyen Anh Quynh91a1cb42015-05-02 11:38:34 +0800534 unsigned int opc;
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800535 MCOperand *Dst = MCInst_getOperand(MI, 0);
536 MCOperand *MO1 = MCInst_getOperand(MI, 1);
537 MCOperand *MO2 = MCInst_getOperand(MI, 2);
538
Nguyen Anh Quynh91a1cb42015-05-02 11:38:34 +0800539 opc = ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2));
540 SStream_concat0(O, ARM_AM_getShiftOpcStr(opc));
541 switch(opc) {
542 default:
543 break;
544 case ARM_AM_asr:
545 MCInst_setOpcodePub(MI, ARM_INS_ASR);
546 break;
547 case ARM_AM_lsl:
548 MCInst_setOpcodePub(MI, ARM_INS_LSL);
549 break;
550 case ARM_AM_lsr:
551 MCInst_setOpcodePub(MI, ARM_INS_LSR);
552 break;
553 case ARM_AM_ror:
554 MCInst_setOpcodePub(MI, ARM_INS_ROR);
555 break;
556 case ARM_AM_rrx:
557 MCInst_setOpcodePub(MI, ARM_INS_RRX);
558 break;
559 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800560 printSBitModifierOperand(MI, 5, O);
561 printPredicateOperand(MI, 3, O);
562
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700563 SStream_concat0(O, "\t");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800564 printRegName(MI->csh, O, MCOperand_getReg(Dst));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800565 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700566 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
567 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 +0800568 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 +0700569 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800570 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800571
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700572 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800573 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800574 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700575 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
576 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 +0800577 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 +0700578 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800579 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800580
Nguyen Anh Quynh52a6b8b2015-05-02 11:46:53 +0800581 if (opc == ARM_AM_rrx) {
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800582 //printAnnotation(O, Annot);
583 return;
584 }
585
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700586 SStream_concat0(O, ", ");
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100587 tmp = translateShiftImm(getSORegOffset((unsigned int)MCOperand_getImm(MO2)));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800588 if (tmp > HEX_THRESHOLD)
589 SStream_concat(O, "#0x%x", tmp);
590 else
591 SStream_concat(O, "#%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800592 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700593 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type =
Nguyen Anh Quynh52a6b8b2015-05-02 11:46:53 +0800594 (arm_shifter)opc;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700595 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 +0800596 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800597 return;
598 }
599
600 // A8.6.123 PUSH
601 case ARM_STMDB_UPD:
602 case ARM_t2STMDB_UPD:
603 if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP &&
604 MCInst_getNumOperands(MI) > 5) {
605 // Should only print PUSH if there are at least two registers in the list.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700606 SStream_concat0(O, "push");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800607 MCInst_setOpcodePub(MI, ARM_INS_PUSH);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800608 printPredicateOperand(MI, 2, O);
609 if (Opcode == ARM_t2STMDB_UPD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700610 SStream_concat0(O, ".w");
611 SStream_concat0(O, "\t");
Nguyen Anh Quynhba829772016-08-15 20:00:40 +0800612
613 if (MI->csh->detail) {
614 MI->flat_insn->detail->regs_read[MI->flat_insn->detail->regs_read_count] = ARM_REG_SP;
615 MI->flat_insn->detail->regs_read_count++;
616 MI->flat_insn->detail->regs_write[MI->flat_insn->detail->regs_write_count] = ARM_REG_SP;
617 MI->flat_insn->detail->regs_write_count++;
618 }
619
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800620 printRegisterList(MI, 4, O);
621 return;
622 }
623 break;
624
625 case ARM_STR_PRE_IMM:
626 if (MCOperand_getReg(MCInst_getOperand(MI, 2)) == ARM_SP &&
627 MCOperand_getImm(MCInst_getOperand(MI, 3)) == -4) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700628 SStream_concat0(O, "push");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800629 MCInst_setOpcodePub(MI, ARM_INS_PUSH);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800630 printPredicateOperand(MI, 4, O);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700631 SStream_concat0(O, "\t{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800632 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 1)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800633 if (MI->csh->detail) {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800634#ifndef CAPSTONE_DIET
635 uint8_t access;
636#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700637 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
638 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 +0800639#ifndef CAPSTONE_DIET
640 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
641 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
642 MI->ac_idx++;
643#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700644 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800645 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700646 SStream_concat0(O, "}");
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800647 return;
648 }
649 break;
650
651 // A8.6.122 POP
652 case ARM_LDMIA_UPD:
653 case ARM_t2LDMIA_UPD:
654 if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP &&
655 MCInst_getNumOperands(MI) > 5) {
656 // Should only print POP if there are at least two registers in the list.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700657 SStream_concat0(O, "pop");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800658 MCInst_setOpcodePub(MI, ARM_INS_POP);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800659 printPredicateOperand(MI, 2, O);
660 if (Opcode == ARM_t2LDMIA_UPD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700661 SStream_concat0(O, ".w");
662 SStream_concat0(O, "\t");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800663 if (MI->csh->detail) {
664 MI->flat_insn->detail->regs_read[MI->flat_insn->detail->regs_read_count] = ARM_REG_SP;
665 MI->flat_insn->detail->regs_read_count++;
666 MI->flat_insn->detail->regs_write[MI->flat_insn->detail->regs_write_count] = ARM_REG_SP;
667 MI->flat_insn->detail->regs_write_count++;
668 }
669
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800670 printRegisterList(MI, 4, O);
671 return;
672 }
673 break;
674
675 case ARM_LDR_POST_IMM:
Nguyen Anh Quynh3caf8372014-11-27 14:34:40 +0800676 if (MCOperand_getReg(MCInst_getOperand(MI, 2)) == ARM_SP) {
677 MCOperand *MO2 = MCInst_getOperand(MI, 4);
678 if ((getAM2Op((unsigned int)MCOperand_getImm(MO2)) == ARM_AM_add &&
679 getAM2Offset((unsigned int)MCOperand_getImm(MO2)) == 4) ||
680 MCOperand_getImm(MO2) == 4) {
681 SStream_concat0(O, "pop");
682 MCInst_setOpcodePub(MI, ARM_INS_POP);
683 printPredicateOperand(MI, 5, O);
684 SStream_concat0(O, "\t{");
685 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 0)));
686 if (MI->csh->detail) {
687 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 = MCOperand_getReg(MCInst_getOperand(MI, 0));
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 Quynh3caf8372014-11-27 14:34:40 +0800690 MI->flat_insn->detail->arm.op_count++;
691 }
692 SStream_concat0(O, "}");
693 return;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800694 }
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800695 }
696 break;
697
698 // A8.6.355 VPUSH
699 case ARM_VSTMSDB_UPD:
700 case ARM_VSTMDDB_UPD:
701 if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700702 SStream_concat0(O, "vpush");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800703 MCInst_setOpcodePub(MI, ARM_INS_VPUSH);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800704 printPredicateOperand(MI, 2, O);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700705 SStream_concat0(O, "\t");
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800706 printRegisterList(MI, 4, O);
707 return;
708 }
709 break;
710
711 // A8.6.354 VPOP
712 case ARM_VLDMSIA_UPD:
713 case ARM_VLDMDIA_UPD:
714 if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700715 SStream_concat0(O, "vpop");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800716 MCInst_setOpcodePub(MI, ARM_INS_VPOP);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800717 printPredicateOperand(MI, 2, O);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700718 SStream_concat0(O, "\t");
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800719 printRegisterList(MI, 4, O);
720 return;
721 }
722 break;
723
724 case ARM_tLDMIA: {
Nguyen Anh Quynh8cdafda2014-11-11 22:30:30 +0800725 bool Writeback = true;
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800726 unsigned BaseReg = MCOperand_getReg(MCInst_getOperand(MI, 0));
727 unsigned i;
728 for (i = 3; i < MCInst_getNumOperands(MI); ++i) {
729 if (MCOperand_getReg(MCInst_getOperand(MI, i)) == BaseReg)
730 Writeback = false;
731 }
732
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700733 SStream_concat0(O, "ldm");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +0800734 MCInst_setOpcodePub(MI, ARM_INS_LDM);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800735
736 printPredicateOperand(MI, 1, O);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700737 SStream_concat0(O, "\t");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800738 printRegName(MI->csh, O, BaseReg);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800739 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700740 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
741 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = BaseReg;
Nguyen Anh Quynh8e7f1d02016-08-17 16:19:21 +0800742 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ | CS_AC_WRITE;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700743 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800744 }
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800745 if (Writeback) {
746 MI->writeback = true;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700747 SStream_concat0(O, "!");
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +0800748 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700749 SStream_concat0(O, ", ");
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800750 printRegisterList(MI, 3, O);
751 return;
752 }
753
754 // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
755 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
756 // a single GPRPair reg operand is used in the .td file to replace the two
757 // GPRs. However, when decoding them, the two GRPs cannot be automatically
758 // expressed as a GPRPair, so we have to manually merge them.
759 // FIXME: We would really like to be able to tablegen'erate this.
760 case ARM_LDREXD:
761 case ARM_STREXD:
762 case ARM_LDAEXD:
763 case ARM_STLEXD: {
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800764 MCRegisterClass* MRC = MCRegisterInfo_getRegClass(MRI, ARM_GPRRegClassID);
765 bool isStore = Opcode == ARM_STREXD || Opcode == ARM_STLEXD;
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800766 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, isStore ? 1 : 0));
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +0800767
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800768 if (MCRegisterClass_contains(MRC, Reg)) {
769 MCInst NewMI;
Nguyen Anh Quynh5e2e6602014-05-30 17:43:36 +0800770
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800771 MCInst_Init(&NewMI);
772 MCInst_setOpcode(&NewMI, Opcode);
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800773
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800774 if (isStore)
775 MCInst_addOperand2(&NewMI, MCInst_getOperand(MI, 0));
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800776
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800777 MCOperand_CreateReg0(&NewMI, MCRegisterInfo_getMatchingSuperReg(MRI, Reg, ARM_gsub_0,
778 MCRegisterInfo_getRegClass(MRI, ARM_GPRPairRegClassID)));
Nguyen Anh Quynh96787052014-06-10 13:59:55 +0700779
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800780 // Copy the rest operands into NewMI.
781 for(i = isStore ? 3 : 2; i < MCInst_getNumOperands(MI); ++i)
782 MCInst_addOperand2(&NewMI, MCInst_getOperand(MI, i));
Nguyen Anh Quynh96787052014-06-10 13:59:55 +0700783
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800784 printInstruction(&NewMI, O, MRI);
785 return;
Nguyen Anh Quynh173ed2b2013-12-01 22:19:27 +0800786 }
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +0800787 break;
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800788 }
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +0800789 // B9.3.3 ERET (Thumb)
790 // For a target that has Virtualization Extensions, ERET is the preferred
791 // disassembly of SUBS PC, LR, #0
792 case ARM_t2SUBS_PC_LR: {
793 MCOperand *opc = MCInst_getOperand(MI, 0);
794 if (MCInst_getNumOperands(MI) == 3 &&
795 MCOperand_isImm(opc) &&
796 MCOperand_getImm(opc) == 0 &&
797 (ARM_getFeatureBits(MI->csh->mode) & ARM_FeatureVirtualization)) {
798 SStream_concat0(O, "eret");
799 MCInst_setOpcodePub(MI, ARM_INS_ERET);
800 printPredicateOperand(MI, 1, O);
801 return;
802 }
803 break;
804 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800805 }
806
807 //if (printAliasInstr(MI, O, MRI))
808 // printInstruction(MI, O, MRI);
809 printInstruction(MI, O, MRI);
810}
811
812static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
813{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800814 int32_t imm;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800815 MCOperand *Op = MCInst_getOperand(MI, OpNo);
816 if (MCOperand_isReg(Op)) {
817 unsigned Reg = MCOperand_getReg(Op);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800818 printRegName(MI->csh, O, Reg);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800819 if (MI->csh->detail) {
Nguyen Anh Quynh19b0de32013-12-31 22:40:04 +0800820 if (MI->csh->doing_mem) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700821 if (MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base == ARM_REG_INVALID)
822 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = Reg;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800823 else
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700824 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = Reg;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800825 } else {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800826#ifndef CAPSTONE_DIET
827 uint8_t access;
828#endif
829
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700830 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
831 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800832#ifndef CAPSTONE_DIET
833 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
834 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
835 MI->ac_idx++;
836#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700837 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800838 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800839 }
840 } else if (MCOperand_isImm(Op)) {
Nguyen Anh Quynh0c235e12014-07-31 21:16:54 +0800841 unsigned int opc = MCInst_getOpcode(MI);
flyingsymbols298d4132014-06-30 01:45:40 -0400842
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100843 imm = (int32_t)MCOperand_getImm(Op);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800844
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800845 // relative branch only has relative offset, so we have to update it
846 // to reflect absolute address.
847 // Note: in ARM, PC is always 2 instructions ahead, so we have to
848 // add 8 in ARM mode, or 4 in Thumb mode
Nguyen Anh Quynhbc80b3d2014-05-09 17:31:41 +0800849 // printf(">> opcode: %u\n", MCInst_getOpcode(MI));
flyingsymbols298d4132014-06-30 01:45:40 -0400850 if (ARM_rel_branch(MI->csh, opc)) {
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800851 // only do this for relative branch
flyingsymbols298d4132014-06-30 01:45:40 -0400852 if (MI->csh->mode & CS_MODE_THUMB) {
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800853 imm += (int32_t)MI->address + 4;
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800854 if (ARM_blx_to_arm_mode(MI->csh, opc)) {
Nguyen Anh Quynh0c235e12014-07-31 21:16:54 +0800855 // here need to align down to the nearest 4-byte address
reyalpchdk8b12b712016-01-16 21:32:09 -0800856 imm &= ~3;
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800857 }
858 } else {
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800859 imm += (int32_t)MI->address + 8;
Nguyen Anh Quynh26dfbc62014-07-31 18:24:51 +0800860 }
Nguyen Anh Quynh79e1dcb2014-05-07 14:12:50 +0800861
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +0800862 printUInt32Bang(O, imm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +0800863 } else {
Nguyen Anh Quynh278e7272014-11-11 12:50:43 +0800864 switch(MI->flat_insn->id) {
865 default:
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +0800866 if (MI->csh->imm_unsigned)
867 printUInt32Bang(O, imm);
868 else
869 printInt32Bang(O, imm);
Nguyen Anh Quynh278e7272014-11-11 12:50:43 +0800870 break;
871 case ARM_INS_AND:
872 case ARM_INS_ORR:
873 case ARM_INS_EOR:
874 case ARM_INS_BIC:
Nguyen Anh Quynha2934a72014-11-25 21:02:18 +0800875 case ARM_INS_MVN:
Nguyen Anh Quynh278e7272014-11-11 12:50:43 +0800876 // do not print number in negative form
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +0800877 printUInt32Bang(O, imm);
Nguyen Anh Quynh278e7272014-11-11 12:50:43 +0800878 break;
879 }
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +0800880 }
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +0800881
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800882 if (MI->csh->detail) {
Nguyen Anh Quynh19b0de32013-12-31 22:40:04 +0800883 if (MI->csh->doing_mem)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700884 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = imm;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800885 else {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700886 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
887 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
888 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800889 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800890 }
891 }
892}
893
894static void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O)
895{
896 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +0800897 int32_t OffImm;
Nguyen Anh Quynh42706a32014-05-09 07:33:35 +0800898 bool isSub;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700899 SStream_concat0(O, "[pc, ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800900
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100901 OffImm = (int32_t)MCOperand_getImm(MO1);
902 isSub = OffImm < 0;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800903
904 // Special value for #-0. All others are normal.
905 if (OffImm == INT32_MIN)
906 OffImm = 0;
907 if (isSub) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700908 SStream_concat(O, "#-0x%x", -OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800909 } else {
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +0800910 printUInt32Bang(O, OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800911 }
912
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700913 SStream_concat0(O, "]");
Nguyen Anh Quynhbb71c132014-06-01 10:14:31 +0700914
915 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700916 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
917 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = ARM_REG_PC;
918 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
919 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
920 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +0800921 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 +0700922 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynhbb71c132014-06-01 10:14:31 +0700923 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800924}
925
926// so_reg is a 4-operand unit corresponding to register forms of the A5.1
927// "Addressing Mode 1 - Data-processing operands" forms. This includes:
928// REG 0 0 - e.g. R5
929// REG REG 0,SH_OPC - e.g. R5, ROR R3
930// REG 0 IMM,SH_OPC - e.g. R5, LSL #3
931static void printSORegRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
932{
933 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
934 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
935 MCOperand *MO3 = MCInst_getOperand(MI, OpNum+2);
Nguyen Anh Quynh42706a32014-05-09 07:33:35 +0800936 ARM_AM_ShiftOpc ShOpc;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800937
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800938 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800939
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800940 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700941 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
942 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 +0800943 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 +0800944
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700945 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (MCOperand_getImm(MO3) & 7) + ARM_SFT_ASR_REG - 1;
946 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800947 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800948
949 // Print the shift opc.
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +0100950 ShOpc = ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700951 SStream_concat0(O, ", ");
952 SStream_concat0(O, ARM_AM_getShiftOpcStr(ShOpc));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800953 if (ShOpc == ARM_AM_rrx)
954 return;
955
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700956 SStream_concat0(O, " ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800957 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800958 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700959 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 +0800960 //assert(ARM_AM_getSORegOffset(MO3.getImm()) == 0);
961}
962
963static void printSORegImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
964{
965 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
966 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
967
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800968 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800969 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700970 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
971 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 +0800972 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 +0700973 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = MCOperand_getImm(MO2) & 7;
974 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = (unsigned int)MCOperand_getImm(MO2) >> 3;
975 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800976 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800977
978 // Print the shift opc.
Alex Ionescu46018db2014-01-22 09:45:00 -0800979 printRegImmShift(MI, O, ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2)),
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +0700980 getSORegOffset((unsigned int)MCOperand_getImm(MO2)));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800981}
982
983//===--------------------------------------------------------------------===//
984// Addressing Mode #2
985//===--------------------------------------------------------------------===//
986
987static void printAM2PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O)
988{
989 MCOperand *MO1 = MCInst_getOperand(MI, Op);
990 MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
991 MCOperand *MO3 = MCInst_getOperand(MI, Op + 2);
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +0800992 ARM_AM_AddrOpc subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800993
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +0700994 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800995 set_mem_access(MI, true);
996
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +0800997 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800998 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +0700999 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 +08001000 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001001
1002 if (!MCOperand_getReg(MO2)) {
Alex Ionescu46018db2014-01-22 09:45:00 -08001003 unsigned tmp = getAM2Offset((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001004 if (tmp) { // Don't print +0.
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001005 subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO3));
1006
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001007 SStream_concat0(O, ", ");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001008 if (tmp > HEX_THRESHOLD)
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001009 SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(subtracted), tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001010 else
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001011 SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(subtracted), tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001012 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001013 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (arm_shifter)getAM2Op((unsigned int)MCOperand_getImm(MO3));
1014 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = tmp;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001015 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 +08001016 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001017 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001018 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001019 set_mem_access(MI, false);
1020 return;
1021 }
1022
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001023 SStream_concat0(O, ", ");
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001024 SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001025 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001026 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001027 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 +08001028 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 +08001029 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001030
Alex Ionescu46018db2014-01-22 09:45:00 -08001031 printRegImmShift(MI, O, getAM2ShiftOpc((unsigned int)MCOperand_getImm(MO3)),
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +07001032 getAM2Offset((unsigned int)MCOperand_getImm(MO3)));
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001033 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001034 set_mem_access(MI, false);
1035}
1036
1037static void printAddrModeTBB(MCInst *MI, unsigned Op, SStream *O)
1038{
1039 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1040 MCOperand *MO2 = MCInst_getOperand(MI, Op+1);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001041 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001042 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001043 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001044 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001045 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 +07001046 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001047 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001048 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001049 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 +07001050 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001051 set_mem_access(MI, false);
1052}
1053
1054static void printAddrModeTBH(MCInst *MI, unsigned Op, SStream *O)
1055{
1056 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1057 MCOperand *MO2 = MCInst_getOperand(MI, Op+1);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001058 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001059 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001060 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001061 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001062 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 +07001063 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001064 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001065 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001066 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 +07001067 SStream_concat0(O, ", lsl #1]");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001068 if (MI->csh->detail) {
Nguyen Anh Quynh706b8082015-01-12 15:27:29 +08001069 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.lshift = 1;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001070 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001071 set_mem_access(MI, false);
1072}
1073
1074static void printAddrMode2Operand(MCInst *MI, unsigned Op, SStream *O)
1075{
1076 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1077
1078 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
1079 printOperand(MI, Op, O);
1080 return;
1081 }
1082
1083 printAM2PreOrOffsetIndexOp(MI, Op, O);
1084}
1085
1086static void printAddrMode2OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
1087{
1088 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1089 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001090 ARM_AM_AddrOpc subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001091
1092 if (!MCOperand_getReg(MO1)) {
Alex Ionescu46018db2014-01-22 09:45:00 -08001093 unsigned ImmOffs = getAM2Offset((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001094 if (ImmOffs > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001095 SStream_concat(O, "#%s0x%x",
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001096 ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001097 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001098 SStream_concat(O, "#%s%u",
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001099 ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001100 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001101 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1102 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = ImmOffs;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001103 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 +07001104 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001105 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001106 return;
1107 }
1108
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001109 SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001110 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001111 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001112 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1113 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 +08001114 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 +08001115 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 +07001116 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001117 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001118
Alex Ionescu46018db2014-01-22 09:45:00 -08001119 printRegImmShift(MI, O, getAM2ShiftOpc((unsigned int)MCOperand_getImm(MO2)),
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +07001120 getAM2Offset((unsigned int)MCOperand_getImm(MO2)));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001121}
1122
1123//===--------------------------------------------------------------------===//
1124// Addressing Mode #3
1125//===--------------------------------------------------------------------===//
1126
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001127static void printAM3PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O,
1128 bool AlwaysPrintImm0)
1129{
1130 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1131 MCOperand *MO2 = MCInst_getOperand(MI, Op+1);
1132 MCOperand *MO3 = MCInst_getOperand(MI, Op+2);
Nguyen Anh Quynhed43e242015-08-15 14:16:39 +08001133 ARM_AM_AddrOpc sign = getAM3Op((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001134 unsigned ImmOffs;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001135
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001136 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001137 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001138 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001139 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001140 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 +08001141
1142 if (MCOperand_getReg(MO2)) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001143 SStream_concat0(O, ", ");
Nguyen Anh Quynhed43e242015-08-15 14:16:39 +08001144 SStream_concat0(O, ARM_AM_getAddrOpcStr(sign));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001145 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001146 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001147 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
Nguyen Anh Quynhed43e242015-08-15 14:16:39 +08001148 if (!sign) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001149 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = -1;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001150 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
1151 }
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001152 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001153 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001154 set_mem_access(MI, false);
1155 return;
1156 }
1157
1158 //If the op is sub we have to print the immediate even if it is 0
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001159 ImmOffs = getAM3Offset((unsigned int)MCOperand_getImm(MO3));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001160
Nguyen Anh Quynhed43e242015-08-15 14:16:39 +08001161 if (AlwaysPrintImm0 || ImmOffs || (sign == ARM_AM_sub)) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001162 if (ImmOffs > HEX_THRESHOLD)
Nguyen Anh Quynhed43e242015-08-15 14:16:39 +08001163 SStream_concat(O, ", #%s0x%x", ARM_AM_getAddrOpcStr(sign), ImmOffs);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001164 else
Nguyen Anh Quynhed43e242015-08-15 14:16:39 +08001165 SStream_concat(O, ", #%s%u", ARM_AM_getAddrOpcStr(sign), ImmOffs);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001166 }
Nguyen Anh Quynh6677b992013-12-08 22:20:35 +08001167
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001168 if (MI->csh->detail) {
Nguyen Anh Quynhed43e242015-08-15 14:16:39 +08001169 if (!sign) {
Nguyen Anh Quynhddf54882015-08-19 22:36:09 +08001170 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 +08001171 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
1172 } else
Nguyen Anh Quynhddf54882015-08-19 22:36:09 +08001173 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 +08001174 }
Nguyen Anh Quynh6677b992013-12-08 22:20:35 +08001175
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001176 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001177 set_mem_access(MI, false);
1178}
1179
1180static void printAddrMode3Operand(MCInst *MI, unsigned Op, SStream *O,
1181 bool AlwaysPrintImm0)
1182{
1183 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1184 if (!MCOperand_isReg(MO1)) { // For label symbolic references.
1185 printOperand(MI, Op, O);
1186 return;
1187 }
1188
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001189 printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
1190}
1191
1192static void printAddrMode3OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
1193{
1194 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1195 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001196 ARM_AM_AddrOpc subtracted = getAM3Op((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001197 unsigned ImmOffs;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001198
1199 if (MCOperand_getReg(MO1)) {
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001200 SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001201 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001202 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001203 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 +08001204 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 +08001205 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 +08001206 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 +07001207 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001208 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001209 return;
1210 }
1211
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001212 ImmOffs = getAM3Offset((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001213 if (ImmOffs > HEX_THRESHOLD)
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001214 SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001215 else
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001216 SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001217 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001218 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 +08001219
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001220 if (subtracted) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001221 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = ImmOffs;
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001222 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
1223 } else
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001224 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = -(int)ImmOffs;
Nguyen Anh Quynh6677b992013-12-08 22:20:35 +08001225
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001226 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001227 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001228}
1229
1230static void printPostIdxImm8Operand(MCInst *MI, unsigned OpNum, SStream *O)
1231{
1232 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Alex Ionescu46018db2014-01-22 09:45:00 -08001233 unsigned Imm = (unsigned int)MCOperand_getImm(MO);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001234 if ((Imm & 0xff) > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001235 SStream_concat(O, "#%s0x%x", ((Imm & 256) ? "" : "-"), (Imm & 0xff));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001236 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001237 SStream_concat(O, "#%s%u", ((Imm & 256) ? "" : "-"), (Imm & 0xff));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001238 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001239 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1240 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Imm & 0xff;
1241 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001242 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001243}
1244
1245static void printPostIdxRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
1246{
1247 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1248 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
1249
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001250 SStream_concat0(O, (MCOperand_getImm(MO2) ? "" : "-"));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001251 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001252 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001253 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1254 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 +08001255 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 +07001256 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001257 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001258}
1259
1260static void printPostIdxImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O)
1261{
1262 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Alex Ionescu46018db2014-01-22 09:45:00 -08001263 unsigned Imm = (unsigned int)MCOperand_getImm(MO);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001264 if (((Imm & 0xff) << 2) > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001265 SStream_concat(O, "#%s0x%x", ((Imm & 256) ? "" : "-"), ((Imm & 0xff) << 2));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001266 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001267 SStream_concat(O, "#%s%u", ((Imm & 256) ? "" : "-"), ((Imm & 0xff) << 2));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001268}
1269
1270static void printAddrMode5Operand(MCInst *MI, unsigned OpNum, SStream *O,
1271 bool AlwaysPrintImm0)
1272{
Nguyen Anh Quynh6acaaa52014-11-10 17:41:05 +08001273 unsigned ImmOffs;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001274 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1275 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynh6acaaa52014-11-10 17:41:05 +08001276 ARM_AM_AddrOpc subtracted = ARM_AM_getAM5Op((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001277
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001278 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
1279 printOperand(MI, OpNum, O);
1280 return;
1281 }
1282
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001283 SStream_concat0(O, "[");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001284 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001285
Nguyen Anh Quynhb79d9152014-06-01 10:48:55 +07001286 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001287 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
1288 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
1289 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
1290 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
1291 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001292 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 +07001293 }
1294
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001295 ImmOffs = ARM_AM_getAM5Offset((unsigned int)MCOperand_getImm(MO2));
Nguyen Anh Quynh6acaaa52014-11-10 17:41:05 +08001296 if (AlwaysPrintImm0 || ImmOffs || subtracted == ARM_AM_sub) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001297 if (ImmOffs * 4 > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001298 SStream_concat(O, ", #%s0x%x",
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001299 ARM_AM_getAddrOpcStr(subtracted),
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001300 ImmOffs * 4);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001301 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001302 SStream_concat(O, ", #%s%u",
Nguyen Anh Quynh8fb2eab2014-10-06 20:27:25 +08001303 ARM_AM_getAddrOpcStr(subtracted),
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001304 ImmOffs * 4);
Nguyen Anh Quynha04ee4f2014-06-01 10:52:01 +07001305 if (MI->csh->detail) {
Nguyen Anh Quynh6acaaa52014-11-10 17:41:05 +08001306 if (subtracted)
1307 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = ImmOffs * 4;
1308 else
Nguyen Anh Quynh51888c32014-11-11 23:59:23 +08001309 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 +07001310 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001311 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001312 SStream_concat0(O, "]");
Nguyen Anh Quynhb79d9152014-06-01 10:48:55 +07001313
1314 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001315 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynhb79d9152014-06-01 10:48:55 +07001316 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001317}
1318
1319static void printAddrMode6Operand(MCInst *MI, unsigned OpNum, SStream *O)
1320{
1321 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
1322 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001323 unsigned tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001324
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001325 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001326 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001327 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001328 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001329 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 +01001330 tmp = (unsigned int)MCOperand_getImm(MO2);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001331 if (tmp) {
1332 if (tmp << 3 > HEX_THRESHOLD)
1333 SStream_concat(O, ":0x%x", (tmp << 3));
1334 else
1335 SStream_concat(O, ":%u", (tmp << 3));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001336 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001337 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 +08001338 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001339 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001340 set_mem_access(MI, false);
1341}
1342
1343static void printAddrMode7Operand(MCInst *MI, unsigned OpNum, SStream *O)
1344{
1345 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001346 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001347 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001348 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001349 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001350 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 +07001351 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001352 set_mem_access(MI, false);
1353}
1354
1355static void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
1356{
1357 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +08001358 if (MCOperand_getReg(MO) == 0) {
1359 MI->writeback = true;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001360 SStream_concat0(O, "!");
Nguyen Anh Quynh03e5e102015-01-21 12:15:14 +08001361 } else {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001362 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001363 printRegName(MI->csh, O, MCOperand_getReg(MO));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001364 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001365 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1366 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 +08001367 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 +07001368 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001369 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001370 }
1371}
1372
1373static void printBitfieldInvMaskImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1374{
1375 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Alex Ionescu46018db2014-01-22 09:45:00 -08001376 uint32_t v = ~(uint32_t)MCOperand_getImm(MO);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001377 int32_t lsb = CountTrailingZeros_32(v);
1378 int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001379
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001380 //assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +08001381 printUInt32Bang(O, lsb);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001382
1383 if (width > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001384 SStream_concat(O, ", #0x%x", width);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001385 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001386 SStream_concat(O, ", #%u", width);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001387
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001388 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001389 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1390 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = lsb;
1391 MI->flat_insn->detail->arm.op_count++;
1392 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1393 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = width;
1394 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001395 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001396}
1397
1398static void printMemBOption(MCInst *MI, unsigned OpNum, SStream *O)
1399{
Alex Ionescu46018db2014-01-22 09:45:00 -08001400 unsigned val = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh8cdafda2014-11-11 22:30:30 +08001401 SStream_concat0(O, ARM_MB_MemBOptToString(val + 1,
Nguyen Anh Quynh106e0f12015-05-24 21:33:17 +08001402 (ARM_getFeatureBits(MI->csh->mode) & ARM_HasV8Ops) != 0));
Nguyen Anh Quynh8cdafda2014-11-11 22:30:30 +08001403
1404 if (MI->csh->detail) {
Nguyen Anh Quynh51888c32014-11-11 23:59:23 +08001405 MI->flat_insn->detail->arm.mem_barrier = (arm_mem_barrier)(val + 1);
Nguyen Anh Quynh8cdafda2014-11-11 22:30:30 +08001406 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001407}
1408
1409void printInstSyncBOption(MCInst *MI, unsigned OpNum, SStream *O)
1410{
Alex Ionescu46018db2014-01-22 09:45:00 -08001411 unsigned val = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001412 SStream_concat0(O, ARM_ISB_InstSyncBOptToString(val));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001413}
1414
1415static void printShiftImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1416{
Alex Ionescu46018db2014-01-22 09:45:00 -08001417 unsigned ShiftOp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001418 bool isASR = (ShiftOp & (1 << 5)) != 0;
1419 unsigned Amt = ShiftOp & 0x1f;
1420 if (isASR) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001421 unsigned tmp = Amt == 0 ? 32 : Amt;
1422 if (tmp > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001423 SStream_concat(O, ", asr #0x%x", tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001424 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001425 SStream_concat(O, ", asr #%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001426 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001427 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_ASR;
1428 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 +08001429 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001430 } else if (Amt) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001431 if (Amt > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001432 SStream_concat(O, ", lsl #0x%x", Amt);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001433 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001434 SStream_concat(O, ", lsl #%u", Amt);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001435 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001436 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_LSL;
1437 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 +08001438 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001439 }
1440}
1441
1442static void printPKHLSLShiftImm(MCInst *MI, unsigned OpNum, SStream *O)
1443{
Alex Ionescu46018db2014-01-22 09:45:00 -08001444 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001445 if (Imm == 0)
1446 return;
1447 //assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001448 if (Imm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001449 SStream_concat(O, ", lsl #0x%x", Imm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001450 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001451 SStream_concat(O, ", lsl #%u", Imm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001452 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001453 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_LSL;
1454 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 +08001455 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001456}
1457
1458static void printPKHASRShiftImm(MCInst *MI, unsigned OpNum, SStream *O)
1459{
Alex Ionescu46018db2014-01-22 09:45:00 -08001460 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001461 // A shift amount of 32 is encoded as 0.
1462 if (Imm == 0)
1463 Imm = 32;
1464 //assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001465 if (Imm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001466 SStream_concat(O, ", asr #0x%x", Imm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001467 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001468 SStream_concat(O, ", asr #%u", Imm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001469 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001470 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_ASR;
1471 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 +08001472 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001473}
1474
1475// FIXME: push {r1, r2, r3, ...} can exceed the number of operands in MCInst struct
1476static void printRegisterList(MCInst *MI, unsigned OpNum, SStream *O)
1477{
Nguyen Anh Quynh42706a32014-05-09 07:33:35 +08001478 unsigned i, e;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001479#ifndef CAPSTONE_DIET
Ole André Vadla Ravnåsd2e6b5a2015-04-23 12:19:38 +02001480 uint8_t access = 0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001481#endif
1482
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001483 SStream_concat0(O, "{");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001484
1485#ifndef CAPSTONE_DIET
1486 if (MI->csh->detail) {
1487 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1488 }
1489#endif
1490
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001491 for (i = OpNum, e = MCInst_getNumOperands(MI); i != e; ++i) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001492 if (i != OpNum) SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001493 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, i)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001494 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001495 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1496 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 +08001497#ifndef CAPSTONE_DIET
1498 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
1499#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001500 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001501 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001502 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001503 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001504
1505#ifndef CAPSTONE_DIET
1506 if (MI->csh->detail) {
1507 MI->ac_idx++;
1508 }
1509#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001510}
1511
1512static void printGPRPairOperand(MCInst *MI, unsigned OpNum, SStream *O,
1513 MCRegisterInfo *MRI)
1514{
1515 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001516 printRegName(MI->csh, O, MCRegisterInfo_getSubReg(MRI, Reg, ARM_gsub_0));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001517 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001518 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1519 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCRegisterInfo_getSubReg(MRI, Reg, ARM_gsub_0);
1520 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001521 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001522 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001523 printRegName(MI->csh, O, MCRegisterInfo_getSubReg(MRI, Reg, ARM_gsub_1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001524 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001525 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
1526 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCRegisterInfo_getSubReg(MRI, Reg, ARM_gsub_1);
1527 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001528 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001529}
1530
1531// SETEND BE/LE
1532static void printSetendOperand(MCInst *MI, unsigned OpNum, SStream *O)
1533{
1534 MCOperand *Op = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001535 if (MCOperand_getImm(Op)) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001536 SStream_concat0(O, "be");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001537 if (MI->csh->detail) {
1538 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SETEND;
1539 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].setend = ARM_SETEND_BE;
1540 MI->flat_insn->detail->arm.op_count++;
1541 }
1542 } else {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001543 SStream_concat0(O, "le");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001544 if (MI->csh->detail) {
1545 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SETEND;
1546 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].setend = ARM_SETEND_LE;
1547 MI->flat_insn->detail->arm.op_count++;
1548 }
1549 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001550}
1551
1552static void printCPSIMod(MCInst *MI, unsigned OpNum, SStream *O)
1553{
1554 MCOperand *Op = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001555 unsigned int mode = (unsigned int)MCOperand_getImm(Op);
1556
1557 SStream_concat0(O, ARM_PROC_IModToString(mode));
1558
1559 if (MI->csh->detail) {
1560 MI->flat_insn->detail->arm.cps_mode = mode;
1561 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001562}
1563
1564static void printCPSIFlag(MCInst *MI, unsigned OpNum, SStream *O)
1565{
1566 MCOperand *Op = MCInst_getOperand(MI, OpNum);
Alex Ionescu46018db2014-01-22 09:45:00 -08001567 unsigned IFlags = (unsigned int)MCOperand_getImm(Op);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001568 int i;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001569
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001570 for (i = 2; i >= 0; --i)
1571 if (IFlags & (1 << i)) {
1572 SStream_concat0(O, ARM_PROC_IFlagsToString(1 << i));
1573 }
1574
1575 if (IFlags == 0) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001576 SStream_concat0(O, "none");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001577 IFlags = ARM_CPSFLAG_NONE;
1578 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001579
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001580 if (MI->csh->detail) {
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001581 MI->flat_insn->detail->arm.cps_flag = IFlags;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001582 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001583}
1584
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001585static void printMSRMaskOperand(MCInst *MI, unsigned OpNum, SStream *O)
1586{
1587 MCOperand *Op = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh07c92ec2014-08-26 15:35:11 +08001588 unsigned SpecRegRBit = (unsigned)MCOperand_getImm(Op) >> 4;
Nguyen Anh Quynhb52f11f2014-08-13 22:38:15 +08001589 unsigned Mask = MCOperand_getImm(Op) & 0xf;
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001590 unsigned reg;
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001591 uint64_t FeatureBits = ARM_getFeatureBits(MI->csh->mode);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001592
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001593 if (FeatureBits & ARM_FeatureMClass) {
Nguyen Anh Quynh07c92ec2014-08-26 15:35:11 +08001594 unsigned SYSm = (unsigned)MCOperand_getImm(Op);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001595 unsigned Opcode = MCInst_getOpcode(MI);
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001596
1597 // For writes, handle extended mask bits if the DSP extension is present.
1598 if (Opcode == ARM_t2MSR_M && (FeatureBits & ARM_FeatureDSPThumb2)) {
1599 switch (SYSm) {
1600 case 0x400: SStream_concat0(O, "apsr_g"); ARM_addSysReg(MI, ARM_SYSREG_APSR_G); return;
1601 case 0xc00: SStream_concat0(O, "apsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQG); return;
1602 case 0x401: SStream_concat0(O, "iapsr_g"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR_G); return;
1603 case 0xc01: SStream_concat0(O, "iapsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR_NZCVQG); return;
1604 case 0x402: SStream_concat0(O, "eapsr_g"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR_G); return;
1605 case 0xc02: SStream_concat0(O, "eapsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR_NZCVQG); return;
1606 case 0x403: SStream_concat0(O, "xpsr_g"); ARM_addSysReg(MI, ARM_SYSREG_XPSR_G); return;
1607 case 0xc03: SStream_concat0(O, "xpsr_nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_XPSR_NZCVQG); return;
1608 }
1609 }
1610
1611 // Handle the basic 8-bit mask.
1612 SYSm &= 0xff;
1613
1614 if (Opcode == ARM_t2MSR_M && (FeatureBits & ARM_HasV7Ops)) {
1615 // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
1616 // alias for MSR APSR_nzcvq.
1617 switch (SYSm) {
1618 case 0: SStream_concat0(O, "apsr_nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQ); return;
1619 case 1: SStream_concat0(O, "iapsr_nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR_NZCVQ); return;
1620 case 2: SStream_concat0(O, "eapsr_nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR_NZCVQ); return;
1621 case 3: SStream_concat0(O, "xpsr_nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_XPSR_NZCVQ); return;
1622 }
1623 }
1624
1625
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001626 switch (SYSm) {
Nguyen Anh Quynhb52f11f2014-08-13 22:38:15 +08001627 default: //llvm_unreachable("Unexpected mask value!");
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08001628 case 0: SStream_concat0(O, "apsr"); ARM_addSysReg(MI, ARM_SYSREG_APSR); return;
1629 case 1: SStream_concat0(O, "iapsr"); ARM_addSysReg(MI, ARM_SYSREG_IAPSR); return;
1630 case 2: SStream_concat0(O, "eapsr"); ARM_addSysReg(MI, ARM_SYSREG_EAPSR); return;
1631 case 3: SStream_concat0(O, "xpsr"); ARM_addSysReg(MI, ARM_SYSREG_XPSR); return;
1632 case 5: SStream_concat0(O, "ipsr"); ARM_addSysReg(MI, ARM_SYSREG_IPSR); return;
1633 case 6: SStream_concat0(O, "epsr"); ARM_addSysReg(MI, ARM_SYSREG_EPSR); return;
1634 case 7: SStream_concat0(O, "iepsr"); ARM_addSysReg(MI, ARM_SYSREG_IEPSR); return;
1635 case 8: SStream_concat0(O, "msp"); ARM_addSysReg(MI, ARM_SYSREG_MSP); return;
1636 case 9: SStream_concat0(O, "psp"); ARM_addSysReg(MI, ARM_SYSREG_PSP); return;
1637 case 16: SStream_concat0(O, "primask"); ARM_addSysReg(MI, ARM_SYSREG_PRIMASK); return;
1638 case 17: SStream_concat0(O, "basepri"); ARM_addSysReg(MI, ARM_SYSREG_BASEPRI); return;
1639 case 18: SStream_concat0(O, "basepri_max"); ARM_addSysReg(MI, ARM_SYSREG_BASEPRI_MAX); return;
1640 case 19: SStream_concat0(O, "faultmask"); ARM_addSysReg(MI, ARM_SYSREG_FAULTMASK); return;
1641 case 20: SStream_concat0(O, "control"); ARM_addSysReg(MI, ARM_SYSREG_CONTROL); return;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001642 }
1643 }
Nguyen Anh Quynhb52f11f2014-08-13 22:38:15 +08001644
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001645 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
1646 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
1647 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
Nguyen Anh Quynhd865f392014-11-10 16:38:17 +08001648 SStream_concat0(O, "apsr_");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001649 switch (Mask) {
Nguyen Anh Quynhb52f11f2014-08-13 22:38:15 +08001650 default: // llvm_unreachable("Unexpected mask value!");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001651 case 4: SStream_concat0(O, "g"); ARM_addSysReg(MI, ARM_SYSREG_APSR_G); return;
1652 case 8: SStream_concat0(O, "nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQ); return;
1653 case 12: SStream_concat0(O, "nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQG); return;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001654 }
1655 }
1656
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001657 reg = 0;
1658 if (SpecRegRBit) {
Nguyen Anh Quynhd865f392014-11-10 16:38:17 +08001659 SStream_concat0(O, "spsr");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001660 if (Mask) {
1661 SStream_concat0(O, "_");
1662 if (Mask & 8) {
1663 SStream_concat0(O, "f");
1664 reg += ARM_SYSREG_SPSR_F;
1665 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001666
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001667 if (Mask & 4) {
1668 SStream_concat0(O, "s");
1669 reg += ARM_SYSREG_SPSR_S;
1670 }
1671
1672 if (Mask & 2) {
1673 SStream_concat0(O, "x");
1674 reg += ARM_SYSREG_SPSR_X;
1675 }
1676
1677 if (Mask & 1) {
1678 SStream_concat0(O, "c");
1679 reg += ARM_SYSREG_SPSR_C;
1680 }
1681 ARM_addSysReg(MI, reg);
1682 }
1683 } else {
Nguyen Anh Quynhd865f392014-11-10 16:38:17 +08001684 SStream_concat0(O, "cpsr");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001685 if (Mask) {
1686 SStream_concat0(O, "_");
1687 if (Mask & 8) {
1688 SStream_concat0(O, "f");
1689 reg += ARM_SYSREG_CPSR_F;
1690 }
1691
1692 if (Mask & 4) {
1693 SStream_concat0(O, "s");
1694 reg += ARM_SYSREG_CPSR_S;
1695 }
1696
1697 if (Mask & 2) {
1698 SStream_concat0(O, "x");
1699 reg += ARM_SYSREG_CPSR_X;
1700 }
1701
1702 if (Mask & 1) {
1703 SStream_concat0(O, "c");
1704 reg += ARM_SYSREG_CPSR_C;
1705 }
1706 ARM_addSysReg(MI, reg);
1707 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001708 }
1709}
1710
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001711static void printBankedRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
1712{
Nguyen Anh Quynh586e4392016-03-08 00:49:15 +08001713 uint32_t Banked = (uint32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001714 uint32_t R = (Banked & 0x20) >> 5;
1715 uint32_t SysM = Banked & 0x1f;
1716 char *RegNames[] = {
1717 "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "sp_usr", "lr_usr", "",
1718 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq", "lr_fiq", "",
1719 "lr_irq", "sp_irq", "lr_svc", "sp_svc", "lr_abt", "sp_abt", "lr_und", "sp_und",
1720 "", "", "", "", "lr_mon", "sp_mon", "elr_hyp", "sp_hyp"
1721 };
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08001722 arm_sysreg RegIds[] = {
1723 ARM_SYSREG_R8_USR, ARM_SYSREG_R9_USR, ARM_SYSREG_R10_USR,
1724 ARM_SYSREG_R11_USR, ARM_SYSREG_R12_USR, ARM_SYSREG_SP_USR,
1725 ARM_SYSREG_LR_USR, 0, ARM_SYSREG_R8_FIQ, ARM_SYSREG_R9_FIQ,
1726 ARM_SYSREG_R10_FIQ, ARM_SYSREG_R11_FIQ, ARM_SYSREG_R12_FIQ,
1727 ARM_SYSREG_SP_FIQ, ARM_SYSREG_LR_FIQ, 0, ARM_SYSREG_LR_IRQ,
1728 ARM_SYSREG_SP_IRQ, ARM_SYSREG_LR_SVC, ARM_SYSREG_SP_SVC,
1729 ARM_SYSREG_LR_ABT, ARM_SYSREG_SP_ABT, ARM_SYSREG_LR_UND,
1730 ARM_SYSREG_SP_UND, 0, 0, 0, 0, ARM_SYSREG_LR_MON, ARM_SYSREG_SP_MON,
1731 ARM_SYSREG_ELR_HYP, ARM_SYSREG_SP_HYP,
1732 };
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001733 char *Name = RegNames[SysM];
1734
1735 // Nothing much we can do about this, the encodings are specified in B9.2.3 of
1736 // the ARM ARM v7C, and are all over the shop.
1737 if (R) {
1738 SStream_concat0(O, "SPSR_");
1739
1740 switch(SysM) {
1741 default: // llvm_unreachable("Invalid banked SPSR register");
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08001742 case 0x0e: SStream_concat0(O, "fiq"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_FIQ); return;
1743 case 0x10: SStream_concat0(O, "irq"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_IRQ); return;
1744 case 0x12: SStream_concat0(O, "svc"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_SVC); return;
1745 case 0x14: SStream_concat0(O, "abt"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_ABT); return;
1746 case 0x16: SStream_concat0(O, "und"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_UND); return;
1747 case 0x1c: SStream_concat0(O, "mon"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_MON); return;
1748 case 0x1e: SStream_concat0(O, "hyp"); ARM_addSysReg(MI, ARM_SYSREG_SPSR_HYP); return;
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001749 }
1750 }
1751
1752 //assert(!R && "should have dealt with SPSR regs");
1753 //assert(Name[0] && "invalid banked register operand");
1754
1755 SStream_concat0(O, Name);
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08001756 ARM_addSysReg(MI, RegIds[SysM]);
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08001757}
1758
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001759static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O)
1760{
1761 ARMCC_CondCodes CC = (ARMCC_CondCodes)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1762 // Handle the undefined 15 CC value here for printing so we don't abort().
1763 if ((unsigned)CC == 15) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001764 SStream_concat0(O, "<und>");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001765 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001766 MI->flat_insn->detail->arm.cc = ARM_CC_INVALID;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001767 } else {
1768 if (CC != ARMCC_AL) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001769 SStream_concat0(O, ARMCC_ARMCondCodeToString(CC));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001770 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001771 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001772 MI->flat_insn->detail->arm.cc = CC + 1;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001773 }
1774}
1775
1776// TODO: test this
1777static void printMandatoryPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O)
1778{
1779 ARMCC_CondCodes CC = (ARMCC_CondCodes)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001780 SStream_concat0(O, ARMCC_ARMCondCodeToString(CC));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001781 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001782 MI->flat_insn->detail->arm.cc = CC + 1;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001783}
1784
1785static void printSBitModifierOperand(MCInst *MI, unsigned OpNum, SStream *O)
1786{
1787 if (MCOperand_getReg(MCInst_getOperand(MI, OpNum))) {
1788 //assert(MCOperand_getReg(MCInst_getOperand(MI, OpNum)) == ARM_CPSR &&
1789 // "Expect ARM CPSR register!");
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001790 SStream_concat0(O, "s");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001791 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001792 MI->flat_insn->detail->arm.update_flags = true;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001793 }
1794}
1795
1796static void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O)
1797{
Alex Ionescu46018db2014-01-22 09:45:00 -08001798 unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001799 if (tmp > HEX_THRESHOLD)
1800 SStream_concat(O, "0x%x", tmp);
1801 else
1802 SStream_concat(O, "%u", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001803 if (MI->csh->detail) {
Nguyen Anh Quynh19b0de32013-12-31 22:40:04 +08001804 if (MI->csh->doing_mem) {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001805 MI->flat_insn->detail->arm.op_count--;
tandasat45e5eab2016-05-11 21:48:32 -07001806 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].neon_lane = (int8_t)tmp;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08001807 MI->ac_idx--; // consecutive operands share the same access right
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001808 } else {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001809 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1810 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
1811 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001812 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001813 }
1814}
1815
1816static void printPImmediate(MCInst *MI, unsigned OpNum, SStream *O)
1817{
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001818 unsigned imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1819
1820 SStream_concat(O, "p%u", imm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001821 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001822 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 +08001823 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001824 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001825 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001826}
1827
1828static void printCImmediate(MCInst *MI, unsigned OpNum, SStream *O)
1829{
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08001830 unsigned imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1831
1832 SStream_concat(O, "c%u", imm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001833 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001834 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 +08001835 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001836 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001837 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001838}
1839
1840static void printCoprocOptionImm(MCInst *MI, unsigned OpNum, SStream *O)
1841{
Alex Ionescu46018db2014-01-22 09:45:00 -08001842 unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001843 if (tmp > HEX_THRESHOLD)
1844 SStream_concat(O, "{0x%x}", tmp);
1845 else
1846 SStream_concat(O, "{%u}", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001847 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001848 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1849 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
1850 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001851 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001852}
1853
1854static void printAdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned scale)
1855{
1856 MCOperand *MO = MCInst_getOperand(MI, OpNum);
1857
1858 int32_t OffImm = (int32_t)MCOperand_getImm(MO) << scale;
1859
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001860 if (OffImm == INT32_MIN) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001861 SStream_concat0(O, "#-0");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001862 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001863 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1864 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = 0;
1865 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001866 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001867 } else {
1868 if (OffImm < 0)
Nguyen Anh Quynh741a9de2013-11-28 16:02:08 +08001869 SStream_concat(O, "#-0x%x", -OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001870 else {
1871 if (OffImm > HEX_THRESHOLD)
1872 SStream_concat(O, "#0x%x", OffImm);
1873 else
1874 SStream_concat(O, "#%u", OffImm);
1875 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001876 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001877 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1878 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
1879 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001880 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001881 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001882}
1883
1884static void printThumbS4ImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1885{
Alex Ionescu46018db2014-01-22 09:45:00 -08001886 unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)) * 4;
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +08001887
1888 printUInt32Bang(O, tmp);
1889
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08001890 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001891 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1892 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
1893 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08001894 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001895}
1896
1897static void printThumbSRImm(MCInst *MI, unsigned OpNum, SStream *O)
1898{
Alex Ionescu46018db2014-01-22 09:45:00 -08001899 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001900 unsigned tmp = Imm == 0 ? 32 : Imm;
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +08001901
1902 printUInt32Bang(O, tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08001903
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001904 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001905 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
1906 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
1907 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08001908 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001909}
1910
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001911static void printThumbITMask(MCInst *MI, unsigned OpNum, SStream *O)
1912{
1913 // (3 - the number of trailing zeros) is the number of then / else.
Alex Ionescu46018db2014-01-22 09:45:00 -08001914 unsigned Mask = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1915 unsigned Firstcond = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum-1));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001916 unsigned CondBit0 = Firstcond & 1;
1917 unsigned NumTZ = CountTrailingZeros_32(Mask);
1918 //assert(NumTZ <= 3 && "Invalid IT mask!");
1919 unsigned Pos, e;
1920 for (Pos = 3, e = NumTZ; Pos > e; --Pos) {
1921 bool T = ((Mask >> Pos) & 1) == CondBit0;
1922 if (T)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001923 SStream_concat0(O, "t");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001924 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001925 SStream_concat0(O, "e");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001926 }
1927}
1928
1929static void printThumbAddrModeRROperand(MCInst *MI, unsigned Op, SStream *O)
1930{
1931 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1932 MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001933 unsigned RegNum;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001934
1935 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
1936 printOperand(MI, Op, O);
1937 return;
1938 }
1939
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001940 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001941 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001942 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001943 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001944 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 +01001945 RegNum = MCOperand_getReg(MO2);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001946 if (RegNum) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001947 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001948 printRegName(MI->csh, O, RegNum);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001949 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001950 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = RegNum;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001951 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001952 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001953 set_mem_access(MI, false);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001954}
1955
1956static void printThumbAddrModeImm5SOperand(MCInst *MI, unsigned Op, SStream *O,
1957 unsigned Scale)
1958{
1959 MCOperand *MO1 = MCInst_getOperand(MI, Op);
1960 MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08001961 unsigned ImmOffs, tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001962
1963 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
1964 printOperand(MI, Op, O);
1965 return;
1966 }
1967
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001968 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001969 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08001970 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001971 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001972 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 +01001973 ImmOffs = (unsigned int)MCOperand_getImm(MO2);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001974 if (ImmOffs) {
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01001975 tmp = ImmOffs * Scale;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001976 SStream_concat0(O, ", ");
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +08001977 printUInt32Bang(O, tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08001978 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07001979 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001980 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07001981 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001982 set_mem_access(MI, false);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001983}
1984
1985static void printThumbAddrModeImm5S1Operand(MCInst *MI, unsigned Op, SStream *O)
1986{
1987 printThumbAddrModeImm5SOperand(MI, Op, O, 1);
1988}
1989
1990static void printThumbAddrModeImm5S2Operand(MCInst *MI, unsigned Op, SStream *O)
1991{
1992 printThumbAddrModeImm5SOperand(MI, Op, O, 2);
1993}
1994
1995static void printThumbAddrModeImm5S4Operand(MCInst *MI, unsigned Op, SStream *O)
1996{
1997 printThumbAddrModeImm5SOperand(MI, Op, O, 4);
1998}
1999
2000static void printThumbAddrModeSPOperand(MCInst *MI, unsigned Op, SStream *O)
2001{
2002 printThumbAddrModeImm5SOperand(MI, Op, O, 4);
2003}
2004
2005// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
2006// register with shift forms.
2007// REG 0 0 - e.g. R5
2008// REG IMM, SH_OPC - e.g. R5, LSL #3
2009static void printT2SOOperand(MCInst *MI, unsigned OpNum, SStream *O)
2010{
2011 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2012 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
2013
2014 unsigned Reg = MCOperand_getReg(MO1);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002015 printRegName(MI->csh, O, Reg);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002016 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002017 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2018 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002019 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 +07002020 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002021 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002022
2023 // Print the shift opc.
2024 //assert(MO2.isImm() && "Not a valid t2_so_reg value!");
Alex Ionescu46018db2014-01-22 09:45:00 -08002025 printRegImmShift(MI, O, ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2)),
Nguyen Anh Quynh8c1104b2014-06-10 00:39:06 +07002026 getSORegOffset((unsigned int)MCOperand_getImm(MO2)));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002027}
2028
2029static void printAddrModeImm12Operand(MCInst *MI, unsigned OpNum,
2030 SStream *O, bool AlwaysPrintImm0)
2031{
2032 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2033 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08002034 int32_t OffImm;
2035 bool isSub;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002036
2037 if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
2038 printOperand(MI, OpNum, O);
2039 return;
2040 }
2041
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002042 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002043 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002044 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002045
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002046 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002047 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 +08002048
Alex Ionescu46018db2014-01-22 09:45:00 -08002049 OffImm = (int32_t)MCOperand_getImm(MO2);
2050 isSub = OffImm < 0;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002051 // Special value for #-0. All others are normal.
2052 if (OffImm == INT32_MIN)
2053 OffImm = 0;
2054 if (isSub) {
Nguyen Anh Quynha247dc12014-04-12 00:19:42 +08002055 if (OffImm < -HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002056 SStream_concat(O, ", #-0x%x", -OffImm);
Nguyen Anh Quynha247dc12014-04-12 00:19:42 +08002057 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002058 SStream_concat(O, ", #-%u", -OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002059 } else if (AlwaysPrintImm0 || OffImm > 0) {
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002060 if (OffImm >= 0) {
2061 if (OffImm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002062 SStream_concat(O, ", #0x%x", OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002063 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002064 SStream_concat(O, ", #%u", OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002065 } else {
2066 if (OffImm < -HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002067 SStream_concat(O, ", #-0x%x", -OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002068 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002069 SStream_concat(O, ", #-%u", -OffImm);
Nguyen Anh Quynhffff7562014-03-26 16:21:31 +08002070 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002071 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002072 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002073 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002074 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002075 set_mem_access(MI, false);
2076}
2077
2078static void printT2AddrModeImm8Operand(MCInst *MI, unsigned OpNum, SStream *O,
2079 bool AlwaysPrintImm0)
2080{
2081 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2082 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08002083 int32_t OffImm;
2084 bool isSub;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002085
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002086 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002087 set_mem_access(MI, true);
2088
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002089 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002090 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002091 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 +08002092
Alex Ionescu46018db2014-01-22 09:45:00 -08002093 OffImm = (int32_t)MCOperand_getImm(MO2);
2094 isSub = OffImm < 0;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002095 // Don't print +0.
2096 if (OffImm == INT32_MIN)
2097 OffImm = 0;
2098
2099 if (isSub)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002100 SStream_concat(O, ", #-0x%x", -OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002101 else if (AlwaysPrintImm0 || OffImm > 0) {
2102 if (OffImm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002103 SStream_concat(O, ", #0x%x", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002104 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002105 SStream_concat(O, ", #%u", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002106 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002107
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.disp = OffImm;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002110 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002111 set_mem_access(MI, false);
2112}
2113
2114static void printT2AddrModeImm8s4Operand(MCInst *MI,
2115 unsigned OpNum, SStream *O, bool AlwaysPrintImm0)
2116{
2117 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2118 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhaa078a12014-01-23 22:29:04 +08002119 int32_t OffImm;
2120 bool isSub;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002121
2122 if (!MCOperand_isReg(MO1)) { // For label symbolic references.
2123 printOperand(MI, OpNum, O);
2124 return;
2125 }
2126
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002127 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002128 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002129 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002130 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002131 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 +08002132
Alex Ionescu46018db2014-01-22 09:45:00 -08002133 OffImm = (int32_t)MCOperand_getImm(MO2);
2134 isSub = OffImm < 0;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002135
2136 //assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
2137
2138 // Don't print +0.
2139 if (OffImm == INT32_MIN)
2140 OffImm = 0;
2141 if (isSub) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002142 SStream_concat(O, ", #-0x%x", -OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002143 } else if (AlwaysPrintImm0 || OffImm > 0) {
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002144 if (OffImm > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002145 SStream_concat(O, ", #0x%x", OffImm);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002146 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002147 SStream_concat(O, ", #%u", OffImm);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002148 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002149 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002150 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002151
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002152 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002153 set_mem_access(MI, false);
2154}
2155
2156static void printT2AddrModeImm0_1020s4Operand(MCInst *MI, unsigned OpNum, SStream *O)
2157{
2158 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2159 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08002160 unsigned tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002161
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002162 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002163 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002164 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002165 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002166 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 +08002167 if (MCOperand_getImm(MO2)) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002168 SStream_concat0(O, ", ");
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01002169 tmp = (unsigned int)MCOperand_getImm(MO2) * 4;
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +08002170 printUInt32Bang(O, tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002171 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002172 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002173 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002174 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002175 set_mem_access(MI, false);
2176}
2177
2178static void printT2AddrModeImm8OffsetOperand(MCInst *MI,
2179 unsigned OpNum, SStream *O)
2180{
2181 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2182 int32_t OffImm = (int32_t)MCOperand_getImm(MO1);
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002183 SStream_concat0(O, ", ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002184 if (OffImm == INT32_MIN) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002185 SStream_concat0(O, "#-0");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002186 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002187 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2188 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = 0;
2189 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002190 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002191 } else {
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +08002192 printInt32Bang(O, OffImm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002193 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002194 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2195 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
2196 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002197 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002198 }
2199}
2200
2201static void printT2AddrModeImm8s4OffsetOperand(MCInst *MI,
2202 unsigned OpNum, SStream *O)
2203{
2204 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2205 int32_t OffImm = (int32_t)MCOperand_getImm(MO1);
2206
2207 //assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
2208
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002209 SStream_concat0(O, ", ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002210 if (OffImm == INT32_MIN) {
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002211 SStream_concat0(O, "#-0");
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002212 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002213 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2214 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = 0;
2215 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002216 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002217 } else {
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +08002218 printInt32Bang(O, OffImm);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002219 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002220 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2221 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
2222 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002223 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002224 }
2225}
2226
2227static void printT2AddrModeSoRegOperand(MCInst *MI,
2228 unsigned OpNum, SStream *O)
2229{
2230 MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
2231 MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
2232 MCOperand *MO3 = MCInst_getOperand(MI, OpNum+2);
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08002233 unsigned ShAmt;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002234
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002235 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002236 set_mem_access(MI, true);
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002237 printRegName(MI->csh, O, MCOperand_getReg(MO1));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002238 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002239 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 +08002240
2241 //assert(MCOperand_getReg(MO2.getReg() && "Invalid so_reg load / store address!");
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002242 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002243 printRegName(MI->csh, O, MCOperand_getReg(MO2));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002244 if (MI->csh->detail)
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002245 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 +08002246
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01002247 ShAmt = (unsigned int)MCOperand_getImm(MO3);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002248 if (ShAmt) {
2249 //assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002250 SStream_concat0(O, ", lsl ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002251 SStream_concat(O, "#%d", ShAmt);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002252 if (MI->csh->detail) {
Nguyen Anh Quynh706b8082015-01-12 15:27:29 +08002253 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.lshift = ShAmt;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002254 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002255 }
2256
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002257 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002258 set_mem_access(MI, false);
2259}
2260
2261static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
2262{
2263 MCOperand *MO = MCInst_getOperand(MI, OpNum);
Nguyen Anh Quynh2ac5d792014-11-10 21:46:34 +08002264 SStream_concat(O, "#%e", getFPImmFloat((unsigned int)MCOperand_getImm(MO)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002265 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002266 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_FP;
2267 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].fp = getFPImmFloat((unsigned int)MCOperand_getImm(MO));
2268 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002269 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002270}
2271
2272static void printNEONModImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
2273{
Alex Ionescu46018db2014-01-22 09:45:00 -08002274 unsigned EncodedImm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002275 unsigned EltBits;
2276 uint64_t Val = ARM_AM_decodeNEONModImm(EncodedImm, &EltBits);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002277 if (Val > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002278 SStream_concat(O, "#0x%"PRIx64, Val);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002279 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002280 SStream_concat(O, "#%"PRIu64, Val);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002281 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002282 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2283 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = (unsigned int)Val;
2284 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002285 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002286}
2287
2288static void printImmPlusOneOperand(MCInst *MI, unsigned OpNum, SStream *O)
2289{
Alex Ionescu46018db2014-01-22 09:45:00 -08002290 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002291 if (Imm + 1 > HEX_THRESHOLD)
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002292 SStream_concat(O, "#0x%x", Imm + 1);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002293 else
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002294 SStream_concat(O, "#%u", Imm + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002295 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002296 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2297 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Imm + 1;
2298 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002299 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002300}
2301
2302static void printRotImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
2303{
Alex Ionescu46018db2014-01-22 09:45:00 -08002304 unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002305 if (Imm == 0)
2306 return;
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002307 SStream_concat0(O, ", ror #");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002308 switch (Imm) {
2309 default: //assert (0 && "illegal ror immediate!");
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002310 case 1: SStream_concat0(O, "8"); break;
2311 case 2: SStream_concat0(O, "16"); break;
2312 case 3: SStream_concat0(O, "24"); break;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002313 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002314 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002315 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_ROR;
2316 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 +08002317 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002318}
2319
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08002320static void printModImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
2321{
2322 MCOperand *Op = MCInst_getOperand(MI, OpNum);
2323 unsigned Bits = MCOperand_getImm(Op) & 0xFF;
2324 unsigned Rot = (MCOperand_getImm(Op) & 0xF00) >> 7;
2325 int32_t Rotated;
2326
2327 bool PrintUnsigned = false;
2328 switch (MCInst_getOpcode(MI)) {
2329 case ARM_MOVi:
2330 // Movs to PC should be treated unsigned
2331 PrintUnsigned = (MCOperand_getReg(MCInst_getOperand(MI, OpNum - 1)) == ARM_PC);
2332 break;
2333 case ARM_MSRi:
2334 // Movs to special registers should be treated unsigned
2335 PrintUnsigned = true;
2336 break;
2337 }
2338
2339 Rotated = rotr32(Bits, Rot);
2340 if (getSOImmVal(Rotated) == MCOperand_getImm(Op)) {
2341 // #rot has the least possible value
Nguyen Anh Quynhe0329dd2015-03-08 00:29:20 +08002342 if (PrintUnsigned) {
2343 if (Rotated > HEX_THRESHOLD || Rotated < -HEX_THRESHOLD)
2344 SStream_concat(O, "#0x%x", Rotated);
2345 else
2346 SStream_concat(O, "#%u", Rotated);
2347 } else if (Rotated >= 0) {
Nguyen Anh Quynhb8b83482015-03-07 00:26:24 +08002348 if (Rotated > HEX_THRESHOLD)
2349 SStream_concat(O, "#0x%x", Rotated);
2350 else
2351 SStream_concat(O, "#%u", Rotated);
2352 } else {
2353 SStream_concat(O, "#0x%x", Rotated);
2354 }
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08002355 if (MI->csh->detail) {
2356 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2357 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Rotated;
2358 MI->flat_insn->detail->arm.op_count++;
2359 }
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08002360 return;
2361 }
2362
2363 // Explicit #bits, #rot implied
Nguyen Anh Quynh7e256092015-03-03 18:28:10 +08002364 SStream_concat(O, "#%u, #%u", Bits, Rot);
2365 if (MI->csh->detail) {
2366 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2367 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Bits;
2368 MI->flat_insn->detail->arm.op_count++;
2369 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2370 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Rot;
2371 MI->flat_insn->detail->arm.op_count++;
2372 }
Nguyen Anh Quynhd1fc2bd2015-03-03 16:26:32 +08002373}
2374
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002375static void printFBits16(MCInst *MI, unsigned OpNum, SStream *O)
2376{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08002377 unsigned tmp;
2378
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01002379 tmp = 16 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +08002380 printUInt32Bang(O, tmp);
2381
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002382 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002383 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2384 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
2385 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002386 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002387}
2388
2389static void printFBits32(MCInst *MI, unsigned OpNum, SStream *O)
2390{
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +08002391 unsigned tmp;
2392
Axel 0vercl0k Souchet779d4c72014-05-08 23:44:49 +01002393 tmp = 32 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh256090a2016-03-14 13:52:23 +08002394 printUInt32Bang(O, tmp);
2395
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002396 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002397 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
2398 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
2399 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002400 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002401}
2402
2403static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O)
2404{
Alex Ionescu46018db2014-01-22 09:45:00 -08002405 unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002406 if (tmp > HEX_THRESHOLD)
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002407 SStream_concat(O, "[0x%x]", tmp);
Nguyen Anh Quynh462f2912013-12-11 17:35:27 +08002408 else
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002409 SStream_concat(O, "[%u]", tmp);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002410 if (MI->csh->detail) {
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08002411 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 +08002412 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002413}
2414
2415static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O)
2416{
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002417 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002418 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002419 if (MI->csh->detail) {
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002420#ifndef CAPSTONE_DIET
2421 uint8_t access;
2422
2423 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2424#endif
2425
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002426 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2427 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 +08002428#ifndef CAPSTONE_DIET
2429 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2430#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002431 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002432
2433#ifndef CAPSTONE_DIET
2434 MI->ac_idx++;
2435#endif
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002436 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002437 SStream_concat0(O, "}");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002438}
2439
2440static void printVectorListTwo(MCInst *MI, unsigned OpNum,
2441 SStream *O, MCRegisterInfo *MRI)
2442{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002443#ifndef CAPSTONE_DIET
2444 uint8_t access;
2445#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002446 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2447 unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
2448 unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002449
2450#ifndef CAPSTONE_DIET
2451 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2452#endif
2453
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002454 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002455 printRegName(MI->csh, O, Reg0);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002456 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002457 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2458 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002459#ifndef CAPSTONE_DIET
2460 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2461#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002462 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002463 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002464 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002465 printRegName(MI->csh, O, Reg1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002466 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002467 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2468 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002469#ifndef CAPSTONE_DIET
2470 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2471#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002472 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002473 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002474 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002475
2476#ifndef CAPSTONE_DIET
2477 MI->ac_idx++;
2478#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002479}
2480
2481static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum,
2482 SStream *O, MCRegisterInfo *MRI)
2483{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002484#ifndef CAPSTONE_DIET
2485 uint8_t access;
2486#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002487 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2488 unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
2489 unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_2);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002490
2491#ifndef CAPSTONE_DIET
2492 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2493#endif
2494
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002495 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002496 printRegName(MI->csh, O, Reg0);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002497 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002498 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2499 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002500#ifndef CAPSTONE_DIET
2501 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2502#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002503 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002504 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002505 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002506 printRegName(MI->csh, O, Reg1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002507 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002508 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2509 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002510#ifndef CAPSTONE_DIET
2511 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2512#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002513 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002514 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002515 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002516
2517#ifndef CAPSTONE_DIET
2518 MI->ac_idx++;
2519#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002520}
2521
2522static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
2523{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002524#ifndef CAPSTONE_DIET
2525 uint8_t access;
2526
2527 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2528#endif
2529
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002530 // Normally, it's not safe to use register enum values directly with
2531 // addition to get the next register, but for VFP registers, the
2532 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002533 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002534 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002535 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002536 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2537 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 +08002538#ifndef CAPSTONE_DIET
2539 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2540#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002541 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002542 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002543 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002544 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002545 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002546 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2547 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 +08002548#ifndef CAPSTONE_DIET
2549 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2550#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002551 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002552 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002553 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002554 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002555 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002556 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2557 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 +08002558#ifndef CAPSTONE_DIET
2559 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2560#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002561 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002562 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002563 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002564
2565#ifndef CAPSTONE_DIET
2566 MI->ac_idx++;
2567#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002568}
2569
2570static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
2571{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002572#ifndef CAPSTONE_DIET
2573 uint8_t access;
2574
2575 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2576#endif
2577
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002578 // Normally, it's not safe to use register enum values directly with
2579 // addition to get the next register, but for VFP registers, the
2580 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002581 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002582 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002583 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002584 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2585 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 +08002586#ifndef CAPSTONE_DIET
2587 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2588#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002589 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002590 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002591 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002592 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002593 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002594 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2595 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 +08002596#ifndef CAPSTONE_DIET
2597 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2598#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002599 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002600 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002601 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002602 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002603 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002604 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2605 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 +08002606#ifndef CAPSTONE_DIET
2607 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2608#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002609 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002610 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002611 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002612 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002613 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002614 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2615 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 +08002616#ifndef CAPSTONE_DIET
2617 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2618#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002619 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002620 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002621 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002622
2623#ifndef CAPSTONE_DIET
2624 MI->ac_idx++;
2625#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002626}
2627
2628static void printVectorListOneAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
2629{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002630#ifndef CAPSTONE_DIET
2631 uint8_t access;
2632
2633 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2634#endif
2635
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002636 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002637 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002638 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002639 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2640 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 +08002641#ifndef CAPSTONE_DIET
2642 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2643#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002644 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002645 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002646 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002647
2648#ifndef CAPSTONE_DIET
2649 MI->ac_idx++;
2650#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002651}
2652
2653static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum,
2654 SStream *O, MCRegisterInfo *MRI)
2655{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002656#ifndef CAPSTONE_DIET
2657 uint8_t access;
2658#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002659 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2660 unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
2661 unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_1);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002662
2663#ifndef CAPSTONE_DIET
2664 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2665#endif
2666
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002667 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002668 printRegName(MI->csh, O, Reg0);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002669 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002670 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2671 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002672#ifndef CAPSTONE_DIET
2673 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2674#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002675 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002676 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002677 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002678 printRegName(MI->csh, O, Reg1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002679 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002680 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2681 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002682#ifndef CAPSTONE_DIET
2683 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2684#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002685 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002686 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002687 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002688
2689#ifndef CAPSTONE_DIET
2690 MI->ac_idx++;
2691#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002692}
2693
2694static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
2695{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002696#ifndef CAPSTONE_DIET
2697 uint8_t access;
2698
2699 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2700#endif
2701
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002702 // Normally, it's not safe to use register enum values directly with
2703 // addition to get the next register, but for VFP registers, the
2704 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002705 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002706 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002707 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002708 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2709 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 +08002710#ifndef CAPSTONE_DIET
2711 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2712#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002713 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002714 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002715 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002716 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002717 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002718 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2719 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 +08002720#ifndef CAPSTONE_DIET
2721 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2722#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002723 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002724 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002725 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002726 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002727 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002728 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2729 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 +08002730#ifndef CAPSTONE_DIET
2731 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2732#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002733 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002734 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002735 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002736
2737#ifndef CAPSTONE_DIET
2738 MI->ac_idx++;
2739#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002740}
2741
2742static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
2743{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002744#ifndef CAPSTONE_DIET
2745 uint8_t access;
2746
2747 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2748#endif
2749
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002750 // Normally, it's not safe to use register enum values directly with
2751 // addition to get the next register, but for VFP registers, the
2752 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002753 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002754 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002755 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002756 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2757 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 +08002758#ifndef CAPSTONE_DIET
2759 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2760#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002761 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002762 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002763 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002764 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002765 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002766 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2767 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 +08002768#ifndef CAPSTONE_DIET
2769 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2770#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002771 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002772 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002773 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002774 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002775 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002776 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2777 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 +08002778#ifndef CAPSTONE_DIET
2779 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2780#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002781 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002782 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002783 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002784 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002785 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002786 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2787 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 +08002788#ifndef CAPSTONE_DIET
2789 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2790#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002791 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002792 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002793 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002794
2795#ifndef CAPSTONE_DIET
2796 MI->ac_idx++;
2797#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002798}
2799
2800static void printVectorListTwoSpacedAllLanes(MCInst *MI,
2801 unsigned OpNum, SStream *O, MCRegisterInfo *MRI)
2802{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002803#ifndef CAPSTONE_DIET
2804 uint8_t access;
2805#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002806 unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2807 unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
2808 unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_2);
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002809
2810#ifndef CAPSTONE_DIET
2811 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2812#endif
2813
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002814 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002815 printRegName(MI->csh, O, Reg0);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002816 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002817 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2818 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002819#ifndef CAPSTONE_DIET
2820 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2821#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002822 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002823 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002824 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002825 printRegName(MI->csh, O, Reg1);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002826 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002827 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2828 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002829#ifndef CAPSTONE_DIET
2830 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2831#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002832 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002833 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002834 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002835
2836#ifndef CAPSTONE_DIET
2837 MI->ac_idx++;
2838#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002839}
2840
2841static void printVectorListThreeSpacedAllLanes(MCInst *MI,
2842 unsigned OpNum, SStream *O)
2843{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002844#ifndef CAPSTONE_DIET
2845 uint8_t access;
2846
2847 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2848#endif
2849
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002850 // Normally, it's not safe to use register enum values directly with
2851 // addition to get the next register, but for VFP registers, the
2852 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002853 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002854 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002855 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002856 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2857 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 +08002858#ifndef CAPSTONE_DIET
2859 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2860#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002861 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002862 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002863 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002864 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002865 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002866 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2867 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 +08002868#ifndef CAPSTONE_DIET
2869 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2870#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002871 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002872 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002873 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002874 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002875 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002876 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2877 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 +08002878#ifndef CAPSTONE_DIET
2879 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2880#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002881 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002882 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002883 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002884
2885#ifndef CAPSTONE_DIET
2886 MI->ac_idx++;
2887#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002888}
2889
2890static void printVectorListFourSpacedAllLanes(MCInst *MI,
2891 unsigned OpNum, SStream *O)
2892{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002893#ifndef CAPSTONE_DIET
2894 uint8_t access;
2895
2896 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2897#endif
2898
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002899 // Normally, it's not safe to use register enum values directly with
2900 // addition to get the next register, but for VFP registers, the
2901 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002902 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002903 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002904 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002905 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2906 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 +08002907#ifndef CAPSTONE_DIET
2908 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2909#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002910 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002911 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002912 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002913 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002914 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002915 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2916 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 +08002917#ifndef CAPSTONE_DIET
2918 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2919#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002920 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002921 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002922 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002923 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002924 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002925 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2926 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 +08002927#ifndef CAPSTONE_DIET
2928 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2929#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002930 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002931 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002932 SStream_concat0(O, "[], ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002933 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002934 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002935 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2936 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 +08002937#ifndef CAPSTONE_DIET
2938 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2939#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002940 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002941 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002942 SStream_concat0(O, "[]}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002943
2944#ifndef CAPSTONE_DIET
2945 MI->ac_idx++;
2946#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002947}
2948
2949static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
2950{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002951#ifndef CAPSTONE_DIET
2952 uint8_t access;
2953
2954 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2955#endif
2956
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002957 // Normally, it's not safe to use register enum values directly with
2958 // addition to get the next register, but for VFP registers, the
2959 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002960 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002961 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002962 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002963 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2964 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 +08002965#ifndef CAPSTONE_DIET
2966 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2967#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002968 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002969 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002970 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002971 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002972 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002973 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2974 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 +08002975#ifndef CAPSTONE_DIET
2976 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2977#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002978 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002979 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002980 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08002981 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08002982 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002983 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
2984 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 +08002985#ifndef CAPSTONE_DIET
2986 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
2987#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07002988 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08002989 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07002990 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002991
2992#ifndef CAPSTONE_DIET
2993 MI->ac_idx++;
2994#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08002995}
2996
2997static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
2998{
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08002999#ifndef CAPSTONE_DIET
3000 uint8_t access;
3001
3002 access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
3003#endif
3004
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08003005 // Normally, it's not safe to use register enum values directly with
3006 // addition to get the next register, but for VFP registers, the
3007 // sort order is guaranteed because they're all of the form D<n>.
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003008 SStream_concat0(O, "{");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08003009 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08003010 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003011 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3012 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 +08003013#ifndef CAPSTONE_DIET
3014 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
3015#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003016 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08003017 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003018 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08003019 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08003020 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003021 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3022 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 +08003023#ifndef CAPSTONE_DIET
3024 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
3025#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003026 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08003027 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003028 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08003029 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08003030 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003031 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3032 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 +08003033#ifndef CAPSTONE_DIET
3034 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
3035#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003036 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08003037 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003038 SStream_concat0(O, ", ");
Nguyen Anh Quynh2ff665a2014-03-11 00:18:50 +08003039 printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +08003040 if (MI->csh->detail) {
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003041 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3042 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 +08003043#ifndef CAPSTONE_DIET
3044 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
3045#endif
Nguyen Anh Quynh29fd0f62014-06-09 08:00:18 +07003046 MI->flat_insn->detail->arm.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +08003047 }
Nguyen Anh Quynhdd9225b2014-06-10 00:37:53 +07003048 SStream_concat0(O, "}");
Nguyen Anh Quynh29f777b2015-04-07 11:59:26 +08003049
3050#ifndef CAPSTONE_DIET
3051 MI->ac_idx++;
3052#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08003053}
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +08003054
Nguyen Anh Quynh04d9f8e2014-09-01 23:27:24 +08003055void ARM_addVectorDataType(MCInst *MI, arm_vectordata_type vd)
3056{
3057 if (MI->csh->detail) {
3058 MI->flat_insn->detail->arm.vector_data = vd;
3059 }
3060}
3061
3062void ARM_addVectorDataSize(MCInst *MI, int size)
3063{
3064 if (MI->csh->detail) {
3065 MI->flat_insn->detail->arm.vector_size = size;
3066 }
3067}
3068
3069void ARM_addReg(MCInst *MI, int reg)
3070{
3071 if (MI->csh->detail) {
3072 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
3073 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = reg;
3074 MI->flat_insn->detail->arm.op_count++;
3075 }
3076}
3077
3078void ARM_addUserMode(MCInst *MI)
3079{
3080 if (MI->csh->detail) {
3081 MI->flat_insn->detail->arm.usermode = true;
3082 }
3083}
3084
3085void ARM_addSysReg(MCInst *MI, arm_sysreg reg)
3086{
3087 if (MI->csh->detail) {
3088 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SYSREG;
3089 MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = reg;
3090 MI->flat_insn->detail->arm.op_count++;
3091 }
3092}
3093
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +08003094#endif