Coverage Report

Created: 2023-12-08 06:05

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