/src/capstonenext/arch/ARM/ARMInstPrinter.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Capstone Disassembly Engine, http://www.capstone-engine.org */ |
2 | | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */ |
3 | | /* Rot127 <unisono@quyllur.org> 2022-2023 */ |
4 | | /* Automatically translated source file from LLVM. */ |
5 | | |
6 | | /* LLVM-commit: 464bda7750a3ba9e23823fc707d7e7b6fc38438d */ |
7 | | /* LLVM-tag: llvmorg-16.0.2-5-g464bda7750a3 */ |
8 | | |
9 | | /* Only small edits allowed. */ |
10 | | /* For multiple similar edits, please create a Patch for the translator. */ |
11 | | |
12 | | /* Capstone's C++ file translator: */ |
13 | | /* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */ |
14 | | |
15 | | //===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===// |
16 | | // |
17 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
18 | | // See https://llvm.org/LICENSE.txt for license information. |
19 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
20 | | // |
21 | | //===----------------------------------------------------------------------===// |
22 | | // |
23 | | // This class prints an ARM MCInst to a .s file. |
24 | | // |
25 | | //===----------------------------------------------------------------------===// |
26 | | |
27 | | #include <capstone/platform.h> |
28 | | #include <stdio.h> |
29 | | #include <stdlib.h> |
30 | | #include <string.h> |
31 | | |
32 | | #include "../../Mapping.h" |
33 | | #include "../../MCInst.h" |
34 | | #include "../../MCInstPrinter.h" |
35 | | #include "../../MCRegisterInfo.h" |
36 | | #include "../../SStream.h" |
37 | | #include "../../utils.h" |
38 | | #include "ARMAddressingModes.h" |
39 | | #include "ARMBaseInfo.h" |
40 | | #include "ARMDisassemblerExtension.h" |
41 | | #include "ARMInstPrinter.h" |
42 | | #include "ARMLinkage.h" |
43 | | #include "ARMMapping.h" |
44 | | |
45 | | #define GET_BANKEDREG_IMPL |
46 | | #include "ARMGenSystemRegister.inc" |
47 | | |
48 | 94.3k | #define CONCAT(a, b) CONCAT_(a, b) |
49 | 94.3k | #define CONCAT_(a, b) a##_##b |
50 | | |
51 | | #define DEBUG_TYPE "asm-printer" |
52 | | |
53 | | // Static function declarations. These are functions which have the same identifiers |
54 | | // over all architectures. Therefor they need to be static. |
55 | | #ifndef CAPSTONE_DIET |
56 | | static void printCustomAliasOperand(MCInst *MI, uint64_t Address, |
57 | | unsigned OpIdx, unsigned PrintMethodIdx, |
58 | | SStream *O); |
59 | | #endif |
60 | | static void printOperand(MCInst *MI, unsigned OpNo, SStream *O); |
61 | | static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O); |
62 | | static void printRegName(SStream *OS, unsigned RegNo); |
63 | | static void printInst(MCInst *MI, SStream *O, void *info); |
64 | | |
65 | | #define PRINT_ALIAS_INSTR |
66 | | #include "ARMGenAsmWriter.inc" |
67 | | |
68 | | /// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing. |
69 | | /// |
70 | | /// getSORegOffset returns an integer from 0-31, representing '32' as 0. |
71 | | unsigned translateShiftImm(unsigned imm) |
72 | 71.8k | { |
73 | | // lsr #32 and asr #32 exist, but should be encoded as a 0. |
74 | | |
75 | 71.8k | if (imm == 0) |
76 | 5.37k | return 32; |
77 | 66.4k | return imm; |
78 | 71.8k | } |
79 | | |
80 | | /// Prints the shift value with an immediate value. |
81 | | static void printRegImmShift(MCInst *MI, SStream *O, ARM_AM_ShiftOpc ShOpc, |
82 | | unsigned ShImm, bool UseMarkup) |
83 | 25.6k | { |
84 | 25.6k | add_cs_detail(MI, ARM_OP_GROUP_RegImmShift, ShOpc, ShImm); |
85 | 25.6k | if (ShOpc == ARM_AM_no_shift || (ShOpc == ARM_AM_lsl && !ShImm)) |
86 | 812 | return; |
87 | 24.8k | SStream_concat0(O, ", "); |
88 | | |
89 | 24.8k | SStream_concat0(O, ARM_AM_getShiftOpcStr(ShOpc)); |
90 | | |
91 | 24.8k | if (ShOpc != ARM_AM_rrx) { |
92 | 23.7k | SStream_concat0(O, " "); |
93 | 23.7k | if (getUseMarkup()) |
94 | 0 | SStream_concat0(O, "<imm:"); |
95 | 23.7k | SStream_concat(O, "%s%d", "#", translateShiftImm(ShImm)); |
96 | 23.7k | if (getUseMarkup()) |
97 | 0 | SStream_concat0(O, ">"); |
98 | 23.7k | } |
99 | 24.8k | } |
100 | | |
101 | | static void printRegName(SStream *OS, unsigned RegNo) |
102 | 5.63M | { |
103 | 5.63M | SStream_concat(OS, "%s%s", markup("<reg:"), |
104 | 5.63M | getRegisterName(RegNo, ARM_NoRegAltName)); |
105 | 5.63M | SStream_concat0(OS, markup(">")); |
106 | 5.63M | } |
107 | | |
108 | | static void printInst(MCInst *MI, SStream *O, void *info) |
109 | 1.47M | { |
110 | 1.47M | bool isAlias = false; |
111 | 1.47M | bool useAliasDetails = map_use_alias_details(MI); |
112 | 1.47M | map_set_fill_detail_ops(MI, useAliasDetails); |
113 | 1.47M | unsigned Opcode = MCInst_getOpcode(MI); |
114 | 1.47M | uint64_t Address = MI->address; |
115 | | |
116 | 1.47M | switch (Opcode) { |
117 | | // Check for MOVs and print canonical forms, instead. |
118 | 318 | case ARM_MOVsr: { |
119 | 318 | isAlias = true; |
120 | 318 | MCInst_setIsAlias(MI, isAlias); |
121 | | // FIXME: Thumb variants? |
122 | 318 | MCOperand *MO3 = MCInst_getOperand(MI, (3)); |
123 | | |
124 | 318 | SStream_concat1(O, ' '); |
125 | 318 | SStream_concat0(O, ARM_AM_getShiftOpcStr(ARM_AM_getSORegShOp( |
126 | 318 | MCOperand_getImm(MO3)))); |
127 | 318 | printSBitModifierOperand(MI, 6, O); |
128 | 318 | printPredicateOperand(MI, 4, O); |
129 | | |
130 | 318 | SStream_concat0(O, " "); |
131 | | |
132 | 318 | printOperand(MI, 0, O); |
133 | 318 | SStream_concat0(O, ", "); |
134 | 318 | printOperand(MI, 1, O); |
135 | | |
136 | 318 | SStream_concat0(O, ", "); |
137 | 318 | printOperand(MI, 2, O); |
138 | | |
139 | 318 | if (useAliasDetails) |
140 | 318 | return; |
141 | 0 | else |
142 | 0 | goto add_real_detail; |
143 | 318 | } |
144 | | |
145 | 604 | case ARM_MOVsi: { |
146 | 604 | isAlias = true; |
147 | 604 | MCInst_setIsAlias(MI, isAlias); |
148 | | // FIXME: Thumb variants? |
149 | 604 | MCOperand *MO2 = MCInst_getOperand(MI, (2)); |
150 | | |
151 | 604 | SStream_concat0(O, ARM_AM_getShiftOpcStr(ARM_AM_getSORegShOp( |
152 | 604 | MCOperand_getImm(MO2)))); |
153 | 604 | printSBitModifierOperand(MI, 5, O); |
154 | 604 | printPredicateOperand(MI, 3, O); |
155 | | |
156 | 604 | SStream_concat0(O, " "); |
157 | | |
158 | 604 | printOperand(MI, 0, O); |
159 | 604 | SStream_concat0(O, ", "); |
160 | 604 | printOperand(MI, 1, O); |
161 | | |
162 | 604 | if (ARM_AM_getSORegShOp(MCOperand_getImm(MO2)) == ARM_AM_rrx) { |
163 | 22 | if (useAliasDetails) |
164 | 22 | return; |
165 | 0 | else |
166 | 0 | goto add_real_detail; |
167 | 22 | } |
168 | | |
169 | 582 | SStream_concat(O, "%s%s%s%d", ", ", markup("<imm:"), "#", |
170 | 582 | translateShiftImm(ARM_AM_getSORegOffset( |
171 | 582 | MCOperand_getImm(MO2)))); |
172 | 582 | SStream_concat0(O, markup(">")); |
173 | 582 | if (useAliasDetails) |
174 | 582 | return; |
175 | 0 | else |
176 | 0 | goto add_real_detail; |
177 | 582 | } |
178 | | |
179 | | // A8.6.123 PUSH |
180 | 681 | case ARM_STMDB_UPD: |
181 | 945 | case ARM_t2STMDB_UPD: |
182 | 945 | if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP && |
183 | 945 | MCInst_getNumOperands(MI) > 5) { |
184 | 528 | isAlias = true; |
185 | 528 | MCInst_setIsAlias(MI, isAlias); |
186 | | // Should only print PUSH if there are at least two registers in the |
187 | | // list. |
188 | 528 | SStream_concat0(O, "push"); |
189 | 528 | printPredicateOperand(MI, 2, O); |
190 | 528 | if (Opcode == ARM_t2STMDB_UPD) |
191 | 212 | SStream_concat0(O, ".w"); |
192 | 528 | SStream_concat0(O, " "); |
193 | | |
194 | 528 | printRegisterList(MI, 4, O); |
195 | 528 | if (useAliasDetails) |
196 | 528 | return; |
197 | 0 | else |
198 | 0 | goto add_real_detail; |
199 | 528 | } else |
200 | 417 | break; |
201 | | |
202 | 1.31k | case ARM_STR_PRE_IMM: |
203 | 1.31k | if (MCOperand_getReg(MCInst_getOperand(MI, (2))) == ARM_SP && |
204 | 1.31k | MCOperand_getImm(MCInst_getOperand(MI, (3))) == -4) { |
205 | 0 | isAlias = true; |
206 | 0 | MCInst_setIsAlias(MI, isAlias); |
207 | 0 | SStream_concat1(O, ' '); |
208 | 0 | SStream_concat0(O, "push"); |
209 | 0 | printPredicateOperand(MI, 4, O); |
210 | 0 | SStream_concat0(O, " {"); |
211 | 0 | printOperand(MI, 1, O); |
212 | 0 | SStream_concat0(O, "}"); |
213 | 0 | if (useAliasDetails) |
214 | 0 | return; |
215 | 0 | else |
216 | 0 | goto add_real_detail; |
217 | 0 | } else |
218 | 1.31k | break; |
219 | | |
220 | | // A8.6.122 POP |
221 | 284 | case ARM_LDMIA_UPD: |
222 | 1.15k | case ARM_t2LDMIA_UPD: |
223 | 1.15k | if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP && |
224 | 1.15k | MCInst_getNumOperands(MI) > 5) { |
225 | 428 | isAlias = true; |
226 | 428 | MCInst_setIsAlias(MI, isAlias); |
227 | | // Should only print POP if there are at least two registers in the |
228 | | // list. |
229 | 428 | SStream_concat0(O, "pop"); |
230 | 428 | printPredicateOperand(MI, 2, O); |
231 | 428 | if (Opcode == ARM_t2LDMIA_UPD) |
232 | 388 | SStream_concat0(O, ".w"); |
233 | 428 | SStream_concat0(O, " "); |
234 | | |
235 | 428 | printRegisterList(MI, 4, O); |
236 | 428 | if (useAliasDetails) |
237 | 428 | return; |
238 | 0 | else |
239 | 0 | goto add_real_detail; |
240 | 428 | } else |
241 | 729 | break; |
242 | | |
243 | 1.11k | case ARM_LDR_POST_IMM: |
244 | 1.11k | if ((MCOperand_getReg(MCInst_getOperand(MI, (2))) == ARM_SP) && |
245 | 1.11k | ((ARM_AM_getAM2Offset(MCOperand_getImm( |
246 | 670 | MCInst_getOperand(MI, (4)))) == 4))) { |
247 | 445 | isAlias = true; |
248 | 445 | MCInst_setIsAlias(MI, isAlias); |
249 | 445 | SStream_concat0(O, "pop"); |
250 | 445 | printPredicateOperand(MI, 5, O); |
251 | 445 | SStream_concat0(O, " {"); |
252 | 445 | printOperand(MI, 0, O); |
253 | 445 | SStream_concat0(O, "}"); |
254 | 445 | if (useAliasDetails) |
255 | 445 | return; |
256 | 0 | else |
257 | 0 | goto add_real_detail; |
258 | 445 | } else |
259 | 667 | break; |
260 | 313 | case ARM_t2LDR_POST: |
261 | 313 | if ((MCOperand_getReg(MCInst_getOperand(MI, (2))) == ARM_SP) && |
262 | 313 | (Opcode == ARM_t2LDR_POST && |
263 | 102 | (MCOperand_getImm(MCInst_getOperand(MI, (3))) == 4))) { |
264 | 21 | isAlias = true; |
265 | 21 | MCInst_setIsAlias(MI, isAlias); |
266 | 21 | SStream_concat0(O, "pop"); |
267 | 21 | printPredicateOperand(MI, 4, O); |
268 | 21 | SStream_concat0(O, " {"); |
269 | 21 | printOperand(MI, 0, O); |
270 | 21 | SStream_concat0(O, "}"); |
271 | 21 | if (useAliasDetails) |
272 | 21 | return; |
273 | 0 | else |
274 | 0 | goto add_real_detail; |
275 | 21 | } else |
276 | 292 | break; |
277 | | |
278 | | // A8.6.355 VPUSH |
279 | 97 | case ARM_VSTMSDB_UPD: |
280 | 499 | case ARM_VSTMDDB_UPD: |
281 | 499 | if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP) { |
282 | 168 | isAlias = true; |
283 | 168 | MCInst_setIsAlias(MI, isAlias); |
284 | 168 | SStream_concat0(O, "vpush"); |
285 | 168 | printPredicateOperand(MI, 2, O); |
286 | 168 | SStream_concat0(O, " "); |
287 | | |
288 | 168 | printRegisterList(MI, 4, O); |
289 | 168 | if (useAliasDetails) |
290 | 168 | return; |
291 | 0 | else |
292 | 0 | goto add_real_detail; |
293 | 168 | } else |
294 | 331 | break; |
295 | | |
296 | | // A8.6.354 VPOP |
297 | 494 | case ARM_VLDMSIA_UPD: |
298 | 580 | case ARM_VLDMDIA_UPD: |
299 | 580 | if (MCOperand_getReg(MCInst_getOperand(MI, (0))) == ARM_SP) { |
300 | 79 | isAlias = true; |
301 | 79 | MCInst_setIsAlias(MI, isAlias); |
302 | 79 | SStream_concat1(O, ' '); |
303 | 79 | SStream_concat0(O, "vpop"); |
304 | 79 | printPredicateOperand(MI, 2, O); |
305 | 79 | SStream_concat0(O, " "); |
306 | | |
307 | 79 | printRegisterList(MI, 4, O); |
308 | 79 | if (useAliasDetails) |
309 | 79 | return; |
310 | 0 | else |
311 | 0 | goto add_real_detail; |
312 | 79 | } else |
313 | 501 | break; |
314 | | |
315 | 18.2k | case ARM_tLDMIA: { |
316 | 18.2k | isAlias = true; |
317 | 18.2k | MCInst_setIsAlias(MI, isAlias); |
318 | 18.2k | bool Writeback = true; |
319 | 18.2k | unsigned BaseReg = MCOperand_getReg(MCInst_getOperand(MI, (0))); |
320 | 101k | for (unsigned i = 3; i < MCInst_getNumOperands(MI); ++i) { |
321 | 82.8k | if (MCOperand_getReg(MCInst_getOperand(MI, (i))) == |
322 | 82.8k | BaseReg) |
323 | 9.35k | Writeback = false; |
324 | 82.8k | } |
325 | | |
326 | 18.2k | SStream_concat0(O, "ldm"); |
327 | | |
328 | 18.2k | printPredicateOperand(MI, 1, O); |
329 | 18.2k | SStream_concat0(O, " "); |
330 | | |
331 | 18.2k | printOperand(MI, 0, O); |
332 | 18.2k | if (Writeback) { |
333 | 8.93k | SStream_concat0(O, "!"); |
334 | 8.93k | } |
335 | 18.2k | SStream_concat0(O, ", "); |
336 | 18.2k | printRegisterList(MI, 3, O); |
337 | 18.2k | if (useAliasDetails) |
338 | 18.2k | return; |
339 | 0 | else |
340 | 0 | goto add_real_detail; |
341 | 18.2k | } |
342 | | |
343 | | // Combine 2 GPRs from disassember into a GPRPair to match with instr def. |
344 | | // ldrexd/strexd require even/odd GPR pair. To enforce this constraint, |
345 | | // a single GPRPair reg operand is used in the .td file to replace the two |
346 | | // GPRs. However, when decoding them, the two GRPs cannot be automatically |
347 | | // expressed as a GPRPair, so we have to manually merge them. |
348 | | // FIXME: We would really like to be able to tablegen'erate this. |
349 | 220 | case ARM_LDREXD: |
350 | 274 | case ARM_STREXD: |
351 | 355 | case ARM_LDAEXD: |
352 | 990 | case ARM_STLEXD: { |
353 | 990 | const MCRegisterClass *MRC = |
354 | 990 | MCRegisterInfo_getRegClass(MI->MRI, ARM_GPRRegClassID); |
355 | 990 | bool isStore = Opcode == ARM_STREXD || Opcode == ARM_STLEXD; |
356 | 990 | unsigned Reg = MCOperand_getReg( |
357 | 990 | MCInst_getOperand(MI, isStore ? 1 : 0)); |
358 | | |
359 | 990 | if (MCRegisterClass_contains(MRC, Reg)) { |
360 | 0 | MCInst NewMI; |
361 | |
|
362 | 0 | MCInst_Init(&NewMI); |
363 | 0 | MCInst_setOpcode(&NewMI, Opcode); |
364 | |
|
365 | 0 | if (isStore) |
366 | 0 | MCInst_addOperand2(&NewMI, |
367 | 0 | MCInst_getOperand(MI, 0)); |
368 | |
|
369 | 0 | MCOperand_CreateReg0( |
370 | 0 | &NewMI, |
371 | 0 | MCRegisterInfo_getMatchingSuperReg( |
372 | 0 | MI->MRI, Reg, ARM_gsub_0, |
373 | 0 | MCRegisterInfo_getRegClass( |
374 | 0 | MI->MRI, ARM_GPRPairRegClassID))); |
375 | | |
376 | | // Copy the rest operands into NewMI. |
377 | 0 | for (unsigned i = isStore ? 3 : 2; |
378 | 0 | i < MCInst_getNumOperands(MI); ++i) |
379 | 0 | MCInst_addOperand2(&NewMI, |
380 | 0 | MCInst_getOperand(MI, i)); |
381 | |
|
382 | 0 | printInstruction(&NewMI, Address, O); |
383 | 0 | return; |
384 | 0 | } |
385 | 990 | break; |
386 | 990 | } |
387 | 990 | case ARM_TSB: |
388 | 86 | case ARM_t2TSB: |
389 | 86 | isAlias = true; |
390 | 86 | MCInst_setIsAlias(MI, isAlias); |
391 | | |
392 | 86 | SStream_concat0(O, " tsb csync"); |
393 | 86 | if (useAliasDetails) |
394 | 86 | return; |
395 | 0 | else |
396 | 0 | goto add_real_detail; |
397 | 1.56k | case ARM_t2DSB: |
398 | 1.56k | isAlias = true; |
399 | 1.56k | MCInst_setIsAlias(MI, isAlias); |
400 | | |
401 | 1.56k | switch (MCOperand_getImm(MCInst_getOperand(MI, (0)))) { |
402 | 701 | default: |
403 | 701 | if (!printAliasInstr(MI, Address, O)) |
404 | 701 | printInstruction(MI, Address, O); |
405 | 701 | break; |
406 | 635 | case 0: |
407 | 635 | SStream_concat0(O, " ssbb"); |
408 | 635 | break; |
409 | 229 | case 4: |
410 | 229 | SStream_concat0(O, " pssbb"); |
411 | 229 | break; |
412 | 1.56k | }; |
413 | 1.56k | if (useAliasDetails) |
414 | 1.56k | return; |
415 | 0 | else |
416 | 0 | goto add_real_detail; |
417 | 1.47M | } |
418 | | |
419 | 1.45M | if (!isAlias) |
420 | 1.45M | isAlias |= printAliasInstr(MI, Address, O); |
421 | | |
422 | 1.45M | add_real_detail: |
423 | 1.45M | MCInst_setIsAlias(MI, isAlias); |
424 | 1.45M | if (!isAlias || !useAliasDetails) { |
425 | 1.45M | map_set_fill_detail_ops(MI, !(isAlias && useAliasDetails)); |
426 | 1.45M | if (isAlias) |
427 | 0 | SStream_Close(O); |
428 | 1.45M | printInstruction(MI, Address, O); |
429 | 1.45M | if (isAlias) |
430 | 0 | SStream_Open(O); |
431 | 1.45M | } |
432 | 1.45M | } |
433 | | |
434 | | static void printOperand(MCInst *MI, unsigned OpNo, SStream *O) |
435 | 2.41M | { |
436 | 2.41M | add_cs_detail(MI, ARM_OP_GROUP_Operand, OpNo); |
437 | 2.41M | MCOperand *Op = MCInst_getOperand(MI, (OpNo)); |
438 | 2.41M | if (MCOperand_isReg(Op)) { |
439 | 1.99M | unsigned Reg = MCOperand_getReg(Op); |
440 | 1.99M | printRegName(O, Reg); |
441 | 1.99M | } else if (MCOperand_isImm(Op)) { |
442 | 428k | SStream_concat(O, "%s", markup("<imm:")); |
443 | 428k | SStream_concat1(O, '#'); |
444 | 428k | printInt64(O, MCOperand_getImm(Op)); |
445 | 428k | SStream_concat0(O, markup(">")); |
446 | 428k | } else { |
447 | 0 | assert(0 && "Expressions are not supported."); |
448 | 0 | } |
449 | 2.41M | } |
450 | | |
451 | | void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O) |
452 | 69.7k | { |
453 | 69.7k | MCOperand *Op = MCInst_getOperand(MI, (OpNum)); |
454 | 69.7k | if (!MCOperand_isImm(Op) || MI->csh->PrintBranchImmNotAsAddress || |
455 | 69.7k | getUseMarkup()) { |
456 | 0 | printOperand(MI, OpNum, O); |
457 | 0 | return; |
458 | 0 | } |
459 | 69.7k | int64_t Imm = MCOperand_getImm(Op); |
460 | | // For ARM instructions the PC offset is 8 bytes, for Thumb instructions it |
461 | | // is 4 bytes. |
462 | 69.7k | uint64_t Offset = ARM_getFeatureBits(MI->csh->mode, ARM_ModeThumb) ? 4 : |
463 | 69.7k | 8; |
464 | | |
465 | | // A Thumb instruction BLX(i) can be 16-bit aligned while targets Arm code |
466 | | // which is 32-bit aligned. The target address for the case is calculated as |
467 | | // targetAddress = Align(PC,4) + imm32; |
468 | | // where |
469 | | // Align(x, y) = y * (x DIV y); |
470 | 69.7k | if (MCInst_getOpcode(MI) == ARM_tBLXi) |
471 | 473 | Address &= ~0x3; |
472 | | |
473 | 69.7k | uint64_t Target = Address + Imm + Offset; |
474 | | |
475 | 69.7k | Target &= 0xffffffff; |
476 | 69.7k | ARM_set_detail_op_imm(MI, OpNum, ARM_OP_IMM, Target); |
477 | 69.7k | printUInt64(O, Target); |
478 | 69.7k | } |
479 | | |
480 | | void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O) |
481 | 31.3k | { |
482 | 31.3k | add_cs_detail(MI, ARM_OP_GROUP_ThumbLdrLabelOperand, OpNum); |
483 | 31.3k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
484 | 31.3k | if (MCOperand_isExpr(MO1)) { |
485 | | // MO1.getExpr()->print(O, &MAI); |
486 | 0 | return; |
487 | 0 | } |
488 | | |
489 | 31.3k | SStream_concat(O, "%s", markup("<mem:")); |
490 | 31.3k | SStream_concat0(O, "[pc, "); |
491 | | |
492 | 31.3k | int32_t OffImm = (int32_t)MCOperand_getImm(MO1); |
493 | 31.3k | bool isSub = OffImm < 0; |
494 | | |
495 | | // Special value for #-0. All others are normal. |
496 | 31.3k | if (OffImm == INT32_MIN) |
497 | 834 | OffImm = 0; |
498 | 31.3k | if (isSub) { |
499 | 5.87k | SStream_concat(O, "%s", markup("<imm:")); |
500 | 5.87k | printInt32Bang(O, OffImm); |
501 | 5.87k | SStream_concat0(O, markup(">")); |
502 | 25.5k | } else { |
503 | 25.5k | SStream_concat(O, "%s", markup("<imm:")); |
504 | 25.5k | printInt32Bang(O, OffImm); |
505 | 25.5k | SStream_concat0(O, markup(">")); |
506 | 25.5k | } |
507 | 31.3k | SStream_concat(O, "%s", "]"); |
508 | 31.3k | SStream_concat0(O, markup(">")); |
509 | 31.3k | } |
510 | | |
511 | | // so_reg is a 4-operand unit corresponding to register forms of the A5.1 |
512 | | // "Addressing Mode 1 - Data-processing operands" forms. This includes: |
513 | | // REG 0 0 - e.g. R5 |
514 | | // REG REG 0,SH_OPC - e.g. R5, ROR R3 |
515 | | // REG 0 IMM,SH_OPC - e.g. R5, LSL #3 |
516 | | void printSORegRegOperand(MCInst *MI, unsigned OpNum, SStream *O) |
517 | 7.10k | { |
518 | 7.10k | add_cs_detail(MI, ARM_OP_GROUP_SORegRegOperand, OpNum); |
519 | 7.10k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
520 | 7.10k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); |
521 | 7.10k | MCOperand *MO3 = MCInst_getOperand(MI, (OpNum + 2)); |
522 | | |
523 | 7.10k | printRegName(O, MCOperand_getReg(MO1)); |
524 | | |
525 | | // Print the shift opc. |
526 | 7.10k | ARM_AM_ShiftOpc ShOpc = ARM_AM_getSORegShOp(MCOperand_getImm(MO3)); |
527 | 7.10k | SStream_concat(O, "%s", ", "); |
528 | 7.10k | SStream_concat0(O, ARM_AM_getShiftOpcStr(ShOpc)); |
529 | 7.10k | if (ShOpc == ARM_AM_rrx) |
530 | 0 | return; |
531 | | |
532 | 7.10k | SStream_concat0(O, " "); |
533 | | |
534 | 7.10k | printRegName(O, MCOperand_getReg(MO2)); |
535 | 7.10k | } |
536 | | |
537 | | void printSORegImmOperand(MCInst *MI, unsigned OpNum, SStream *O) |
538 | 12.6k | { |
539 | 12.6k | add_cs_detail(MI, ARM_OP_GROUP_SORegImmOperand, OpNum); |
540 | 12.6k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
541 | 12.6k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); |
542 | | |
543 | 12.6k | printRegName(O, MCOperand_getReg(MO1)); |
544 | | |
545 | | // Print the shift opc. |
546 | 12.6k | printRegImmShift(MI, O, ARM_AM_getSORegShOp(MCOperand_getImm(MO2)), |
547 | 12.6k | ARM_AM_getSORegOffset(MCOperand_getImm(MO2)), |
548 | 12.6k | getUseMarkup()); |
549 | 12.6k | } |
550 | | |
551 | | //===--------------------------------------------------------------------===// |
552 | | // Addressing Mode #2 |
553 | | //===--------------------------------------------------------------------===// |
554 | | |
555 | | void printAM2PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O) |
556 | 5.03k | { |
557 | 5.03k | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); |
558 | 5.03k | MCOperand *MO2 = MCInst_getOperand(MI, (Op + 1)); |
559 | 5.03k | MCOperand *MO3 = MCInst_getOperand(MI, (Op + 2)); |
560 | | |
561 | 5.03k | SStream_concat(O, "%s", markup("<mem:")); |
562 | 5.03k | SStream_concat0(O, "["); |
563 | 5.03k | printRegName(O, MCOperand_getReg(MO1)); |
564 | | |
565 | 5.03k | if (!MCOperand_getReg(MO2)) { |
566 | 0 | if (ARM_AM_getAM2Offset( |
567 | 0 | MCOperand_getImm(MO3))) { // Don't print +0. |
568 | 0 | SStream_concat( |
569 | 0 | O, "%s%s%s", ", ", markup("<imm:"), "#", |
570 | 0 | ARM_AM_getAddrOpcStr( |
571 | 0 | ARM_AM_getAM2Op(MCOperand_getImm(MO3))), |
572 | 0 | ARM_AM_getAM2Offset(MCOperand_getImm(MO3))); |
573 | 0 | SStream_concat0(O, markup(">")); |
574 | 0 | } |
575 | 0 | SStream_concat(O, "%s", "]"); |
576 | 0 | SStream_concat0(O, markup(">")); |
577 | 0 | return; |
578 | 0 | } |
579 | | |
580 | 5.03k | SStream_concat0(O, ", "); |
581 | 5.03k | SStream_concat0(O, ARM_AM_getAddrOpcStr( |
582 | 5.03k | ARM_AM_getAM2Op(MCOperand_getImm(MO3)))); |
583 | 5.03k | printRegName(O, MCOperand_getReg(MO2)); |
584 | | |
585 | 5.03k | printRegImmShift(MI, O, ARM_AM_getAM2ShiftOpc(MCOperand_getImm(MO3)), |
586 | 5.03k | ARM_AM_getAM2Offset(MCOperand_getImm(MO3)), |
587 | 5.03k | getUseMarkup()); |
588 | 5.03k | SStream_concat(O, "%s", "]"); |
589 | 5.03k | SStream_concat0(O, markup(">")); |
590 | 5.03k | } |
591 | | |
592 | | void printAddrModeTBB(MCInst *MI, unsigned Op, SStream *O) |
593 | 77 | { |
594 | 77 | add_cs_detail(MI, ARM_OP_GROUP_AddrModeTBB, Op); |
595 | 77 | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); |
596 | 77 | MCOperand *MO2 = MCInst_getOperand(MI, (Op + 1)); |
597 | 77 | SStream_concat(O, "%s", markup("<mem:")); |
598 | 77 | SStream_concat0(O, "["); |
599 | 77 | printRegName(O, MCOperand_getReg(MO1)); |
600 | 77 | SStream_concat0(O, ", "); |
601 | 77 | printRegName(O, MCOperand_getReg(MO2)); |
602 | 77 | SStream_concat(O, "%s", "]"); |
603 | 77 | SStream_concat0(O, markup(">")); |
604 | 77 | } |
605 | | |
606 | | void printAddrModeTBH(MCInst *MI, unsigned Op, SStream *O) |
607 | 446 | { |
608 | 446 | add_cs_detail(MI, ARM_OP_GROUP_AddrModeTBH, Op); |
609 | 446 | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); |
610 | 446 | MCOperand *MO2 = MCInst_getOperand(MI, (Op + 1)); |
611 | 446 | SStream_concat(O, "%s", markup("<mem:")); |
612 | 446 | SStream_concat0(O, "["); |
613 | 446 | printRegName(O, MCOperand_getReg(MO1)); |
614 | 446 | SStream_concat0(O, ", "); |
615 | 446 | printRegName(O, MCOperand_getReg(MO2)); |
616 | 446 | SStream_concat(O, "%s%s%s%s%s", ", lsl ", markup("<imm:"), "#1", |
617 | 446 | markup(">"), "]"); |
618 | 446 | SStream_concat0(O, markup(">")); |
619 | 446 | } |
620 | | |
621 | | void printAddrMode2Operand(MCInst *MI, unsigned Op, SStream *O) |
622 | 5.03k | { |
623 | 5.03k | add_cs_detail(MI, ARM_OP_GROUP_AddrMode2Operand, Op); |
624 | 5.03k | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); |
625 | | |
626 | 5.03k | if (!MCOperand_isReg( |
627 | 5.03k | MO1)) { // FIXME: This is for CP entries, but isn't right. |
628 | 0 | printOperand(MI, Op, O); |
629 | 0 | return; |
630 | 0 | } |
631 | | |
632 | 5.03k | printAM2PreOrOffsetIndexOp(MI, Op, O); |
633 | 5.03k | } |
634 | | |
635 | | void printAddrMode2OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O) |
636 | 10.0k | { |
637 | 10.0k | add_cs_detail(MI, ARM_OP_GROUP_AddrMode2OffsetOperand, OpNum); |
638 | 10.0k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
639 | 10.0k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); |
640 | | |
641 | 10.0k | if (!MCOperand_getReg(MO1)) { |
642 | 5.92k | unsigned ImmOffs = ARM_AM_getAM2Offset(MCOperand_getImm(MO2)); |
643 | 5.92k | SStream_concat(O, "%s", markup("<imm:")); |
644 | 5.92k | SStream_concat1(O, '#'); |
645 | 5.92k | SStream_concat(O, "%s", |
646 | 5.92k | ARM_AM_getAddrOpcStr( |
647 | 5.92k | ARM_AM_getAM2Op(MCOperand_getImm(MO2)))); |
648 | 5.92k | printUInt32(O, ImmOffs); |
649 | 5.92k | SStream_concat0(O, markup(">")); |
650 | 5.92k | return; |
651 | 5.92k | } |
652 | | |
653 | 4.10k | SStream_concat0(O, ARM_AM_getAddrOpcStr( |
654 | 4.10k | ARM_AM_getAM2Op(MCOperand_getImm(MO2)))); |
655 | 4.10k | printRegName(O, MCOperand_getReg(MO1)); |
656 | | |
657 | 4.10k | printRegImmShift(MI, O, ARM_AM_getAM2ShiftOpc(MCOperand_getImm(MO2)), |
658 | 4.10k | ARM_AM_getAM2Offset(MCOperand_getImm(MO2)), |
659 | 4.10k | getUseMarkup()); |
660 | 4.10k | } |
661 | | |
662 | | //===--------------------------------------------------------------------===// |
663 | | // Addressing Mode #3 |
664 | | //===--------------------------------------------------------------------===// |
665 | | |
666 | | void printAM3PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O, |
667 | | bool AlwaysPrintImm0) |
668 | 5.19k | { |
669 | 5.19k | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); |
670 | 5.19k | MCOperand *MO2 = MCInst_getOperand(MI, (Op + 1)); |
671 | 5.19k | MCOperand *MO3 = MCInst_getOperand(MI, (Op + 2)); |
672 | | |
673 | 5.19k | SStream_concat(O, "%s", markup("<mem:")); |
674 | 5.19k | SStream_concat0(O, "["); |
675 | | |
676 | 5.19k | printRegName(O, MCOperand_getReg(MO1)); |
677 | | |
678 | 5.19k | if (MCOperand_getReg(MO2)) { |
679 | 2.23k | SStream_concat(O, "%s", ", "); |
680 | 2.23k | SStream_concat0(O, ARM_AM_getAddrOpcStr(ARM_AM_getAM3Op( |
681 | 2.23k | MCOperand_getImm(MO3)))); |
682 | 2.23k | printRegName(O, MCOperand_getReg(MO2)); |
683 | 2.23k | SStream_concat1(O, ']'); |
684 | 2.23k | SStream_concat0(O, markup(">")); |
685 | 2.23k | return; |
686 | 2.23k | } |
687 | | |
688 | | // If the op is sub we have to print the immediate even if it is 0 |
689 | 2.95k | unsigned ImmOffs = ARM_AM_getAM3Offset(MCOperand_getImm(MO3)); |
690 | 2.95k | ARM_AM_AddrOpc op = ARM_AM_getAM3Op(MCOperand_getImm(MO3)); |
691 | | |
692 | 2.95k | if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM_sub)) { |
693 | 2.91k | SStream_concat(O, "%s%s%s%s", ", ", markup("<imm:"), "#", |
694 | 2.91k | ARM_AM_getAddrOpcStr(op)); |
695 | 2.91k | printUInt32(O, ImmOffs); |
696 | 2.91k | SStream_concat0(O, markup(">")); |
697 | 2.91k | } |
698 | 2.95k | SStream_concat1(O, ']'); |
699 | 2.95k | SStream_concat0(O, markup(">")); |
700 | 2.95k | } |
701 | | |
702 | | #define DEFINE_printAddrMode3Operand(AlwaysPrintImm0) \ |
703 | | void CONCAT(printAddrMode3Operand, \ |
704 | | AlwaysPrintImm0)(MCInst * MI, unsigned Op, SStream *O) \ |
705 | 5.19k | { \ |
706 | 5.19k | add_cs_detail(MI, \ |
707 | 5.19k | CONCAT(ARM_OP_GROUP_AddrMode3Operand, \ |
708 | 5.19k | AlwaysPrintImm0), \ |
709 | 5.19k | Op, AlwaysPrintImm0); \ |
710 | 5.19k | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); \ |
711 | 5.19k | if (!MCOperand_isReg(MO1)) { \ |
712 | 0 | printOperand(MI, Op, O); \ |
713 | 0 | return; \ |
714 | 0 | } \ |
715 | 5.19k | \ |
716 | 5.19k | printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0); \ |
717 | 5.19k | } Line | Count | Source | 705 | 2.60k | { \ | 706 | 2.60k | add_cs_detail(MI, \ | 707 | 2.60k | CONCAT(ARM_OP_GROUP_AddrMode3Operand, \ | 708 | 2.60k | AlwaysPrintImm0), \ | 709 | 2.60k | Op, AlwaysPrintImm0); \ | 710 | 2.60k | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); \ | 711 | 2.60k | if (!MCOperand_isReg(MO1)) { \ | 712 | 0 | printOperand(MI, Op, O); \ | 713 | 0 | return; \ | 714 | 0 | } \ | 715 | 2.60k | \ | 716 | 2.60k | printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0); \ | 717 | 2.60k | } |
Line | Count | Source | 705 | 2.58k | { \ | 706 | 2.58k | add_cs_detail(MI, \ | 707 | 2.58k | CONCAT(ARM_OP_GROUP_AddrMode3Operand, \ | 708 | 2.58k | AlwaysPrintImm0), \ | 709 | 2.58k | Op, AlwaysPrintImm0); \ | 710 | 2.58k | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); \ | 711 | 2.58k | if (!MCOperand_isReg(MO1)) { \ | 712 | 0 | printOperand(MI, Op, O); \ | 713 | 0 | return; \ | 714 | 0 | } \ | 715 | 2.58k | \ | 716 | 2.58k | printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0); \ | 717 | 2.58k | } |
|
718 | | DEFINE_printAddrMode3Operand(false) DEFINE_printAddrMode3Operand(true) |
719 | | |
720 | | void printAddrMode3OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O) |
721 | 4.64k | { |
722 | 4.64k | add_cs_detail(MI, ARM_OP_GROUP_AddrMode3OffsetOperand, OpNum); |
723 | 4.64k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
724 | 4.64k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); |
725 | | |
726 | 4.64k | if (MCOperand_getReg(MO1)) { |
727 | 3.08k | SStream_concat0(O, ARM_AM_getAddrOpcStr(ARM_AM_getAM3Op( |
728 | 3.08k | MCOperand_getImm(MO2)))); |
729 | 3.08k | printRegName(O, MCOperand_getReg(MO1)); |
730 | 3.08k | return; |
731 | 3.08k | } |
732 | | |
733 | 1.56k | unsigned ImmOffs = ARM_AM_getAM3Offset(MCOperand_getImm(MO2)); |
734 | 1.56k | SStream_concat(O, "%s", markup("<imm:")); |
735 | 1.56k | SStream_concat1(O, '#'); |
736 | 1.56k | SStream_concat( |
737 | 1.56k | O, "%s", |
738 | 1.56k | ARM_AM_getAddrOpcStr(ARM_AM_getAM3Op(MCOperand_getImm(MO2)))); |
739 | 1.56k | printUInt32(O, ImmOffs); |
740 | 1.56k | SStream_concat0(O, markup(">")); |
741 | 1.56k | } |
742 | | |
743 | | void printPostIdxImm8Operand(MCInst *MI, unsigned OpNum, SStream *O) |
744 | 670 | { |
745 | 670 | add_cs_detail(MI, ARM_OP_GROUP_PostIdxImm8Operand, OpNum); |
746 | 670 | MCOperand *MO = MCInst_getOperand(MI, (OpNum)); |
747 | 670 | unsigned Imm = MCOperand_getImm(MO); |
748 | 670 | SStream_concat(O, "%s", markup("<imm:")); |
749 | 670 | SStream_concat1(O, '#'); |
750 | 670 | SStream_concat(O, "%s", ((Imm & 256) ? "" : "-")); |
751 | 670 | printUInt32(O, (Imm & 0xff)); |
752 | 670 | SStream_concat0(O, markup(">")); |
753 | 670 | } |
754 | | |
755 | | void printPostIdxRegOperand(MCInst *MI, unsigned OpNum, SStream *O) |
756 | 1.46k | { |
757 | 1.46k | add_cs_detail(MI, ARM_OP_GROUP_PostIdxRegOperand, OpNum); |
758 | 1.46k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
759 | 1.46k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); |
760 | | |
761 | 1.46k | SStream_concat0(O, (MCOperand_getImm(MO2) ? "" : "-")); |
762 | 1.46k | printRegName(O, MCOperand_getReg(MO1)); |
763 | 1.46k | } |
764 | | |
765 | | void printPostIdxImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O) |
766 | 10.5k | { |
767 | 10.5k | add_cs_detail(MI, ARM_OP_GROUP_PostIdxImm8s4Operand, OpNum); |
768 | 10.5k | MCOperand *MO = MCInst_getOperand(MI, (OpNum)); |
769 | 10.5k | unsigned Imm = MCOperand_getImm(MO); |
770 | 10.5k | SStream_concat(O, "%s", markup("<imm:")); |
771 | 10.5k | SStream_concat1(O, '#'); |
772 | 10.5k | SStream_concat(O, "%s", ((Imm & 256) ? "" : "-")); |
773 | 10.5k | printUInt32(O, (Imm & 0xff) << 2); |
774 | 10.5k | SStream_concat0(O, markup(">")); |
775 | 10.5k | } |
776 | | |
777 | | #define DEFINE_printMveAddrModeRQOperand(shift) \ |
778 | | void CONCAT(printMveAddrModeRQOperand, \ |
779 | | shift)(MCInst * MI, unsigned OpNum, SStream *O) \ |
780 | 499 | { \ |
781 | 499 | add_cs_detail( \ |
782 | 499 | MI, CONCAT(ARM_OP_GROUP_MveAddrModeRQOperand, shift), \ |
783 | 499 | OpNum, shift); \ |
784 | 499 | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ |
785 | 499 | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ |
786 | 499 | \ |
787 | 499 | SStream_concat(O, "%s", markup("<mem:")); \ |
788 | 499 | SStream_concat0(O, "["); \ |
789 | 499 | printRegName(O, MCOperand_getReg(MO1)); \ |
790 | 499 | SStream_concat0(O, ", "); \ |
791 | 499 | printRegName(O, MCOperand_getReg(MO2)); \ |
792 | 499 | \ |
793 | 499 | if (shift > 0) \ |
794 | 499 | printRegImmShift(MI, O, ARM_AM_uxtw, shift, \ |
795 | 403 | getUseMarkup()); \ |
796 | 499 | \ |
797 | 499 | SStream_concat(O, "%s", "]"); \ |
798 | 499 | SStream_concat0(O, markup(">")); \ |
799 | 499 | } printMveAddrModeRQOperand_0 Line | Count | Source | 780 | 96 | { \ | 781 | 96 | add_cs_detail( \ | 782 | 96 | MI, CONCAT(ARM_OP_GROUP_MveAddrModeRQOperand, shift), \ | 783 | 96 | OpNum, shift); \ | 784 | 96 | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 785 | 96 | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 786 | 96 | \ | 787 | 96 | SStream_concat(O, "%s", markup("<mem:")); \ | 788 | 96 | SStream_concat0(O, "["); \ | 789 | 96 | printRegName(O, MCOperand_getReg(MO1)); \ | 790 | 96 | SStream_concat0(O, ", "); \ | 791 | 96 | printRegName(O, MCOperand_getReg(MO2)); \ | 792 | 96 | \ | 793 | 96 | if (shift > 0) \ | 794 | 96 | printRegImmShift(MI, O, ARM_AM_uxtw, shift, \ | 795 | 0 | getUseMarkup()); \ | 796 | 96 | \ | 797 | 96 | SStream_concat(O, "%s", "]"); \ | 798 | 96 | SStream_concat0(O, markup(">")); \ | 799 | 96 | } |
printMveAddrModeRQOperand_3 Line | Count | Source | 780 | 73 | { \ | 781 | 73 | add_cs_detail( \ | 782 | 73 | MI, CONCAT(ARM_OP_GROUP_MveAddrModeRQOperand, shift), \ | 783 | 73 | OpNum, shift); \ | 784 | 73 | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 785 | 73 | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 786 | 73 | \ | 787 | 73 | SStream_concat(O, "%s", markup("<mem:")); \ | 788 | 73 | SStream_concat0(O, "["); \ | 789 | 73 | printRegName(O, MCOperand_getReg(MO1)); \ | 790 | 73 | SStream_concat0(O, ", "); \ | 791 | 73 | printRegName(O, MCOperand_getReg(MO2)); \ | 792 | 73 | \ | 793 | 73 | if (shift > 0) \ | 794 | 73 | printRegImmShift(MI, O, ARM_AM_uxtw, shift, \ | 795 | 73 | getUseMarkup()); \ | 796 | 73 | \ | 797 | 73 | SStream_concat(O, "%s", "]"); \ | 798 | 73 | SStream_concat0(O, markup(">")); \ | 799 | 73 | } |
printMveAddrModeRQOperand_1 Line | Count | Source | 780 | 137 | { \ | 781 | 137 | add_cs_detail( \ | 782 | 137 | MI, CONCAT(ARM_OP_GROUP_MveAddrModeRQOperand, shift), \ | 783 | 137 | OpNum, shift); \ | 784 | 137 | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 785 | 137 | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 786 | 137 | \ | 787 | 137 | SStream_concat(O, "%s", markup("<mem:")); \ | 788 | 137 | SStream_concat0(O, "["); \ | 789 | 137 | printRegName(O, MCOperand_getReg(MO1)); \ | 790 | 137 | SStream_concat0(O, ", "); \ | 791 | 137 | printRegName(O, MCOperand_getReg(MO2)); \ | 792 | 137 | \ | 793 | 137 | if (shift > 0) \ | 794 | 137 | printRegImmShift(MI, O, ARM_AM_uxtw, shift, \ | 795 | 137 | getUseMarkup()); \ | 796 | 137 | \ | 797 | 137 | SStream_concat(O, "%s", "]"); \ | 798 | 137 | SStream_concat0(O, markup(">")); \ | 799 | 137 | } |
printMveAddrModeRQOperand_2 Line | Count | Source | 780 | 193 | { \ | 781 | 193 | add_cs_detail( \ | 782 | 193 | MI, CONCAT(ARM_OP_GROUP_MveAddrModeRQOperand, shift), \ | 783 | 193 | OpNum, shift); \ | 784 | 193 | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 785 | 193 | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 786 | 193 | \ | 787 | 193 | SStream_concat(O, "%s", markup("<mem:")); \ | 788 | 193 | SStream_concat0(O, "["); \ | 789 | 193 | printRegName(O, MCOperand_getReg(MO1)); \ | 790 | 193 | SStream_concat0(O, ", "); \ | 791 | 193 | printRegName(O, MCOperand_getReg(MO2)); \ | 792 | 193 | \ | 793 | 193 | if (shift > 0) \ | 794 | 193 | printRegImmShift(MI, O, ARM_AM_uxtw, shift, \ | 795 | 193 | getUseMarkup()); \ | 796 | 193 | \ | 797 | 193 | SStream_concat(O, "%s", "]"); \ | 798 | 193 | SStream_concat0(O, markup(">")); \ | 799 | 193 | } |
|
800 | | DEFINE_printMveAddrModeRQOperand(0) DEFINE_printMveAddrModeRQOperand(3) |
801 | | DEFINE_printMveAddrModeRQOperand(1) DEFINE_printMveAddrModeRQOperand(2) |
802 | | |
803 | | void printLdStmModeOperand(MCInst *MI, unsigned OpNum, |
804 | | SStream *O) |
805 | 0 | { |
806 | 0 | add_cs_detail(MI, ARM_OP_GROUP_LdStmModeOperand, OpNum); |
807 | 0 | ARM_AM_SubMode Mode = ARM_AM_getAM4SubMode( |
808 | 0 | MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); |
809 | 0 | SStream_concat0(O, ARM_AM_getAMSubModeStr(Mode)); |
810 | 0 | } |
811 | | |
812 | | #define DEFINE_printAddrMode5Operand(AlwaysPrintImm0) \ |
813 | | void CONCAT(printAddrMode5Operand, \ |
814 | | AlwaysPrintImm0)(MCInst * MI, unsigned OpNum, SStream *O) \ |
815 | 24.6k | { \ |
816 | 24.6k | add_cs_detail(MI, \ |
817 | 24.6k | CONCAT(ARM_OP_GROUP_AddrMode5Operand, \ |
818 | 24.6k | AlwaysPrintImm0), \ |
819 | 24.6k | OpNum, AlwaysPrintImm0); \ |
820 | 24.6k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ |
821 | 24.6k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ |
822 | 24.6k | \ |
823 | 24.6k | SStream_concat(O, "%s", markup("<mem:")); \ |
824 | 24.6k | SStream_concat0(O, "["); \ |
825 | 24.6k | printRegName(O, MCOperand_getReg(MO1)); \ |
826 | 24.6k | \ |
827 | 24.6k | unsigned ImmOffs = ARM_AM_getAM5Offset(MCOperand_getImm(MO2)); \ |
828 | 24.6k | ARM_AM_AddrOpc Op = ARM_AM_getAM5Op(MCOperand_getImm(MO2)); \ |
829 | 24.6k | if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM_sub) { \ |
830 | 24.4k | SStream_concat(O, "%s%s%s%s", ", ", markup("<imm:"), \ |
831 | 24.4k | "#", ARM_AM_getAddrOpcStr(Op)); \ |
832 | 24.4k | printUInt32(O, ImmOffs * 4); \ |
833 | 24.4k | SStream_concat0(O, markup(">")); \ |
834 | 24.4k | } \ |
835 | 24.6k | SStream_concat(O, "%s", "]"); \ |
836 | 24.6k | SStream_concat0(O, markup(">")); \ |
837 | 24.6k | } Line | Count | Source | 815 | 11.2k | { \ | 816 | 11.2k | add_cs_detail(MI, \ | 817 | 11.2k | CONCAT(ARM_OP_GROUP_AddrMode5Operand, \ | 818 | 11.2k | AlwaysPrintImm0), \ | 819 | 11.2k | OpNum, AlwaysPrintImm0); \ | 820 | 11.2k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 821 | 11.2k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 822 | 11.2k | \ | 823 | 11.2k | SStream_concat(O, "%s", markup("<mem:")); \ | 824 | 11.2k | SStream_concat0(O, "["); \ | 825 | 11.2k | printRegName(O, MCOperand_getReg(MO1)); \ | 826 | 11.2k | \ | 827 | 11.2k | unsigned ImmOffs = ARM_AM_getAM5Offset(MCOperand_getImm(MO2)); \ | 828 | 11.2k | ARM_AM_AddrOpc Op = ARM_AM_getAM5Op(MCOperand_getImm(MO2)); \ | 829 | 11.2k | if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM_sub) { \ | 830 | 11.0k | SStream_concat(O, "%s%s%s%s", ", ", markup("<imm:"), \ | 831 | 11.0k | "#", ARM_AM_getAddrOpcStr(Op)); \ | 832 | 11.0k | printUInt32(O, ImmOffs * 4); \ | 833 | 11.0k | SStream_concat0(O, markup(">")); \ | 834 | 11.0k | } \ | 835 | 11.2k | SStream_concat(O, "%s", "]"); \ | 836 | 11.2k | SStream_concat0(O, markup(">")); \ | 837 | 11.2k | } |
Line | Count | Source | 815 | 13.4k | { \ | 816 | 13.4k | add_cs_detail(MI, \ | 817 | 13.4k | CONCAT(ARM_OP_GROUP_AddrMode5Operand, \ | 818 | 13.4k | AlwaysPrintImm0), \ | 819 | 13.4k | OpNum, AlwaysPrintImm0); \ | 820 | 13.4k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 821 | 13.4k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 822 | 13.4k | \ | 823 | 13.4k | SStream_concat(O, "%s", markup("<mem:")); \ | 824 | 13.4k | SStream_concat0(O, "["); \ | 825 | 13.4k | printRegName(O, MCOperand_getReg(MO1)); \ | 826 | 13.4k | \ | 827 | 13.4k | unsigned ImmOffs = ARM_AM_getAM5Offset(MCOperand_getImm(MO2)); \ | 828 | 13.4k | ARM_AM_AddrOpc Op = ARM_AM_getAM5Op(MCOperand_getImm(MO2)); \ | 829 | 13.4k | if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM_sub) { \ | 830 | 13.4k | SStream_concat(O, "%s%s%s%s", ", ", markup("<imm:"), \ | 831 | 13.4k | "#", ARM_AM_getAddrOpcStr(Op)); \ | 832 | 13.4k | printUInt32(O, ImmOffs * 4); \ | 833 | 13.4k | SStream_concat0(O, markup(">")); \ | 834 | 13.4k | } \ | 835 | 13.4k | SStream_concat(O, "%s", "]"); \ | 836 | 13.4k | SStream_concat0(O, markup(">")); \ | 837 | 13.4k | } |
|
838 | | DEFINE_printAddrMode5Operand(false) DEFINE_printAddrMode5Operand(true) |
839 | | |
840 | | #define DEFINE_printAddrMode5FP16Operand(AlwaysPrintImm0) \ |
841 | | void CONCAT(printAddrMode5FP16Operand, \ |
842 | | AlwaysPrintImm0)(MCInst * MI, unsigned OpNum, SStream *O) \ |
843 | 339 | { \ |
844 | 339 | add_cs_detail(MI, \ |
845 | 339 | CONCAT(ARM_OP_GROUP_AddrMode5FP16Operand, \ |
846 | 339 | AlwaysPrintImm0), \ |
847 | 339 | OpNum, AlwaysPrintImm0); \ |
848 | 339 | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ |
849 | 339 | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ |
850 | 339 | \ |
851 | 339 | if (!MCOperand_isReg(MO1)) { \ |
852 | 0 | printOperand(MI, OpNum, O); \ |
853 | 0 | return; \ |
854 | 0 | } \ |
855 | 339 | \ |
856 | 339 | SStream_concat(O, "%s", markup("<mem:")); \ |
857 | 339 | SStream_concat0(O, "["); \ |
858 | 339 | printRegName(O, MCOperand_getReg(MO1)); \ |
859 | 339 | \ |
860 | 339 | unsigned ImmOffs = \ |
861 | 339 | ARM_AM_getAM5FP16Offset(MCOperand_getImm(MO2)); \ |
862 | 339 | unsigned Op = ARM_AM_getAM5FP16Op(MCOperand_getImm(MO2)); \ |
863 | 339 | if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM_sub) { \ |
864 | 307 | SStream_concat( \ |
865 | 307 | O, "%s%s%s%s", ", ", markup("<imm:"), "#", \ |
866 | 307 | ARM_AM_getAddrOpcStr(ARM_AM_getAM5FP16Op( \ |
867 | 307 | MCOperand_getImm(MO2)))); \ |
868 | 307 | printUInt32(O, ImmOffs * 2); \ |
869 | 307 | SStream_concat0(O, markup(">")); \ |
870 | 307 | } \ |
871 | 339 | SStream_concat(O, "%s", "]"); \ |
872 | 339 | SStream_concat0(O, markup(">")); \ |
873 | 339 | } |
874 | | DEFINE_printAddrMode5FP16Operand(false) |
875 | | |
876 | | void printAddrMode6Operand(MCInst *MI, unsigned OpNum, |
877 | | SStream *O) |
878 | 51.9k | { |
879 | 51.9k | add_cs_detail(MI, ARM_OP_GROUP_AddrMode6Operand, OpNum); |
880 | 51.9k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
881 | 51.9k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); |
882 | | |
883 | 51.9k | SStream_concat(O, "%s", markup("<mem:")); |
884 | 51.9k | SStream_concat0(O, "["); |
885 | 51.9k | printRegName(O, MCOperand_getReg(MO1)); |
886 | 51.9k | if (MCOperand_getImm(MO2)) { |
887 | 22.3k | SStream_concat(O, "%s", ":"); |
888 | 22.3k | printInt64(O, ((uint32_t)MCOperand_getImm(MO2)) << 3); |
889 | 22.3k | } |
890 | 51.9k | SStream_concat(O, "%s", "]"); |
891 | 51.9k | SStream_concat0(O, markup(">")); |
892 | 51.9k | } |
893 | | |
894 | | void printAddrMode7Operand(MCInst *MI, unsigned OpNum, SStream *O) |
895 | 44.4k | { |
896 | 44.4k | add_cs_detail(MI, ARM_OP_GROUP_AddrMode7Operand, OpNum); |
897 | 44.4k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
898 | 44.4k | SStream_concat(O, "%s", markup("<mem:")); |
899 | 44.4k | SStream_concat0(O, "["); |
900 | 44.4k | printRegName(O, MCOperand_getReg(MO1)); |
901 | 44.4k | SStream_concat(O, "%s", "]"); |
902 | 44.4k | SStream_concat0(O, markup(">")); |
903 | 44.4k | } |
904 | | |
905 | | void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O) |
906 | 18.8k | { |
907 | 18.8k | add_cs_detail(MI, ARM_OP_GROUP_AddrMode6OffsetOperand, OpNum); |
908 | 18.8k | MCOperand *MO = MCInst_getOperand(MI, (OpNum)); |
909 | 18.8k | if (MCOperand_getReg(MO) == 0) |
910 | 6.89k | SStream_concat0(O, "!"); |
911 | 11.9k | else { |
912 | 11.9k | SStream_concat0(O, ", "); |
913 | 11.9k | printRegName(O, MCOperand_getReg(MO)); |
914 | 11.9k | } |
915 | 18.8k | } |
916 | | |
917 | | void printBitfieldInvMaskImmOperand(MCInst *MI, unsigned OpNum, SStream *O) |
918 | 635 | { |
919 | 635 | add_cs_detail(MI, ARM_OP_GROUP_BitfieldInvMaskImmOperand, OpNum); |
920 | 635 | MCOperand *MO = MCInst_getOperand(MI, (OpNum)); |
921 | 635 | uint32_t v = ~MCOperand_getImm(MO); |
922 | 635 | int32_t lsb = CountTrailingZeros_32(v); |
923 | 635 | int32_t width = (32 - countLeadingZeros(v)) - lsb; |
924 | | |
925 | 635 | SStream_concat(O, "%s", markup("<imm:")); |
926 | 635 | SStream_concat1(O, '#'); |
927 | 635 | printInt32(O, lsb); |
928 | 635 | SStream_concat(O, "%s%s%s", markup(">"), ", ", markup("<imm:")); |
929 | 635 | printInt32Bang(O, width); |
930 | 635 | SStream_concat0(O, markup(">")); |
931 | 635 | } |
932 | | |
933 | | void printMemBOption(MCInst *MI, unsigned OpNum, SStream *O) |
934 | 2.18k | { |
935 | 2.18k | add_cs_detail(MI, ARM_OP_GROUP_MemBOption, OpNum); |
936 | 2.18k | unsigned val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
937 | 2.18k | SStream_concat0(O, ARM_MB_MemBOptToString( |
938 | 2.18k | val, ARM_getFeatureBits(MI->csh->mode, |
939 | 2.18k | ARM_HasV8Ops))); |
940 | 2.18k | } |
941 | | |
942 | | void printInstSyncBOption(MCInst *MI, unsigned OpNum, SStream *O) |
943 | 490 | { |
944 | 490 | add_cs_detail(MI, ARM_OP_GROUP_InstSyncBOption, OpNum); |
945 | 490 | unsigned val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
946 | 490 | SStream_concat0(O, ARM_ISB_InstSyncBOptToString(val)); |
947 | 490 | } |
948 | | |
949 | | void printTraceSyncBOption(MCInst *MI, unsigned OpNum, SStream *O) |
950 | 0 | { |
951 | 0 | add_cs_detail(MI, ARM_OP_GROUP_TraceSyncBOption, OpNum); |
952 | 0 | unsigned val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
953 | 0 | SStream_concat0(O, ARM_TSB_TraceSyncBOptToString(val)); |
954 | 0 | } |
955 | | |
956 | | void printShiftImmOperand(MCInst *MI, unsigned OpNum, SStream *O) |
957 | 2.29k | { |
958 | 2.29k | add_cs_detail(MI, ARM_OP_GROUP_ShiftImmOperand, OpNum); |
959 | 2.29k | unsigned ShiftOp = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
960 | 2.29k | bool isASR = (ShiftOp & (1 << 5)) != 0; |
961 | 2.29k | unsigned Amt = ShiftOp & 0x1f; |
962 | 2.29k | if (isASR) { |
963 | 953 | SStream_concat(O, "%s%s%s", ", asr ", markup("<imm:"), "#"); |
964 | 953 | printUInt32(O, Amt == 0 ? 32 : Amt); |
965 | 953 | SStream_concat0(O, markup(">")); |
966 | 1.34k | } else if (Amt) { |
967 | 1.03k | SStream_concat(O, "%s%s%s", ", lsl ", markup("<imm:"), "#"); |
968 | 1.03k | printUInt32(O, Amt); |
969 | 1.03k | SStream_concat0(O, markup(">")); |
970 | 1.03k | } |
971 | 2.29k | } |
972 | | |
973 | | void printPKHLSLShiftImm(MCInst *MI, unsigned OpNum, SStream *O) |
974 | 187 | { |
975 | 187 | add_cs_detail(MI, ARM_OP_GROUP_PKHLSLShiftImm, OpNum); |
976 | 187 | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
977 | 187 | if (Imm == 0) |
978 | 73 | return; |
979 | | |
980 | 114 | SStream_concat(O, "%s%s%s", ", lsl ", markup("<imm:"), "#"); |
981 | 114 | printUInt32(O, Imm); |
982 | 114 | SStream_concat0(O, markup(">")); |
983 | 114 | } |
984 | | |
985 | | void printPKHASRShiftImm(MCInst *MI, unsigned OpNum, SStream *O) |
986 | 292 | { |
987 | 292 | add_cs_detail(MI, ARM_OP_GROUP_PKHASRShiftImm, OpNum); |
988 | 292 | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
989 | | // A shift amount of 32 is encoded as 0. |
990 | 292 | if (Imm == 0) |
991 | 39 | Imm = 32; |
992 | | |
993 | 292 | SStream_concat(O, "%s%s%s", ", asr ", markup("<imm:"), "#"); |
994 | 292 | printUInt32(O, Imm); |
995 | 292 | SStream_concat0(O, markup(">")); |
996 | 292 | } |
997 | | |
998 | | void printRegisterList(MCInst *MI, unsigned OpNum, SStream *O) |
999 | 60.2k | { |
1000 | 60.2k | add_cs_detail(MI, ARM_OP_GROUP_RegisterList, OpNum); |
1001 | 60.2k | if (MCInst_getOpcode(MI) != ARM_t2CLRM) { |
1002 | 60.1k | } |
1003 | | |
1004 | 60.2k | SStream_concat0(O, "{"); |
1005 | 365k | for (unsigned i = OpNum, e = MCInst_getNumOperands(MI); i != e; ++i) { |
1006 | 305k | if (i != OpNum) |
1007 | 245k | SStream_concat0(O, ", "); |
1008 | 305k | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (i)))); |
1009 | 305k | } |
1010 | 60.2k | SStream_concat0(O, "}"); |
1011 | 60.2k | } |
1012 | | |
1013 | | void printGPRPairOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1014 | 990 | { |
1015 | 990 | add_cs_detail(MI, ARM_OP_GROUP_GPRPairOperand, OpNum); |
1016 | 990 | unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); |
1017 | 990 | printRegName(O, MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_gsub_0)); |
1018 | 990 | SStream_concat0(O, ", "); |
1019 | 990 | printRegName(O, MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_gsub_1)); |
1020 | 990 | } |
1021 | | |
1022 | | void printSetendOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1023 | 162 | { |
1024 | 162 | add_cs_detail(MI, ARM_OP_GROUP_SetendOperand, OpNum); |
1025 | 162 | MCOperand *Op = MCInst_getOperand(MI, (OpNum)); |
1026 | 162 | if (MCOperand_getImm(Op)) |
1027 | 92 | SStream_concat0(O, "be"); |
1028 | 70 | else |
1029 | 70 | SStream_concat0(O, "le"); |
1030 | 162 | } |
1031 | | |
1032 | | void printCPSIMod(MCInst *MI, unsigned OpNum, SStream *O) |
1033 | 1.59k | { |
1034 | 1.59k | add_cs_detail(MI, ARM_OP_GROUP_CPSIMod, OpNum); |
1035 | 1.59k | MCOperand *Op = MCInst_getOperand(MI, (OpNum)); |
1036 | 1.59k | SStream_concat0(O, ARM_PROC_IModToString(MCOperand_getImm(Op))); |
1037 | 1.59k | } |
1038 | | |
1039 | | void printCPSIFlag(MCInst *MI, unsigned OpNum, SStream *O) |
1040 | 1.59k | { |
1041 | 1.59k | add_cs_detail(MI, ARM_OP_GROUP_CPSIFlag, OpNum); |
1042 | 1.59k | MCOperand *Op = MCInst_getOperand(MI, (OpNum)); |
1043 | 1.59k | unsigned IFlags = MCOperand_getImm(Op); |
1044 | 6.39k | for (int i = 2; i >= 0; --i) |
1045 | 4.79k | if (IFlags & (1 << i)) |
1046 | 1.71k | SStream_concat0(O, ARM_PROC_IFlagsToString(1 << i)); |
1047 | | |
1048 | 1.59k | if (IFlags == 0) |
1049 | 729 | SStream_concat0(O, "none"); |
1050 | 1.59k | } |
1051 | | |
1052 | | void printMSRMaskOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1053 | 12.5k | { |
1054 | 12.5k | add_cs_detail(MI, ARM_OP_GROUP_MSRMaskOperand, OpNum); |
1055 | 12.5k | MCOperand *Op = MCInst_getOperand(MI, (OpNum)); |
1056 | | |
1057 | 12.5k | if (ARM_getFeatureBits(MI->csh->mode, ARM_FeatureMClass)) { |
1058 | 11.2k | unsigned SYSm = MCOperand_getImm(Op) & 0xFFF; // 12-bit SYSm |
1059 | 11.2k | unsigned Opcode = MCInst_getOpcode(MI); |
1060 | | |
1061 | | // For writes, handle extended mask bits if the DSP extension is |
1062 | | // present. |
1063 | 11.2k | if (Opcode == ARM_t2MSR_M && |
1064 | 11.2k | ARM_getFeatureBits(MI->csh->mode, ARM_FeatureDSP)) { |
1065 | 10.1k | const ARMSysReg_MClassSysReg *TheReg = |
1066 | 10.1k | ARMSysReg_lookupMClassSysRegBy12bitSYSmValue( |
1067 | 10.1k | SYSm); |
1068 | 10.1k | if (TheReg && MClassSysReg_isInRequiredFeatures( |
1069 | 3.18k | TheReg, ARM_FeatureDSP)) { |
1070 | 365 | SStream_concat0(O, TheReg->Name); |
1071 | 365 | return; |
1072 | 365 | } |
1073 | 10.1k | } |
1074 | | |
1075 | | // Handle the basic 8-bit mask. |
1076 | 10.8k | SYSm &= 0xff; |
1077 | 10.8k | if (Opcode == ARM_t2MSR_M && |
1078 | 10.8k | ARM_getFeatureBits(MI->csh->mode, ARM_HasV7Ops)) { |
1079 | | // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as |
1080 | | // an alias for MSR APSR_nzcvq. |
1081 | 9.77k | const ARMSysReg_MClassSysReg *TheReg = |
1082 | 9.77k | ARMSysReg_lookupMClassSysRegAPSRNonDeprecated( |
1083 | 9.77k | SYSm); |
1084 | 9.77k | if (TheReg) { |
1085 | 595 | SStream_concat0(O, TheReg->Name); |
1086 | 595 | return; |
1087 | 595 | } |
1088 | 9.77k | } |
1089 | | |
1090 | 10.2k | const ARMSysReg_MClassSysReg *TheReg = |
1091 | 10.2k | ARMSysReg_lookupMClassSysRegBy8bitSYSmValue(SYSm); |
1092 | 10.2k | if (TheReg) { |
1093 | 8.38k | SStream_concat0(O, TheReg->Name); |
1094 | 8.38k | return; |
1095 | 8.38k | } |
1096 | | |
1097 | 1.90k | printUInt32(O, SYSm); |
1098 | | |
1099 | 1.90k | return; |
1100 | 10.2k | } |
1101 | | |
1102 | | // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as |
1103 | | // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively. |
1104 | 1.30k | unsigned SpecRegRBit = MCOperand_getImm(Op) >> 4; |
1105 | 1.30k | unsigned Mask = MCOperand_getImm(Op) & 0xf; |
1106 | | |
1107 | 1.30k | if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) { |
1108 | 392 | SStream_concat0(O, "apsr_"); |
1109 | 392 | switch (Mask) { |
1110 | 0 | default: |
1111 | 0 | assert(0 && "Unexpected mask value!"); |
1112 | 113 | case 4: |
1113 | 113 | SStream_concat0(O, "g"); |
1114 | 113 | return; |
1115 | 79 | case 8: |
1116 | 79 | SStream_concat0(O, "nzcvq"); |
1117 | 79 | return; |
1118 | 200 | case 12: |
1119 | 200 | SStream_concat0(O, "nzcvqg"); |
1120 | 200 | return; |
1121 | 392 | } |
1122 | 392 | } |
1123 | | |
1124 | 913 | if (SpecRegRBit) |
1125 | 149 | SStream_concat0(O, "spsr"); |
1126 | 764 | else |
1127 | 764 | SStream_concat0(O, "cpsr"); |
1128 | | |
1129 | 913 | if (Mask) { |
1130 | 894 | SStream_concat0(O, "_"); |
1131 | | |
1132 | 894 | if (Mask & 8) |
1133 | 309 | SStream_concat0(O, "f"); |
1134 | | |
1135 | 894 | if (Mask & 4) |
1136 | 263 | SStream_concat0(O, "s"); |
1137 | | |
1138 | 894 | if (Mask & 2) |
1139 | 834 | SStream_concat0(O, "x"); |
1140 | | |
1141 | 894 | if (Mask & 1) |
1142 | 637 | SStream_concat0(O, "c"); |
1143 | 894 | } |
1144 | 913 | } |
1145 | | |
1146 | | void printBankedRegOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1147 | 244 | { |
1148 | 244 | add_cs_detail(MI, ARM_OP_GROUP_BankedRegOperand, OpNum); |
1149 | 244 | uint32_t Banked = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
1150 | 244 | const ARMBankedReg_BankedReg *TheReg = |
1151 | 244 | ARMBankedReg_lookupBankedRegByEncoding(Banked); |
1152 | | |
1153 | 244 | const char *Name = TheReg->Name; |
1154 | | |
1155 | | // uint32_t isSPSR = (Banked & 0x20) >> 5; |
1156 | | // if (isSPSR) |
1157 | | // Name.replace(0, 4, "SPSR"); // convert 'spsr_' to 'SPSR_' |
1158 | 244 | SStream_concat0(O, Name); |
1159 | 244 | } |
1160 | | |
1161 | | static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1162 | 1.22M | { |
1163 | 1.22M | add_cs_detail(MI, ARM_OP_GROUP_PredicateOperand, OpNum); |
1164 | 1.22M | ARMCC_CondCodes CC = (ARMCC_CondCodes)MCOperand_getImm( |
1165 | 1.22M | MCInst_getOperand(MI, (OpNum))); |
1166 | | // Handle the undefined 15 CC value here for printing so we don't abort(). |
1167 | 1.22M | if ((unsigned)CC == 15) |
1168 | 1.29k | SStream_concat0(O, "<und>"); |
1169 | 1.22M | else if (CC != ARMCC_AL) |
1170 | 167k | SStream_concat0(O, ARMCondCodeToString(CC)); |
1171 | 1.22M | } |
1172 | | |
1173 | | void printMandatoryRestrictedPredicateOperand(MCInst *MI, unsigned OpNum, |
1174 | | SStream *O) |
1175 | 12.6k | { |
1176 | 12.6k | add_cs_detail(MI, ARM_OP_GROUP_MandatoryRestrictedPredicateOperand, |
1177 | 12.6k | OpNum); |
1178 | 12.6k | if ((ARMCC_CondCodes)MCOperand_getImm(MCInst_getOperand(MI, (OpNum))) == |
1179 | 12.6k | ARMCC_HS) |
1180 | 3.27k | SStream_concat0(O, "cs"); |
1181 | 9.34k | else |
1182 | 9.34k | printMandatoryPredicateOperand(MI, OpNum, O); |
1183 | 12.6k | } |
1184 | | |
1185 | | void printMandatoryPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1186 | 28.0k | { |
1187 | 28.0k | add_cs_detail(MI, ARM_OP_GROUP_MandatoryPredicateOperand, OpNum); |
1188 | 28.0k | ARMCC_CondCodes CC = (ARMCC_CondCodes)MCOperand_getImm( |
1189 | 28.0k | MCInst_getOperand(MI, (OpNum))); |
1190 | 28.0k | SStream_concat0(O, ARMCondCodeToString(CC)); |
1191 | 28.0k | } |
1192 | | |
1193 | | void printMandatoryInvertedPredicateOperand(MCInst *MI, unsigned OpNum, |
1194 | | SStream *O) |
1195 | 462 | { |
1196 | 462 | add_cs_detail(MI, ARM_OP_GROUP_MandatoryInvertedPredicateOperand, |
1197 | 462 | OpNum); |
1198 | 462 | ARMCC_CondCodes CC = (ARMCC_CondCodes)MCOperand_getImm( |
1199 | 462 | MCInst_getOperand(MI, (OpNum))); |
1200 | 462 | SStream_concat0(O, ARMCondCodeToString(ARMCC_getOppositeCondition(CC))); |
1201 | 462 | } |
1202 | | |
1203 | | void printSBitModifierOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1204 | 396k | { |
1205 | 396k | add_cs_detail(MI, ARM_OP_GROUP_SBitModifierOperand, OpNum); |
1206 | 396k | if (MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))) { |
1207 | 357k | SStream_concat0(O, "s"); |
1208 | 357k | } |
1209 | 396k | } |
1210 | | |
1211 | | void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O) |
1212 | 36.8k | { |
1213 | 36.8k | add_cs_detail(MI, ARM_OP_GROUP_NoHashImmediate, OpNum); |
1214 | 36.8k | printInt64(O, MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); |
1215 | 36.8k | } |
1216 | | |
1217 | | void printPImmediate(MCInst *MI, unsigned OpNum, SStream *O) |
1218 | 80.0k | { |
1219 | 80.0k | add_cs_detail(MI, ARM_OP_GROUP_PImmediate, OpNum); |
1220 | 80.0k | SStream_concat(O, "%s%d", "p", |
1221 | 80.0k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); |
1222 | 80.0k | } |
1223 | | |
1224 | | void printCImmediate(MCInst *MI, unsigned OpNum, SStream *O) |
1225 | 143k | { |
1226 | 143k | add_cs_detail(MI, ARM_OP_GROUP_CImmediate, OpNum); |
1227 | 143k | SStream_concat(O, "%s%d", "c", |
1228 | 143k | MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); |
1229 | 143k | } |
1230 | | |
1231 | | void printCoprocOptionImm(MCInst *MI, unsigned OpNum, SStream *O) |
1232 | 4.96k | { |
1233 | 4.96k | add_cs_detail(MI, ARM_OP_GROUP_CoprocOptionImm, OpNum); |
1234 | 4.96k | SStream_concat(O, "%s", "{"); |
1235 | 4.96k | printInt64(O, MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); |
1236 | 4.96k | SStream_concat0(O, "}"); |
1237 | 4.96k | } |
1238 | | |
1239 | | void printPCLabel(MCInst *MI, unsigned OpNum, SStream *O) |
1240 | 0 | { |
1241 | | // add_cs_detail(MI, ARM_OP_GROUP_PCLabel, OpNum); |
1242 | 0 | assert(0 && "Unhandled PC-relative pseudo-instruction!"); |
1243 | 0 | } |
1244 | | |
1245 | | #define DEFINE_printAdrLabelOperand(scale) \ |
1246 | | void CONCAT(printAdrLabelOperand, scale)(MCInst * MI, unsigned OpNum, \ |
1247 | | SStream *O) \ |
1248 | 26.2k | { \ |
1249 | 26.2k | add_cs_detail(MI, CONCAT(ARM_OP_GROUP_AdrLabelOperand, scale), \ |
1250 | 26.2k | OpNum, scale); \ |
1251 | 26.2k | MCOperand *MO = MCInst_getOperand(MI, (OpNum)); \ |
1252 | 26.2k | \ |
1253 | 26.2k | if (MCOperand_isExpr(MO)) { \ |
1254 | 0 | return; \ |
1255 | 0 | } \ |
1256 | 26.2k | \ |
1257 | 26.2k | int32_t OffImm = (uint32_t)MCOperand_getImm(MO) << scale; \ |
1258 | 26.2k | \ |
1259 | 26.2k | SStream_concat0(O, markup("<imm:")); \ |
1260 | 26.2k | if (OffImm == INT32_MIN) \ |
1261 | 26.2k | SStream_concat0(O, "#-0"); \ |
1262 | 26.2k | else if (OffImm < 0) { \ |
1263 | 275 | printInt32Bang(O, OffImm); \ |
1264 | 25.9k | } else { \ |
1265 | 25.9k | printInt32Bang(O, OffImm); \ |
1266 | 25.9k | } \ |
1267 | 26.2k | SStream_concat0(O, markup(">")); \ |
1268 | 26.2k | } Line | Count | Source | 1248 | 1.10k | { \ | 1249 | 1.10k | add_cs_detail(MI, CONCAT(ARM_OP_GROUP_AdrLabelOperand, scale), \ | 1250 | 1.10k | OpNum, scale); \ | 1251 | 1.10k | MCOperand *MO = MCInst_getOperand(MI, (OpNum)); \ | 1252 | 1.10k | \ | 1253 | 1.10k | if (MCOperand_isExpr(MO)) { \ | 1254 | 0 | return; \ | 1255 | 0 | } \ | 1256 | 1.10k | \ | 1257 | 1.10k | int32_t OffImm = (uint32_t)MCOperand_getImm(MO) << scale; \ | 1258 | 1.10k | \ | 1259 | 1.10k | SStream_concat0(O, markup("<imm:")); \ | 1260 | 1.10k | if (OffImm == INT32_MIN) \ | 1261 | 1.10k | SStream_concat0(O, "#-0"); \ | 1262 | 1.10k | else if (OffImm < 0) { \ | 1263 | 275 | printInt32Bang(O, OffImm); \ | 1264 | 831 | } else { \ | 1265 | 831 | printInt32Bang(O, OffImm); \ | 1266 | 831 | } \ | 1267 | 1.10k | SStream_concat0(O, markup(">")); \ | 1268 | 1.10k | } |
Line | Count | Source | 1248 | 25.1k | { \ | 1249 | 25.1k | add_cs_detail(MI, CONCAT(ARM_OP_GROUP_AdrLabelOperand, scale), \ | 1250 | 25.1k | OpNum, scale); \ | 1251 | 25.1k | MCOperand *MO = MCInst_getOperand(MI, (OpNum)); \ | 1252 | 25.1k | \ | 1253 | 25.1k | if (MCOperand_isExpr(MO)) { \ | 1254 | 0 | return; \ | 1255 | 0 | } \ | 1256 | 25.1k | \ | 1257 | 25.1k | int32_t OffImm = (uint32_t)MCOperand_getImm(MO) << scale; \ | 1258 | 25.1k | \ | 1259 | 25.1k | SStream_concat0(O, markup("<imm:")); \ | 1260 | 25.1k | if (OffImm == INT32_MIN) \ | 1261 | 25.1k | SStream_concat0(O, "#-0"); \ | 1262 | 25.1k | else if (OffImm < 0) { \ | 1263 | 0 | printInt32Bang(O, OffImm); \ | 1264 | 25.1k | } else { \ | 1265 | 25.1k | printInt32Bang(O, OffImm); \ | 1266 | 25.1k | } \ | 1267 | 25.1k | SStream_concat0(O, markup(">")); \ | 1268 | 25.1k | } |
|
1269 | | DEFINE_printAdrLabelOperand(0) DEFINE_printAdrLabelOperand(2) |
1270 | | |
1271 | | void printThumbS4ImmOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1272 | 31.6k | { |
1273 | 31.6k | add_cs_detail(MI, ARM_OP_GROUP_ThumbS4ImmOperand, OpNum); |
1274 | 31.6k | SStream_concat(O, "%s", markup("<imm:")); |
1275 | 31.6k | printInt64Bang(O, MCOperand_getImm(MCInst_getOperand(MI, (OpNum))) * 4); |
1276 | 31.6k | SStream_concat0(O, markup(">")); |
1277 | 31.6k | } |
1278 | | |
1279 | | void printThumbSRImm(MCInst *MI, unsigned OpNum, SStream *O) |
1280 | 68.2k | { |
1281 | 68.2k | add_cs_detail(MI, ARM_OP_GROUP_ThumbSRImm, OpNum); |
1282 | 68.2k | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
1283 | 68.2k | SStream_concat(O, "%s", markup("<imm:")); |
1284 | 68.2k | printUInt32Bang(O, (Imm == 0 ? 32 : Imm)); |
1285 | 68.2k | SStream_concat0(O, markup(">")); |
1286 | 68.2k | } |
1287 | | |
1288 | | void printThumbITMask(MCInst *MI, unsigned OpNum, SStream *O) |
1289 | 18.3k | { |
1290 | 18.3k | add_cs_detail(MI, ARM_OP_GROUP_ThumbITMask, OpNum); |
1291 | | // (3 - the number of trailing zeros) is the number of then / else. |
1292 | 18.3k | unsigned Mask = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
1293 | 18.3k | unsigned NumTZ = CountTrailingZeros_32(Mask); |
1294 | | |
1295 | 66.4k | for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { |
1296 | 48.1k | if ((Mask >> Pos) & 1) |
1297 | 10.3k | SStream_concat0(O, "e"); |
1298 | | |
1299 | 37.8k | else |
1300 | 37.8k | SStream_concat0(O, "t"); |
1301 | 48.1k | } |
1302 | 18.3k | } |
1303 | | |
1304 | | void printThumbAddrModeRROperand(MCInst *MI, unsigned Op, SStream *O) |
1305 | 38.7k | { |
1306 | 38.7k | add_cs_detail(MI, ARM_OP_GROUP_ThumbAddrModeRROperand, Op); |
1307 | 38.7k | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); |
1308 | 38.7k | MCOperand *MO2 = MCInst_getOperand(MI, (Op + 1)); |
1309 | | |
1310 | 38.7k | if (!MCOperand_isReg( |
1311 | 38.7k | MO1)) { // FIXME: This is for CP entries, but isn't right. |
1312 | 0 | printOperand(MI, Op, O); |
1313 | 0 | return; |
1314 | 0 | } |
1315 | | |
1316 | 38.7k | SStream_concat(O, "%s", markup("<mem:")); |
1317 | 38.7k | SStream_concat0(O, "["); |
1318 | 38.7k | printRegName(O, MCOperand_getReg(MO1)); |
1319 | 38.7k | unsigned RegNum = MCOperand_getReg(MO2); |
1320 | 38.7k | if (RegNum) { |
1321 | 38.7k | SStream_concat0(O, ", "); |
1322 | 38.7k | printRegName(O, RegNum); |
1323 | 38.7k | } |
1324 | 38.7k | SStream_concat(O, "%s", "]"); |
1325 | 38.7k | SStream_concat0(O, markup(">")); |
1326 | 38.7k | } |
1327 | | |
1328 | | void printThumbAddrModeImm5SOperand(MCInst *MI, unsigned Op, SStream *O, |
1329 | | unsigned Scale) |
1330 | 235k | { |
1331 | 235k | MCOperand *MO1 = MCInst_getOperand(MI, (Op)); |
1332 | 235k | MCOperand *MO2 = MCInst_getOperand(MI, (Op + 1)); |
1333 | | |
1334 | 235k | if (!MCOperand_isReg( |
1335 | 235k | MO1)) { // FIXME: This is for CP entries, but isn't right. |
1336 | 0 | printOperand(MI, Op, O); |
1337 | 0 | return; |
1338 | 0 | } |
1339 | | |
1340 | 235k | SStream_concat(O, "%s", markup("<mem:")); |
1341 | 235k | SStream_concat0(O, "["); |
1342 | 235k | printRegName(O, MCOperand_getReg(MO1)); |
1343 | 235k | unsigned ImmOffs = MCOperand_getImm(MO2); |
1344 | 235k | if (ImmOffs) { |
1345 | 218k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); |
1346 | 218k | printUInt32Bang(O, ImmOffs * Scale); |
1347 | 218k | SStream_concat0(O, markup(">")); |
1348 | 218k | } |
1349 | 235k | SStream_concat(O, "%s", "]"); |
1350 | 235k | SStream_concat0(O, markup(">")); |
1351 | 235k | } |
1352 | | |
1353 | | void printThumbAddrModeImm5S1Operand(MCInst *MI, unsigned Op, SStream *O) |
1354 | 57.0k | { |
1355 | 57.0k | add_cs_detail(MI, ARM_OP_GROUP_ThumbAddrModeImm5S1Operand, Op); |
1356 | 57.0k | printThumbAddrModeImm5SOperand(MI, Op, O, 1); |
1357 | 57.0k | } |
1358 | | |
1359 | | void printThumbAddrModeImm5S2Operand(MCInst *MI, unsigned Op, SStream *O) |
1360 | 64.2k | { |
1361 | 64.2k | add_cs_detail(MI, ARM_OP_GROUP_ThumbAddrModeImm5S2Operand, Op); |
1362 | 64.2k | printThumbAddrModeImm5SOperand(MI, Op, O, 2); |
1363 | 64.2k | } |
1364 | | |
1365 | | void printThumbAddrModeImm5S4Operand(MCInst *MI, unsigned Op, SStream *O) |
1366 | 77.2k | { |
1367 | 77.2k | add_cs_detail(MI, ARM_OP_GROUP_ThumbAddrModeImm5S4Operand, Op); |
1368 | 77.2k | printThumbAddrModeImm5SOperand(MI, Op, O, 4); |
1369 | 77.2k | } |
1370 | | |
1371 | | void printThumbAddrModeSPOperand(MCInst *MI, unsigned Op, SStream *O) |
1372 | 36.7k | { |
1373 | 36.7k | add_cs_detail(MI, ARM_OP_GROUP_ThumbAddrModeSPOperand, Op); |
1374 | 36.7k | printThumbAddrModeImm5SOperand(MI, Op, O, 4); |
1375 | 36.7k | } |
1376 | | |
1377 | | // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2 |
1378 | | // register with shift forms. |
1379 | | // REG 0 0 - e.g. R5 |
1380 | | // REG IMM, SH_OPC - e.g. R5, LSL #3 |
1381 | | void printT2SOOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1382 | 3.48k | { |
1383 | 3.48k | add_cs_detail(MI, ARM_OP_GROUP_T2SOOperand, OpNum); |
1384 | 3.48k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
1385 | 3.48k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); |
1386 | | |
1387 | 3.48k | unsigned Reg = MCOperand_getReg(MO1); |
1388 | 3.48k | printRegName(O, Reg); |
1389 | | |
1390 | | // Print the shift opc. |
1391 | | |
1392 | 3.48k | printRegImmShift(MI, O, ARM_AM_getSORegShOp(MCOperand_getImm(MO2)), |
1393 | 3.48k | ARM_AM_getSORegOffset(MCOperand_getImm(MO2)), |
1394 | 3.48k | getUseMarkup()); |
1395 | 3.48k | } |
1396 | | |
1397 | | #define DEFINE_printAddrModeImm12Operand(AlwaysPrintImm0) \ |
1398 | | void CONCAT(printAddrModeImm12Operand, \ |
1399 | | AlwaysPrintImm0)(MCInst * MI, unsigned OpNum, SStream *O) \ |
1400 | 9.26k | { \ |
1401 | 9.26k | add_cs_detail(MI, \ |
1402 | 9.26k | CONCAT(ARM_OP_GROUP_AddrModeImm12Operand, \ |
1403 | 9.26k | AlwaysPrintImm0), \ |
1404 | 9.26k | OpNum, AlwaysPrintImm0); \ |
1405 | 9.26k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ |
1406 | 9.26k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ |
1407 | 9.26k | \ |
1408 | 9.26k | if (!MCOperand_isReg(MO1)) { \ |
1409 | 0 | printOperand(MI, OpNum, O); \ |
1410 | 0 | return; \ |
1411 | 0 | } \ |
1412 | 9.26k | \ |
1413 | 9.26k | SStream_concat(O, "%s", markup("<mem:")); \ |
1414 | 9.26k | SStream_concat0(O, "["); \ |
1415 | 9.26k | printRegName(O, MCOperand_getReg(MO1)); \ |
1416 | 9.26k | \ |
1417 | 9.26k | int32_t OffImm = (int32_t)MCOperand_getImm(MO2); \ |
1418 | 9.26k | bool isSub = OffImm < 0; \ |
1419 | 9.26k | \ |
1420 | 9.26k | if (OffImm == INT32_MIN) \ |
1421 | 9.26k | OffImm = 0; \ |
1422 | 9.26k | if (isSub) { \ |
1423 | 3.52k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ |
1424 | 3.52k | printInt32Bang(O, OffImm); \ |
1425 | 3.52k | SStream_concat0(O, markup(">")); \ |
1426 | 5.74k | } else if (AlwaysPrintImm0 || OffImm > 0) { \ |
1427 | 5.27k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ |
1428 | 5.27k | printInt32Bang(O, OffImm); \ |
1429 | 5.27k | SStream_concat0(O, markup(">")); \ |
1430 | 5.27k | } \ |
1431 | 9.26k | SStream_concat(O, "%s", "]"); \ |
1432 | 9.26k | SStream_concat0(O, markup(">")); \ |
1433 | 9.26k | } printAddrModeImm12Operand_0 Line | Count | Source | 1400 | 5.45k | { \ | 1401 | 5.45k | add_cs_detail(MI, \ | 1402 | 5.45k | CONCAT(ARM_OP_GROUP_AddrModeImm12Operand, \ | 1403 | 5.45k | AlwaysPrintImm0), \ | 1404 | 5.45k | OpNum, AlwaysPrintImm0); \ | 1405 | 5.45k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 1406 | 5.45k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 1407 | 5.45k | \ | 1408 | 5.45k | if (!MCOperand_isReg(MO1)) { \ | 1409 | 0 | printOperand(MI, OpNum, O); \ | 1410 | 0 | return; \ | 1411 | 0 | } \ | 1412 | 5.45k | \ | 1413 | 5.45k | SStream_concat(O, "%s", markup("<mem:")); \ | 1414 | 5.45k | SStream_concat0(O, "["); \ | 1415 | 5.45k | printRegName(O, MCOperand_getReg(MO1)); \ | 1416 | 5.45k | \ | 1417 | 5.45k | int32_t OffImm = (int32_t)MCOperand_getImm(MO2); \ | 1418 | 5.45k | bool isSub = OffImm < 0; \ | 1419 | 5.45k | \ | 1420 | 5.45k | if (OffImm == INT32_MIN) \ | 1421 | 5.45k | OffImm = 0; \ | 1422 | 5.45k | if (isSub) { \ | 1423 | 1.35k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1424 | 1.35k | printInt32Bang(O, OffImm); \ | 1425 | 1.35k | SStream_concat0(O, markup(">")); \ | 1426 | 4.09k | } else if (AlwaysPrintImm0 || OffImm > 0) { \ | 1427 | 3.62k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1428 | 3.62k | printInt32Bang(O, OffImm); \ | 1429 | 3.62k | SStream_concat0(O, markup(">")); \ | 1430 | 3.62k | } \ | 1431 | 5.45k | SStream_concat(O, "%s", "]"); \ | 1432 | 5.45k | SStream_concat0(O, markup(">")); \ | 1433 | 5.45k | } |
printAddrModeImm12Operand_1 Line | Count | Source | 1400 | 3.81k | { \ | 1401 | 3.81k | add_cs_detail(MI, \ | 1402 | 3.81k | CONCAT(ARM_OP_GROUP_AddrModeImm12Operand, \ | 1403 | 3.81k | AlwaysPrintImm0), \ | 1404 | 3.81k | OpNum, AlwaysPrintImm0); \ | 1405 | 3.81k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 1406 | 3.81k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 1407 | 3.81k | \ | 1408 | 3.81k | if (!MCOperand_isReg(MO1)) { \ | 1409 | 0 | printOperand(MI, OpNum, O); \ | 1410 | 0 | return; \ | 1411 | 0 | } \ | 1412 | 3.81k | \ | 1413 | 3.81k | SStream_concat(O, "%s", markup("<mem:")); \ | 1414 | 3.81k | SStream_concat0(O, "["); \ | 1415 | 3.81k | printRegName(O, MCOperand_getReg(MO1)); \ | 1416 | 3.81k | \ | 1417 | 3.81k | int32_t OffImm = (int32_t)MCOperand_getImm(MO2); \ | 1418 | 3.81k | bool isSub = OffImm < 0; \ | 1419 | 3.81k | \ | 1420 | 3.81k | if (OffImm == INT32_MIN) \ | 1421 | 3.81k | OffImm = 0; \ | 1422 | 3.81k | if (isSub) { \ | 1423 | 2.17k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1424 | 2.17k | printInt32Bang(O, OffImm); \ | 1425 | 2.17k | SStream_concat0(O, markup(">")); \ | 1426 | 2.17k | } else if (AlwaysPrintImm0 || OffImm > 0) { \ | 1427 | 1.64k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1428 | 1.64k | printInt32Bang(O, OffImm); \ | 1429 | 1.64k | SStream_concat0(O, markup(">")); \ | 1430 | 1.64k | } \ | 1431 | 3.81k | SStream_concat(O, "%s", "]"); \ | 1432 | 3.81k | SStream_concat0(O, markup(">")); \ | 1433 | 3.81k | } |
|
1434 | | DEFINE_printAddrModeImm12Operand(false) DEFINE_printAddrModeImm12Operand(true) |
1435 | | |
1436 | | #define DEFINE_printT2AddrModeImm8Operand(AlwaysPrintImm0) \ |
1437 | | void CONCAT(printT2AddrModeImm8Operand, \ |
1438 | | AlwaysPrintImm0)(MCInst * MI, unsigned OpNum, SStream *O) \ |
1439 | 12.8k | { \ |
1440 | 12.8k | add_cs_detail(MI, \ |
1441 | 12.8k | CONCAT(ARM_OP_GROUP_T2AddrModeImm8Operand, \ |
1442 | 12.8k | AlwaysPrintImm0), \ |
1443 | 12.8k | OpNum, AlwaysPrintImm0); \ |
1444 | 12.8k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ |
1445 | 12.8k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ |
1446 | 12.8k | \ |
1447 | 12.8k | SStream_concat(O, "%s", markup("<mem:")); \ |
1448 | 12.8k | SStream_concat0(O, "["); \ |
1449 | 12.8k | printRegName(O, MCOperand_getReg(MO1)); \ |
1450 | 12.8k | \ |
1451 | 12.8k | int32_t OffImm = (int32_t)MCOperand_getImm(MO2); \ |
1452 | 12.8k | bool isSub = OffImm < 0; \ |
1453 | 12.8k | \ |
1454 | 12.8k | if (OffImm == INT32_MIN) \ |
1455 | 12.8k | OffImm = 0; \ |
1456 | 12.8k | if (isSub) { \ |
1457 | 8.91k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ |
1458 | 8.91k | printInt32Bang(O, OffImm); \ |
1459 | 8.91k | SStream_concat0(O, markup(">")); \ |
1460 | 8.91k | } else if (AlwaysPrintImm0 || OffImm > 0) { \ |
1461 | 3.08k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ |
1462 | 3.08k | printInt32Bang(O, OffImm); \ |
1463 | 3.08k | SStream_concat0(O, markup(">")); \ |
1464 | 3.08k | } \ |
1465 | 12.8k | SStream_concat(O, "%s", "]"); \ |
1466 | 12.8k | SStream_concat0(O, markup(">")); \ |
1467 | 12.8k | } printT2AddrModeImm8Operand_1 Line | Count | Source | 1439 | 3.49k | { \ | 1440 | 3.49k | add_cs_detail(MI, \ | 1441 | 3.49k | CONCAT(ARM_OP_GROUP_T2AddrModeImm8Operand, \ | 1442 | 3.49k | AlwaysPrintImm0), \ | 1443 | 3.49k | OpNum, AlwaysPrintImm0); \ | 1444 | 3.49k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 1445 | 3.49k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 1446 | 3.49k | \ | 1447 | 3.49k | SStream_concat(O, "%s", markup("<mem:")); \ | 1448 | 3.49k | SStream_concat0(O, "["); \ | 1449 | 3.49k | printRegName(O, MCOperand_getReg(MO1)); \ | 1450 | 3.49k | \ | 1451 | 3.49k | int32_t OffImm = (int32_t)MCOperand_getImm(MO2); \ | 1452 | 3.49k | bool isSub = OffImm < 0; \ | 1453 | 3.49k | \ | 1454 | 3.49k | if (OffImm == INT32_MIN) \ | 1455 | 3.49k | OffImm = 0; \ | 1456 | 3.49k | if (isSub) { \ | 1457 | 2.59k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1458 | 2.59k | printInt32Bang(O, OffImm); \ | 1459 | 2.59k | SStream_concat0(O, markup(">")); \ | 1460 | 2.59k | } else if (AlwaysPrintImm0 || OffImm > 0) { \ | 1461 | 898 | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1462 | 898 | printInt32Bang(O, OffImm); \ | 1463 | 898 | SStream_concat0(O, markup(">")); \ | 1464 | 898 | } \ | 1465 | 3.49k | SStream_concat(O, "%s", "]"); \ | 1466 | 3.49k | SStream_concat0(O, markup(">")); \ | 1467 | 3.49k | } |
printT2AddrModeImm8Operand_0 Line | Count | Source | 1439 | 9.38k | { \ | 1440 | 9.38k | add_cs_detail(MI, \ | 1441 | 9.38k | CONCAT(ARM_OP_GROUP_T2AddrModeImm8Operand, \ | 1442 | 9.38k | AlwaysPrintImm0), \ | 1443 | 9.38k | OpNum, AlwaysPrintImm0); \ | 1444 | 9.38k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 1445 | 9.38k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 1446 | 9.38k | \ | 1447 | 9.38k | SStream_concat(O, "%s", markup("<mem:")); \ | 1448 | 9.38k | SStream_concat0(O, "["); \ | 1449 | 9.38k | printRegName(O, MCOperand_getReg(MO1)); \ | 1450 | 9.38k | \ | 1451 | 9.38k | int32_t OffImm = (int32_t)MCOperand_getImm(MO2); \ | 1452 | 9.38k | bool isSub = OffImm < 0; \ | 1453 | 9.38k | \ | 1454 | 9.38k | if (OffImm == INT32_MIN) \ | 1455 | 9.38k | OffImm = 0; \ | 1456 | 9.38k | if (isSub) { \ | 1457 | 6.32k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1458 | 6.32k | printInt32Bang(O, OffImm); \ | 1459 | 6.32k | SStream_concat0(O, markup(">")); \ | 1460 | 6.32k | } else if (AlwaysPrintImm0 || OffImm > 0) { \ | 1461 | 2.18k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1462 | 2.18k | printInt32Bang(O, OffImm); \ | 1463 | 2.18k | SStream_concat0(O, markup(">")); \ | 1464 | 2.18k | } \ | 1465 | 9.38k | SStream_concat(O, "%s", "]"); \ | 1466 | 9.38k | SStream_concat0(O, markup(">")); \ | 1467 | 9.38k | } |
|
1468 | | DEFINE_printT2AddrModeImm8Operand(true) |
1469 | | DEFINE_printT2AddrModeImm8Operand(false) |
1470 | | |
1471 | | #define DEFINE_printT2AddrModeImm8s4Operand(AlwaysPrintImm0) \ |
1472 | | void CONCAT(printT2AddrModeImm8s4Operand, \ |
1473 | | AlwaysPrintImm0)(MCInst * MI, unsigned OpNum, SStream *O) \ |
1474 | 9.65k | { \ |
1475 | 9.65k | add_cs_detail(MI, \ |
1476 | 9.65k | CONCAT(ARM_OP_GROUP_T2AddrModeImm8s4Operand, \ |
1477 | 9.65k | AlwaysPrintImm0), \ |
1478 | 9.65k | OpNum, AlwaysPrintImm0); \ |
1479 | 9.65k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ |
1480 | 9.65k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ |
1481 | 9.65k | \ |
1482 | 9.65k | if (!MCOperand_isReg(MO1)) { \ |
1483 | 0 | printOperand(MI, OpNum, O); \ |
1484 | 0 | return; \ |
1485 | 0 | } \ |
1486 | 9.65k | \ |
1487 | 9.65k | SStream_concat(O, "%s", markup("<mem:")); \ |
1488 | 9.65k | SStream_concat0(O, "["); \ |
1489 | 9.65k | printRegName(O, MCOperand_getReg(MO1)); \ |
1490 | 9.65k | \ |
1491 | 9.65k | int32_t OffImm = (int32_t)MCOperand_getImm(MO2); \ |
1492 | 9.65k | bool isSub = OffImm < 0; \ |
1493 | 9.65k | \ |
1494 | 9.65k | if (OffImm == INT32_MIN) \ |
1495 | 9.65k | OffImm = 0; \ |
1496 | 9.65k | if (isSub) { \ |
1497 | 5.02k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ |
1498 | 5.02k | printInt32Bang(O, OffImm); \ |
1499 | 5.02k | SStream_concat0(O, markup(">")); \ |
1500 | 5.02k | } else if (AlwaysPrintImm0 || OffImm > 0) { \ |
1501 | 4.55k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ |
1502 | 4.55k | printInt32Bang(O, OffImm); \ |
1503 | 4.55k | SStream_concat0(O, markup(">")); \ |
1504 | 4.55k | } \ |
1505 | 9.65k | SStream_concat(O, "%s", "]"); \ |
1506 | 9.65k | SStream_concat0(O, markup(">")); \ |
1507 | 9.65k | } printT2AddrModeImm8s4Operand_0 Line | Count | Source | 1474 | 1.26k | { \ | 1475 | 1.26k | add_cs_detail(MI, \ | 1476 | 1.26k | CONCAT(ARM_OP_GROUP_T2AddrModeImm8s4Operand, \ | 1477 | 1.26k | AlwaysPrintImm0), \ | 1478 | 1.26k | OpNum, AlwaysPrintImm0); \ | 1479 | 1.26k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 1480 | 1.26k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 1481 | 1.26k | \ | 1482 | 1.26k | if (!MCOperand_isReg(MO1)) { \ | 1483 | 0 | printOperand(MI, OpNum, O); \ | 1484 | 0 | return; \ | 1485 | 0 | } \ | 1486 | 1.26k | \ | 1487 | 1.26k | SStream_concat(O, "%s", markup("<mem:")); \ | 1488 | 1.26k | SStream_concat0(O, "["); \ | 1489 | 1.26k | printRegName(O, MCOperand_getReg(MO1)); \ | 1490 | 1.26k | \ | 1491 | 1.26k | int32_t OffImm = (int32_t)MCOperand_getImm(MO2); \ | 1492 | 1.26k | bool isSub = OffImm < 0; \ | 1493 | 1.26k | \ | 1494 | 1.26k | if (OffImm == INT32_MIN) \ | 1495 | 1.26k | OffImm = 0; \ | 1496 | 1.26k | if (isSub) { \ | 1497 | 803 | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1498 | 803 | printInt32Bang(O, OffImm); \ | 1499 | 803 | SStream_concat0(O, markup(">")); \ | 1500 | 803 | } else if (AlwaysPrintImm0 || OffImm > 0) { \ | 1501 | 381 | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1502 | 381 | printInt32Bang(O, OffImm); \ | 1503 | 381 | SStream_concat0(O, markup(">")); \ | 1504 | 381 | } \ | 1505 | 1.26k | SStream_concat(O, "%s", "]"); \ | 1506 | 1.26k | SStream_concat0(O, markup(">")); \ | 1507 | 1.26k | } |
printT2AddrModeImm8s4Operand_1 Line | Count | Source | 1474 | 8.38k | { \ | 1475 | 8.38k | add_cs_detail(MI, \ | 1476 | 8.38k | CONCAT(ARM_OP_GROUP_T2AddrModeImm8s4Operand, \ | 1477 | 8.38k | AlwaysPrintImm0), \ | 1478 | 8.38k | OpNum, AlwaysPrintImm0); \ | 1479 | 8.38k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); \ | 1480 | 8.38k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); \ | 1481 | 8.38k | \ | 1482 | 8.38k | if (!MCOperand_isReg(MO1)) { \ | 1483 | 0 | printOperand(MI, OpNum, O); \ | 1484 | 0 | return; \ | 1485 | 0 | } \ | 1486 | 8.38k | \ | 1487 | 8.38k | SStream_concat(O, "%s", markup("<mem:")); \ | 1488 | 8.38k | SStream_concat0(O, "["); \ | 1489 | 8.38k | printRegName(O, MCOperand_getReg(MO1)); \ | 1490 | 8.38k | \ | 1491 | 8.38k | int32_t OffImm = (int32_t)MCOperand_getImm(MO2); \ | 1492 | 8.38k | bool isSub = OffImm < 0; \ | 1493 | 8.38k | \ | 1494 | 8.38k | if (OffImm == INT32_MIN) \ | 1495 | 8.38k | OffImm = 0; \ | 1496 | 8.38k | if (isSub) { \ | 1497 | 4.21k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1498 | 4.21k | printInt32Bang(O, OffImm); \ | 1499 | 4.21k | SStream_concat0(O, markup(">")); \ | 1500 | 4.21k | } else if (AlwaysPrintImm0 || OffImm > 0) { \ | 1501 | 4.17k | SStream_concat(O, "%s%s", ", ", markup("<imm:")); \ | 1502 | 4.17k | printInt32Bang(O, OffImm); \ | 1503 | 4.17k | SStream_concat0(O, markup(">")); \ | 1504 | 4.17k | } \ | 1505 | 8.38k | SStream_concat(O, "%s", "]"); \ | 1506 | 8.38k | SStream_concat0(O, markup(">")); \ | 1507 | 8.38k | } |
|
1508 | | DEFINE_printT2AddrModeImm8s4Operand(false) |
1509 | | DEFINE_printT2AddrModeImm8s4Operand(true) |
1510 | | |
1511 | | void printT2AddrModeImm0_1020s4Operand( |
1512 | | MCInst *MI, unsigned OpNum, |
1513 | | SStream *O) |
1514 | 763 | { |
1515 | 763 | add_cs_detail(MI, ARM_OP_GROUP_T2AddrModeImm0_1020s4Operand, OpNum); |
1516 | 763 | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
1517 | 763 | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); |
1518 | | |
1519 | 763 | SStream_concat(O, "%s", markup("<mem:")); |
1520 | 763 | SStream_concat0(O, "["); |
1521 | 763 | printRegName(O, MCOperand_getReg(MO1)); |
1522 | 763 | if (MCOperand_getImm(MO2)) { |
1523 | 570 | SStream_concat(O, "%s%s", ", ", markup("<imm:")); |
1524 | 570 | printInt64Bang(O, (int32_t)(MCOperand_getImm(MO2) * 4)); |
1525 | 570 | SStream_concat0(O, markup(">")); |
1526 | 570 | } |
1527 | 763 | SStream_concat(O, "%s", "]"); |
1528 | 763 | SStream_concat0(O, markup(">")); |
1529 | 763 | } |
1530 | | |
1531 | | void printT2AddrModeImm8OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1532 | 3.52k | { |
1533 | 3.52k | add_cs_detail(MI, ARM_OP_GROUP_T2AddrModeImm8OffsetOperand, OpNum); |
1534 | 3.52k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
1535 | 3.52k | int32_t OffImm = (int32_t)MCOperand_getImm(MO1); |
1536 | 3.52k | SStream_concat(O, "%s", ", "); |
1537 | 3.52k | SStream_concat0(O, markup("<imm:")); |
1538 | 3.52k | if (OffImm == INT32_MIN) |
1539 | 1.11k | SStream_concat0(O, "#-0"); |
1540 | 2.41k | else if (OffImm < 0) { |
1541 | 1.75k | printInt32Bang(O, OffImm); |
1542 | 1.75k | } else { |
1543 | 657 | printInt32Bang(O, OffImm); |
1544 | 657 | } |
1545 | 3.52k | SStream_concat0(O, markup(">")); |
1546 | 3.52k | } |
1547 | | |
1548 | | void printT2AddrModeImm8s4OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1549 | 4.57k | { |
1550 | 4.57k | add_cs_detail(MI, ARM_OP_GROUP_T2AddrModeImm8s4OffsetOperand, OpNum); |
1551 | 4.57k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
1552 | 4.57k | int32_t OffImm = (int32_t)MCOperand_getImm(MO1); |
1553 | | |
1554 | 4.57k | SStream_concat(O, "%s", ", "); |
1555 | 4.57k | SStream_concat0(O, markup("<imm:")); |
1556 | 4.57k | if (OffImm == INT32_MIN) |
1557 | 425 | SStream_concat0(O, "#-0"); |
1558 | 4.14k | else if (OffImm < 0) { |
1559 | 1.28k | printInt32Bang(O, OffImm); |
1560 | 2.86k | } else { |
1561 | 2.86k | printInt32Bang(O, OffImm); |
1562 | 2.86k | } |
1563 | 4.57k | SStream_concat0(O, markup(">")); |
1564 | 4.57k | } |
1565 | | |
1566 | | void printT2AddrModeSoRegOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1567 | 2.02k | { |
1568 | 2.02k | add_cs_detail(MI, ARM_OP_GROUP_T2AddrModeSoRegOperand, OpNum); |
1569 | 2.02k | MCOperand *MO1 = MCInst_getOperand(MI, (OpNum)); |
1570 | 2.02k | MCOperand *MO2 = MCInst_getOperand(MI, (OpNum + 1)); |
1571 | 2.02k | MCOperand *MO3 = MCInst_getOperand(MI, (OpNum + 2)); |
1572 | | |
1573 | 2.02k | SStream_concat(O, "%s", markup("<mem:")); |
1574 | 2.02k | SStream_concat0(O, "["); |
1575 | 2.02k | printRegName(O, MCOperand_getReg(MO1)); |
1576 | | |
1577 | 2.02k | SStream_concat0(O, ", "); |
1578 | 2.02k | printRegName(O, MCOperand_getReg(MO2)); |
1579 | | |
1580 | 2.02k | unsigned ShAmt = MCOperand_getImm(MO3); |
1581 | 2.02k | if (ShAmt) { |
1582 | 465 | SStream_concat(O, "%s%s%s", ", lsl ", markup("<imm:"), "#"); |
1583 | 465 | printUInt32(O, ShAmt); |
1584 | 465 | SStream_concat0(O, markup(">")); |
1585 | 465 | } |
1586 | 2.02k | SStream_concat(O, "%s", "]"); |
1587 | 2.02k | SStream_concat0(O, markup(">")); |
1588 | 2.02k | } |
1589 | | |
1590 | | void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1591 | 1.09k | { |
1592 | 1.09k | add_cs_detail(MI, ARM_OP_GROUP_FPImmOperand, OpNum); |
1593 | 1.09k | MCOperand *MO = MCInst_getOperand(MI, (OpNum)); |
1594 | 1.09k | SStream_concat(O, "%s", markup("<imm:")); |
1595 | 1.09k | printFloatBang(O, ARM_AM_getFPImmFloat(MCOperand_getImm(MO))); |
1596 | 1.09k | SStream_concat0(O, markup(">")); |
1597 | 1.09k | } |
1598 | | |
1599 | | void printVMOVModImmOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1600 | 5.26k | { |
1601 | 5.26k | add_cs_detail(MI, ARM_OP_GROUP_VMOVModImmOperand, OpNum); |
1602 | 5.26k | unsigned EncodedImm = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
1603 | 5.26k | unsigned EltBits; |
1604 | 5.26k | uint64_t Val = ARM_AM_decodeVMOVModImm(EncodedImm, &EltBits); |
1605 | 5.26k | SStream_concat(O, "%s", markup("<imm:")); |
1606 | 5.26k | printUInt64Bang(O, Val); |
1607 | 5.26k | SStream_concat0(O, markup(">")); |
1608 | 5.26k | } |
1609 | | |
1610 | | void printImmPlusOneOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1611 | 1.67k | { |
1612 | 1.67k | add_cs_detail(MI, ARM_OP_GROUP_ImmPlusOneOperand, OpNum); |
1613 | 1.67k | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
1614 | 1.67k | SStream_concat(O, "%s", markup("<imm:")); |
1615 | 1.67k | printUInt32Bang(O, Imm + 1); |
1616 | 1.67k | SStream_concat0(O, markup(">")); |
1617 | 1.67k | } |
1618 | | |
1619 | | void printRotImmOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1620 | 1.00k | { |
1621 | 1.00k | add_cs_detail(MI, ARM_OP_GROUP_RotImmOperand, OpNum); |
1622 | 1.00k | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
1623 | 1.00k | if (Imm == 0) |
1624 | 432 | return; |
1625 | | |
1626 | 573 | SStream_concat(O, "%s%s%s%d", ", ror ", markup("<imm:"), "#", 8 * Imm); |
1627 | 573 | SStream_concat0(O, markup(">")); |
1628 | 573 | } |
1629 | | |
1630 | | void printModImmOperand(MCInst *MI, unsigned OpNum, SStream *O) |
1631 | 8.70k | { |
1632 | 8.70k | add_cs_detail(MI, ARM_OP_GROUP_ModImmOperand, OpNum); |
1633 | 8.70k | MCOperand *Op = MCInst_getOperand(MI, (OpNum)); |
1634 | | |
1635 | | // Support for fixups (MCFixup) |
1636 | 8.70k | if (MCOperand_isExpr(Op)) { |
1637 | 0 | printOperand(MI, OpNum, O); |
1638 | 0 | return; |
1639 | 0 | } |
1640 | | |
1641 | 8.70k | unsigned Bits = MCOperand_getImm(Op) & 0xFF; |
1642 | 8.70k | unsigned Rot = (MCOperand_getImm(Op) & 0xF00) >> 7; |
1643 | | |
1644 | 8.70k | bool PrintUnsigned = false; |
1645 | 8.70k | switch (MCInst_getOpcode(MI)) { |
1646 | 359 | case ARM_MOVi: |
1647 | | // Movs to PC should be treated unsigned |
1648 | 359 | PrintUnsigned = |
1649 | 359 | (MCOperand_getReg(MCInst_getOperand(MI, (OpNum - 1))) == |
1650 | 359 | ARM_PC); |
1651 | 359 | break; |
1652 | 1.07k | case ARM_MSRi: |
1653 | | // Movs to special registers should be treated unsigned |
1654 | 1.07k | PrintUnsigned = true; |
1655 | 1.07k | break; |
1656 | 8.70k | } |
1657 | | |
1658 | 8.70k | int32_t Rotated = ARM_AM_rotr32(Bits, Rot); |
1659 | 8.70k | if (ARM_AM_getSOImmVal(Rotated) == MCOperand_getImm(Op)) { |
1660 | | // #rot has the least possible value |
1661 | 5.77k | SStream_concat(O, "%s", "#"); |
1662 | 5.77k | SStream_concat0(O, markup("<imm:")); |
1663 | 5.77k | if (PrintUnsigned) |
1664 | 187 | printUInt32(O, (uint32_t)(Rotated)); |
1665 | 5.58k | else |
1666 | 5.58k | printInt32(O, Rotated); |
1667 | 5.77k | SStream_concat0(O, markup(">")); |
1668 | 5.77k | return; |
1669 | 5.77k | } |
1670 | | |
1671 | | // Explicit #bits, #rot implied |
1672 | 2.92k | SStream_concat(O, "%s%s%u", "#", markup("<imm:"), Bits); |
1673 | 2.92k | SStream_concat(O, "%s%s%s%u", markup(">"), ", #", markup("<imm:"), Rot); |
1674 | 2.92k | SStream_concat0(O, markup(">")); |
1675 | 2.92k | } |
1676 | | |
1677 | | void printFBits16(MCInst *MI, unsigned OpNum, SStream *O) |
1678 | 756 | { |
1679 | 756 | add_cs_detail(MI, ARM_OP_GROUP_FBits16, OpNum); |
1680 | 756 | SStream_concat(O, "%s%s", markup("<imm:"), "#"); |
1681 | 756 | SStream_concat(O, "%d", |
1682 | 756 | 16 - MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); |
1683 | 756 | SStream_concat0(O, markup(">")); |
1684 | 756 | } |
1685 | | |
1686 | | void printFBits32(MCInst *MI, unsigned OpNum, SStream *O) |
1687 | 1.23k | { |
1688 | 1.23k | add_cs_detail(MI, ARM_OP_GROUP_FBits32, OpNum); |
1689 | 1.23k | SStream_concat(O, "%s%s", markup("<imm:"), "#"); |
1690 | 1.23k | printInt64(O, 32 - MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); |
1691 | 1.23k | SStream_concat0(O, markup(">")); |
1692 | 1.23k | } |
1693 | | |
1694 | | void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O) |
1695 | 6.63k | { |
1696 | 6.63k | add_cs_detail(MI, ARM_OP_GROUP_VectorIndex, OpNum); |
1697 | 6.63k | SStream_concat(O, "%s", "["); |
1698 | 6.63k | printInt64(O, |
1699 | 6.63k | (int32_t)MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); |
1700 | 6.63k | SStream_concat0(O, "]"); |
1701 | 6.63k | } |
1702 | | |
1703 | | void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O) |
1704 | 2.13k | { |
1705 | 2.13k | add_cs_detail(MI, ARM_OP_GROUP_VectorListOne, OpNum); |
1706 | 2.13k | SStream_concat0(O, "{"); |
1707 | 2.13k | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1708 | 2.13k | SStream_concat0(O, "}"); |
1709 | 2.13k | } |
1710 | | |
1711 | | void printVectorListTwo(MCInst *MI, unsigned OpNum, SStream *O) |
1712 | 6.53k | { |
1713 | 6.53k | add_cs_detail(MI, ARM_OP_GROUP_VectorListTwo, OpNum); |
1714 | 6.53k | unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); |
1715 | 6.53k | unsigned Reg0 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_0); |
1716 | 6.53k | unsigned Reg1 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_1); |
1717 | 6.53k | SStream_concat0(O, "{"); |
1718 | 6.53k | printRegName(O, Reg0); |
1719 | 6.53k | SStream_concat0(O, ", "); |
1720 | 6.53k | printRegName(O, Reg1); |
1721 | 6.53k | SStream_concat0(O, "}"); |
1722 | 6.53k | } |
1723 | | |
1724 | | void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum, SStream *O) |
1725 | 4.12k | { |
1726 | 4.12k | add_cs_detail(MI, ARM_OP_GROUP_VectorListTwoSpaced, OpNum); |
1727 | 4.12k | unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); |
1728 | 4.12k | unsigned Reg0 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_0); |
1729 | 4.12k | unsigned Reg1 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_2); |
1730 | 4.12k | SStream_concat0(O, "{"); |
1731 | 4.12k | printRegName(O, Reg0); |
1732 | 4.12k | SStream_concat0(O, ", "); |
1733 | 4.12k | printRegName(O, Reg1); |
1734 | 4.12k | SStream_concat0(O, "}"); |
1735 | 4.12k | } |
1736 | | |
1737 | | void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O) |
1738 | 3.33k | { |
1739 | 3.33k | add_cs_detail(MI, ARM_OP_GROUP_VectorListThree, OpNum); |
1740 | | // Normally, it's not safe to use register enum values directly with |
1741 | | // addition to get the next register, but for VFP registers, the |
1742 | | // sort order is guaranteed because they're all of the form D<n>. |
1743 | 3.33k | SStream_concat0(O, "{"); |
1744 | 3.33k | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1745 | 3.33k | SStream_concat0(O, ", "); |
1746 | 3.33k | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 1); |
1747 | 3.33k | SStream_concat0(O, ", "); |
1748 | 3.33k | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 2); |
1749 | 3.33k | SStream_concat0(O, "}"); |
1750 | 3.33k | } |
1751 | | |
1752 | | void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O) |
1753 | 4.88k | { |
1754 | 4.88k | add_cs_detail(MI, ARM_OP_GROUP_VectorListFour, OpNum); |
1755 | | // Normally, it's not safe to use register enum values directly with |
1756 | | // addition to get the next register, but for VFP registers, the |
1757 | | // sort order is guaranteed because they're all of the form D<n>. |
1758 | 4.88k | SStream_concat0(O, "{"); |
1759 | 4.88k | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1760 | 4.88k | SStream_concat0(O, ", "); |
1761 | 4.88k | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 1); |
1762 | 4.88k | SStream_concat0(O, ", "); |
1763 | 4.88k | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 2); |
1764 | 4.88k | SStream_concat0(O, ", "); |
1765 | 4.88k | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 3); |
1766 | 4.88k | SStream_concat0(O, "}"); |
1767 | 4.88k | } |
1768 | | |
1769 | | void printVectorListOneAllLanes(MCInst *MI, unsigned OpNum, SStream *O) |
1770 | 344 | { |
1771 | 344 | add_cs_detail(MI, ARM_OP_GROUP_VectorListOneAllLanes, OpNum); |
1772 | 344 | SStream_concat0(O, "{"); |
1773 | 344 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1774 | 344 | SStream_concat0(O, "[]}"); |
1775 | 344 | } |
1776 | | |
1777 | | void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum, SStream *O) |
1778 | 1.01k | { |
1779 | 1.01k | add_cs_detail(MI, ARM_OP_GROUP_VectorListTwoAllLanes, OpNum); |
1780 | 1.01k | unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); |
1781 | 1.01k | unsigned Reg0 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_0); |
1782 | 1.01k | unsigned Reg1 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_1); |
1783 | 1.01k | SStream_concat0(O, "{"); |
1784 | 1.01k | printRegName(O, Reg0); |
1785 | 1.01k | SStream_concat0(O, "[], "); |
1786 | 1.01k | printRegName(O, Reg1); |
1787 | 1.01k | SStream_concat0(O, "[]}"); |
1788 | 1.01k | } |
1789 | | |
1790 | | void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O) |
1791 | 0 | { |
1792 | 0 | add_cs_detail(MI, ARM_OP_GROUP_VectorListThreeAllLanes, OpNum); |
1793 | | // Normally, it's not safe to use register enum values directly with |
1794 | | // addition to get the next register, but for VFP registers, the |
1795 | | // sort order is guaranteed because they're all of the form D<n>. |
1796 | 0 | SStream_concat0(O, "{"); |
1797 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1798 | 0 | SStream_concat0(O, "[], "); |
1799 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 1); |
1800 | 0 | SStream_concat0(O, "[], "); |
1801 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 2); |
1802 | 0 | SStream_concat0(O, "[]}"); |
1803 | 0 | } |
1804 | | |
1805 | | void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O) |
1806 | 0 | { |
1807 | 0 | add_cs_detail(MI, ARM_OP_GROUP_VectorListFourAllLanes, OpNum); |
1808 | | // Normally, it's not safe to use register enum values directly with |
1809 | | // addition to get the next register, but for VFP registers, the |
1810 | | // sort order is guaranteed because they're all of the form D<n>. |
1811 | 0 | SStream_concat0(O, "{"); |
1812 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1813 | 0 | SStream_concat0(O, "[], "); |
1814 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 1); |
1815 | 0 | SStream_concat0(O, "[], "); |
1816 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 2); |
1817 | 0 | SStream_concat0(O, "[], "); |
1818 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 3); |
1819 | 0 | SStream_concat0(O, "[]}"); |
1820 | 0 | } |
1821 | | |
1822 | | void printVectorListTwoSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O) |
1823 | 1.78k | { |
1824 | 1.78k | add_cs_detail(MI, ARM_OP_GROUP_VectorListTwoSpacedAllLanes, OpNum); |
1825 | 1.78k | unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); |
1826 | 1.78k | unsigned Reg0 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_0); |
1827 | 1.78k | unsigned Reg1 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_2); |
1828 | 1.78k | SStream_concat0(O, "{"); |
1829 | 1.78k | printRegName(O, Reg0); |
1830 | 1.78k | SStream_concat0(O, "[], "); |
1831 | 1.78k | printRegName(O, Reg1); |
1832 | 1.78k | SStream_concat0(O, "[]}"); |
1833 | 1.78k | } |
1834 | | |
1835 | | void printVectorListThreeSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O) |
1836 | 0 | { |
1837 | 0 | add_cs_detail(MI, ARM_OP_GROUP_VectorListThreeSpacedAllLanes, OpNum); |
1838 | | // Normally, it's not safe to use register enum values directly with |
1839 | | // addition to get the next register, but for VFP registers, the |
1840 | | // sort order is guaranteed because they're all of the form D<n>. |
1841 | 0 | SStream_concat0(O, "{"); |
1842 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1843 | 0 | SStream_concat0(O, "[], "); |
1844 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 2); |
1845 | 0 | SStream_concat0(O, "[], "); |
1846 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 4); |
1847 | 0 | SStream_concat0(O, "[]}"); |
1848 | 0 | } |
1849 | | |
1850 | | void printVectorListFourSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O) |
1851 | 0 | { |
1852 | 0 | add_cs_detail(MI, ARM_OP_GROUP_VectorListFourSpacedAllLanes, OpNum); |
1853 | | // Normally, it's not safe to use register enum values directly with |
1854 | | // addition to get the next register, but for VFP registers, the |
1855 | | // sort order is guaranteed because they're all of the form D<n>. |
1856 | 0 | SStream_concat0(O, "{"); |
1857 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1858 | 0 | SStream_concat0(O, "[], "); |
1859 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 2); |
1860 | 0 | SStream_concat0(O, "[], "); |
1861 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 4); |
1862 | 0 | SStream_concat0(O, "[], "); |
1863 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 6); |
1864 | 0 | SStream_concat0(O, "[]}"); |
1865 | 0 | } |
1866 | | |
1867 | | void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O) |
1868 | 0 | { |
1869 | 0 | add_cs_detail(MI, ARM_OP_GROUP_VectorListThreeSpaced, OpNum); |
1870 | | // Normally, it's not safe to use register enum values directly with |
1871 | | // addition to get the next register, but for VFP registers, the |
1872 | | // sort order is guaranteed because they're all of the form D<n>. |
1873 | 0 | SStream_concat0(O, "{"); |
1874 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1875 | 0 | SStream_concat0(O, ", "); |
1876 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 2); |
1877 | 0 | SStream_concat0(O, ", "); |
1878 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 4); |
1879 | 0 | SStream_concat0(O, "}"); |
1880 | 0 | } |
1881 | | |
1882 | | void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O) |
1883 | 0 | { |
1884 | 0 | add_cs_detail(MI, ARM_OP_GROUP_VectorListFourSpaced, OpNum); |
1885 | | // Normally, it's not safe to use register enum values directly with |
1886 | | // addition to get the next register, but for VFP registers, the |
1887 | | // sort order is guaranteed because they're all of the form D<n>. |
1888 | 0 | SStream_concat0(O, "{"); |
1889 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum)))); |
1890 | 0 | SStream_concat0(O, ", "); |
1891 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 2); |
1892 | 0 | SStream_concat0(O, ", "); |
1893 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 4); |
1894 | 0 | SStream_concat0(O, ", "); |
1895 | 0 | printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))) + 6); |
1896 | 0 | SStream_concat0(O, "}"); |
1897 | 0 | } |
1898 | | |
1899 | | #define DEFINE_printMVEVectorList(NumRegs) \ |
1900 | | void CONCAT(printMVEVectorList, NumRegs)(MCInst * MI, unsigned OpNum, \ |
1901 | | SStream *O) \ |
1902 | 1.70k | { \ |
1903 | 1.70k | add_cs_detail(MI, CONCAT(ARM_OP_GROUP_MVEVectorList, NumRegs), \ |
1904 | 1.70k | OpNum, NumRegs); \ |
1905 | 1.70k | unsigned Reg = \ |
1906 | 1.70k | MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \ |
1907 | 1.70k | const char *Prefix = "{"; \ |
1908 | 6.85k | for (unsigned i = 0; i < NumRegs; i++) { \ |
1909 | 5.15k | SStream_concat0(O, Prefix); \ |
1910 | 5.15k | printRegName( \ |
1911 | 5.15k | O, MCRegisterInfo_getSubReg(MI->MRI, Reg, \ |
1912 | 5.15k | ARM_qsub_0 + i)); \ |
1913 | 5.15k | Prefix = ", "; \ |
1914 | 5.15k | } \ |
1915 | 1.70k | SStream_concat0(O, "}"); \ |
1916 | 1.70k | } Line | Count | Source | 1902 | 834 | { \ | 1903 | 834 | add_cs_detail(MI, CONCAT(ARM_OP_GROUP_MVEVectorList, NumRegs), \ | 1904 | 834 | OpNum, NumRegs); \ | 1905 | 834 | unsigned Reg = \ | 1906 | 834 | MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \ | 1907 | 834 | const char *Prefix = "{"; \ | 1908 | 2.50k | for (unsigned i = 0; i < NumRegs; i++) { \ | 1909 | 1.66k | SStream_concat0(O, Prefix); \ | 1910 | 1.66k | printRegName( \ | 1911 | 1.66k | O, MCRegisterInfo_getSubReg(MI->MRI, Reg, \ | 1912 | 1.66k | ARM_qsub_0 + i)); \ | 1913 | 1.66k | Prefix = ", "; \ | 1914 | 1.66k | } \ | 1915 | 834 | SStream_concat0(O, "}"); \ | 1916 | 834 | } |
Line | Count | Source | 1902 | 871 | { \ | 1903 | 871 | add_cs_detail(MI, CONCAT(ARM_OP_GROUP_MVEVectorList, NumRegs), \ | 1904 | 871 | OpNum, NumRegs); \ | 1905 | 871 | unsigned Reg = \ | 1906 | 871 | MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \ | 1907 | 871 | const char *Prefix = "{"; \ | 1908 | 4.35k | for (unsigned i = 0; i < NumRegs; i++) { \ | 1909 | 3.48k | SStream_concat0(O, Prefix); \ | 1910 | 3.48k | printRegName( \ | 1911 | 3.48k | O, MCRegisterInfo_getSubReg(MI->MRI, Reg, \ | 1912 | 3.48k | ARM_qsub_0 + i)); \ | 1913 | 3.48k | Prefix = ", "; \ | 1914 | 3.48k | } \ | 1915 | 871 | SStream_concat0(O, "}"); \ | 1916 | 871 | } |
|
1917 | | DEFINE_printMVEVectorList(2) DEFINE_printMVEVectorList(4) |
1918 | | |
1919 | | #define DEFINE_printComplexRotationOp(Angle, Remainder) \ |
1920 | | void CONCAT(printComplexRotationOp, CONCAT(Angle, Remainder))( \ |
1921 | | MCInst * MI, unsigned OpNo, SStream *O) \ |
1922 | 3.92k | { \ |
1923 | 3.92k | add_cs_detail( \ |
1924 | 3.92k | MI, \ |
1925 | 3.92k | CONCAT(CONCAT(ARM_OP_GROUP_ComplexRotationOp, Angle), \ |
1926 | 3.92k | Remainder), \ |
1927 | 3.92k | OpNo, Angle, Remainder); \ |
1928 | 3.92k | unsigned Val = \ |
1929 | 3.92k | MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \ |
1930 | 3.92k | SStream_concat(O, "#%d", (Val * Angle) + Remainder); \ |
1931 | 3.92k | } printComplexRotationOp_90_0 Line | Count | Source | 1922 | 1.36k | { \ | 1923 | 1.36k | add_cs_detail( \ | 1924 | 1.36k | MI, \ | 1925 | 1.36k | CONCAT(CONCAT(ARM_OP_GROUP_ComplexRotationOp, Angle), \ | 1926 | 1.36k | Remainder), \ | 1927 | 1.36k | OpNo, Angle, Remainder); \ | 1928 | 1.36k | unsigned Val = \ | 1929 | 1.36k | MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \ | 1930 | 1.36k | SStream_concat(O, "#%d", (Val * Angle) + Remainder); \ | 1931 | 1.36k | } |
printComplexRotationOp_180_90 Line | Count | Source | 1922 | 2.55k | { \ | 1923 | 2.55k | add_cs_detail( \ | 1924 | 2.55k | MI, \ | 1925 | 2.55k | CONCAT(CONCAT(ARM_OP_GROUP_ComplexRotationOp, Angle), \ | 1926 | 2.55k | Remainder), \ | 1927 | 2.55k | OpNo, Angle, Remainder); \ | 1928 | 2.55k | unsigned Val = \ | 1929 | 2.55k | MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \ | 1930 | 2.55k | SStream_concat(O, "#%d", (Val * Angle) + Remainder); \ | 1931 | 2.55k | } |
|
1932 | | DEFINE_printComplexRotationOp(90, 0) DEFINE_printComplexRotationOp(180, |
1933 | | 90) |
1934 | | |
1935 | | void printVPTPredicateOperand(MCInst *MI, unsigned OpNum, |
1936 | | SStream *O) |
1937 | 41.1k | { |
1938 | 41.1k | add_cs_detail(MI, ARM_OP_GROUP_VPTPredicateOperand, OpNum); |
1939 | 41.1k | ARMVCC_VPTCodes CC = (ARMVCC_VPTCodes)MCOperand_getImm( |
1940 | 41.1k | MCInst_getOperand(MI, (OpNum))); |
1941 | 41.1k | if (CC != ARMVCC_None) |
1942 | 4.80k | SStream_concat0(O, ARMVPTPredToString(CC)); |
1943 | 41.1k | } |
1944 | | |
1945 | | void printVPTMask(MCInst *MI, unsigned OpNum, SStream *O) |
1946 | 9.96k | { |
1947 | 9.96k | add_cs_detail(MI, ARM_OP_GROUP_VPTMask, OpNum); |
1948 | | // (3 - the number of trailing zeroes) is the number of them / else. |
1949 | 9.96k | unsigned Mask = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
1950 | 9.96k | unsigned NumTZ = CountTrailingZeros_32(Mask); |
1951 | | |
1952 | 34.6k | for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) { |
1953 | 24.6k | bool T = ((Mask >> Pos) & 1) == 0; |
1954 | 24.6k | if (T) |
1955 | 15.9k | SStream_concat0(O, "t"); |
1956 | | |
1957 | 8.75k | else |
1958 | 8.75k | SStream_concat0(O, "e"); |
1959 | 24.6k | } |
1960 | 9.96k | } |
1961 | | |
1962 | | void printMveSaturateOp(MCInst *MI, unsigned OpNum, SStream *O) |
1963 | 0 | { |
1964 | 0 | add_cs_detail(MI, ARM_OP_GROUP_MveSaturateOp, OpNum); |
1965 | 0 | uint32_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); |
1966 | |
|
1967 | 0 | printUInt32Bang(O, (Val == 1 ? 48 : 64)); |
1968 | 0 | } |
1969 | | |
1970 | | const char *ARM_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx) |
1971 | 952k | { |
1972 | 952k | return getRegisterName(RegNo, AltIdx); |
1973 | 952k | } |
1974 | | |
1975 | | void ARM_LLVM_printInstruction(MCInst *MI, SStream *O, |
1976 | | void * /* MCRegisterInfo* */ info) |
1977 | 1.47M | { |
1978 | 1.47M | printInst(MI, O, info); |
1979 | 1.47M | } |