Coverage Report

Created: 2024-09-08 06:22

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