Coverage Report

Created: 2023-09-25 06:24

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