Coverage Report

Created: 2026-10-17 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/capstonenext/arch/RISCV/RISCVInstPrinter.c
Line
Count
Source
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: <commit> */
7
/* LLVM-tag: <tag> */
8
9
/* Only small edits allowed. */
10
/* For multiple similar edits, please create a Patch for the translator. */
11
12
/* Capstone's C++ file translator: */
13
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
14
15
//===-- RISCVInstPrinter.cpp - Convert RISC-V MCInst to asm 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 RISC-V MCInst to a .s file.
24
//
25
//===----------------------------------------------------------------------===//
26
27
#include <capstone/capstone.h>
28
#include <capstone/platform.h>
29
#include "../../MathExtras.h"
30
31
#include "RISCVMapping.h"
32
#include "RISCVInstPrinter.h"
33
34
#define GET_SUBTARGETINFO_ENUM
35
#include "RISCVGenSubtargetInfo.inc"
36
37
#define GET_INSTRINFO_ENUM
38
#include "RISCVGenInstrInfo.inc"
39
40
#define GET_REGINFO_ENUM
41
#include "RISCVGenRegisterInfo.inc"
42
43
#define GET_SysRegsList_IMPL
44
#include "RISCVGenSystemOperands.inc"
45
46
#define GEN_UNCOMPRESS_INSTR
47
#include "RISCVGenCompressedInstructionsInfo.inc"
48
49
#include "RISCVMapping.h"
50
#include "../../Mapping.h"
51
52
#define CONCAT(a, b) CONCAT_(a, b)
53
#define CONCAT_(a, b) a##_##b
54
55
#define DEBUG_TYPE "asm-printer"
56
57
static void printCustomAliasOperand(MCInst *MI, uint64_t Address,
58
            unsigned OpIdx, unsigned PrintMethodIdx,
59
            SStream *OS);
60
static inline void printRegName(SStream *O, MCRegister Reg);
61
static inline void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
62
// Include the auto-generated portion of the assembly writer.
63
#define PRINT_ALIAS_INSTR
64
#include "RISCVGenAsmWriter.inc"
65
66
// Print architectural register names rather than the ABI names (such as x2
67
// instead of sp).
68
// TODO: Make RISCVInstPrinter_doGetRegisterName non-static so that this can a
69
// member.
70
static bool ArchRegNames;
71
72
static bool isRealSyntax(const MCInst *MI)
73
242k
{
74
242k
  return MI->csh->syntax & CS_OPT_SYNTAX_REAL;
75
242k
}
76
77
static bool isUncompressedRealSyntax(const MCInst *MI)
78
162k
{
79
162k
  return MI->csh->syntax & CS_OPT_SYNTAX_UNCOMPRESSED_REAL;
80
162k
}
81
82
static bool isAliasSyntax(const MCInst *MI)
83
80.0k
{
84
80.0k
  return !(MI->csh->syntax &
85
80.0k
     (CS_OPT_SYNTAX_REAL | CS_OPT_SYNTAX_UNCOMPRESSED_REAL));
86
80.0k
}
87
88
static bool isRealDetail(const MCInst *MI)
89
160k
{
90
160k
  return detail_is_set(MI) && (MI->csh->detail_opt & CS_OPT_DETAIL_REAL);
91
160k
}
92
93
static bool isUncompressedRealDetail(const MCInst *MI)
94
0
{
95
0
  return detail_is_set(MI) &&
96
0
         (MI->csh->detail_opt & CS_OPT_DETAIL_UNCOMPRESSED_REAL);
97
0
}
98
99
static bool isAliasDetail(const MCInst *MI)
100
160k
{
101
160k
  return !(MI->csh->detail_opt &
102
160k
     (CS_OPT_DETAIL_REAL | CS_OPT_DETAIL_UNCOMPRESSED_REAL));
103
160k
}
104
105
const char *doGetRegisterName(MCRegister Reg)
106
134k
{
107
134k
  return getRegisterName(Reg, ArchRegNames ? RISCV_NoRegAltName :
108
134k
               RISCV_ABIRegAltName);
109
134k
}
110
111
static inline void printRegName(SStream *O, MCRegister Reg)
112
358k
{
113
358k
  SStream_concat0(markup_OS(O, Markup_Register), doGetRegisterName(Reg));
114
358k
}
115
116
bool haveRequiredFeatures(const RISCV_SysReg *Reg, MCInst *MI)
117
788
{
118
  // Not in 32-bit mode.
119
788
  if (Reg->isRV32Only &&
120
471
      RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit))
121
273
    return false;
122
123
515
  return true;
124
788
}
125
126
static inline void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
127
173k
{
128
173k
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_Operand, OpNo);
129
130
173k
  MCOperand *MO = MCInst_getOperand(MI, (OpNo));
131
132
173k
  if (MCOperand_isReg(MO)) {
133
128k
    printRegName(O, MCOperand_getReg(MO));
134
128k
    return;
135
128k
  }
136
137
44.3k
  if (MCOperand_isImm(MO)) {
138
44.3k
    printInt64(markup_OS(O, Markup_Immediate),
139
44.3k
         MCOperand_getImm(MO));
140
44.3k
    return;
141
44.3k
  }
142
143
0
  CS_ASSERT(MCOperand_isExpr(MO) &&
144
0
      "Unknown operand kind in printOperand");
145
0
  printExpr(O, MCOperand_getExpr(MO));
146
0
}
147
148
void printBranchOperand(MCInst *MI, uint64_t Address, unsigned OpNo, SStream *O)
149
5.24k
{
150
5.24k
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_BranchOperand, OpNo);
151
5.24k
  MCOperand *MO = MCInst_getOperand(MI, (OpNo));
152
5.24k
  if (!MCOperand_isImm(MO))
153
0
    return printOperand(MI, OpNo, O);
154
155
5.24k
  if (MI->csh->PrintBranchImmAsAddress) {
156
5.24k
    uint64_t Target = Address + MCOperand_getImm(MO);
157
5.24k
    if (!RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit))
158
3.26k
      Target &= 0xffffffff;
159
5.24k
    printUInt64(markup_OS(O, Markup_Target), Target);
160
5.24k
  } else {
161
0
    printInt64(markup_OS(O, Markup_Target), MCOperand_getImm(MO));
162
0
  }
163
5.24k
}
164
165
void printCSRSystemRegister(MCInst *MI, unsigned OpNo, SStream *O)
166
2.21k
{
167
2.21k
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_CSRSystemRegister, OpNo);
168
2.21k
  unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
169
2.21k
  const RISCV_SysReg *SysReg = RISCV_lookupSysRegByEncoding(Imm);
170
2.21k
  if (SysReg && haveRequiredFeatures(SysReg, MI))
171
515
    SStream_concat0(markup_OS(O, Markup_Register), SysReg->Name);
172
1.69k
  else
173
1.69k
    printUInt64(markup_OS(O, Markup_Register), Imm);
174
2.21k
}
175
176
void printFenceArg(MCInst *MI, unsigned OpNo, SStream *O)
177
3.53k
{
178
3.53k
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FenceArg, OpNo);
179
3.53k
  unsigned FenceArg = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
180
3.53k
  CS_ASSERT(((FenceArg >> 4) == 0) &&
181
3.53k
      "Invalid immediate in printFenceArg");
182
183
3.53k
  if ((FenceArg & RISCVFenceField_I) != 0)
184
2.07k
    SStream_concat0(O, "i");
185
186
3.53k
  if ((FenceArg & RISCVFenceField_O) != 0)
187
1.50k
    SStream_concat0(O, "o");
188
189
3.53k
  if ((FenceArg & RISCVFenceField_R) != 0)
190
2.13k
    SStream_concat0(O, "r");
191
192
3.53k
  if ((FenceArg & RISCVFenceField_W) != 0)
193
1.14k
    SStream_concat0(O, "w");
194
195
3.53k
  if (FenceArg == 0)
196
782
    SStream_concat0(O, "0");
197
3.53k
}
198
199
void printFRMArg(MCInst *MI, unsigned OpNo, SStream *O)
200
2.02k
{
201
2.02k
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FRMArg, OpNo);
202
2.02k
  unsigned FRMArg = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
203
2.02k
  if (!isRealSyntax(MI) && !isUncompressedRealSyntax(MI) &&
204
2.02k
      FRMArg == RISCVFPRndMode_DYN)
205
270
    return;
206
1.75k
  SStream_concat(O, "%s", ", ");
207
1.75k
  SStream_concat0(O, RISCVFPRndMode_roundingModeToString(FRMArg));
208
1.75k
}
209
210
void printFRMArgLegacy(MCInst *MI, unsigned OpNo, SStream *O)
211
901
{
212
901
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FRMArgLegacy, OpNo);
213
901
  unsigned FRMArg = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
214
  // Never print rounding mode if it's the default 'rne'. This ensures the
215
  // output can still be parsed by older tools that erroneously failed to
216
  // accept a rounding mode.
217
901
  if (FRMArg == RISCVFPRndMode_RNE)
218
247
    return;
219
654
  SStream_concat(O, "%s", ", ");
220
654
  SStream_concat0(O, RISCVFPRndMode_roundingModeToString(FRMArg));
221
654
}
222
223
void printFPImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
224
1.77k
{
225
1.77k
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FPImmOperand, OpNo);
226
1.77k
  unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
227
1.77k
  if (Imm == 1) {
228
329
    SStream_concat0(markup_OS(O, Markup_Immediate), "min");
229
1.44k
  } else if (Imm == 30) {
230
533
    SStream_concat0(markup_OS(O, Markup_Immediate), "inf");
231
912
  } else if (Imm == 31) {
232
67
    SStream_concat0(markup_OS(O, Markup_Immediate), "nan");
233
845
  } else {
234
845
    float FPVal = getFPImm(Imm);
235
    // If the value is an integer, print a .0 fraction. Otherwise, use %g to
236
    // which will not print trailing zeros and will use scientific notation
237
    // if it is shorter than printing as a decimal. The smallest value requires
238
    // 12 digits of precision including the decimal.
239
845
    if (FPVal == (int)(FPVal))
240
778
      printfFloat(markup_OS(O, Markup_Immediate), "%.1f",
241
778
            FPVal);
242
67
    else
243
67
      printfFloat(markup_OS(O, Markup_Immediate), "%.12g",
244
67
            FPVal);
245
845
  }
246
1.77k
}
247
248
void printZeroOffsetMemOp(MCInst *MI, unsigned OpNo, SStream *O)
249
2.78k
{
250
2.78k
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_ZeroOffsetMemOp, OpNo);
251
2.78k
  MCOperand *MO = MCInst_getOperand(MI, (OpNo));
252
253
2.78k
  CS_ASSERT(MCOperand_isReg(MO) &&
254
2.78k
      "printZeroOffsetMemOp can only print register operands");
255
2.78k
  SStream_concat0(O, "(");
256
2.78k
  printRegName(O, MCOperand_getReg(MO));
257
2.78k
  SStream_concat0(O, ")");
258
2.78k
}
259
260
void printVTypeI(MCInst *MI, unsigned OpNo, SStream *O)
261
3.12k
{
262
3.12k
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_VTypeI, OpNo);
263
3.12k
  unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
264
  // Print the raw immediate for reserved values: vlmul[2:0]=4, vsew[2:0]=0b1xx,
265
  // or non-zero in bits 8 and above.
266
3.12k
  if (RISCVVType_getVLMUL(Imm) == RISCVII_LMUL_RESERVED ||
267
2.93k
      RISCVVType_getSEW(Imm) > 64 || (Imm >> 8) != 0) {
268
1.20k
    printUInt64(O, Imm);
269
1.20k
    return;
270
1.20k
  }
271
  // Print the text form.
272
1.92k
  printVType(Imm, O);
273
1.92k
}
274
275
void printRlist(MCInst *MI, unsigned OpNo, SStream *O)
276
0
{
277
0
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_Rlist, OpNo);
278
0
  unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
279
0
  SStream_concat0(O, "{");
280
0
  switch (Imm) {
281
0
  case RISCVZC_RLISTENCODE_RA:
282
0
    SStream_concat0(markup_OS(O, Markup_Register),
283
0
        (ArchRegNames ? "x1" : "ra"));
284
0
    break;
285
0
  case RISCVZC_RLISTENCODE_RA_S0:
286
0
    SStream_concat0(markup_OS(O, Markup_Register),
287
0
        (ArchRegNames ? "x1" : "ra"));
288
0
    SStream_concat0(O, ", ");
289
0
    SStream_concat0(markup_OS(O, Markup_Register),
290
0
        (ArchRegNames ? "x8" : "s0"));
291
0
    break;
292
0
  case RISCVZC_RLISTENCODE_RA_S0_S1:
293
0
    SStream_concat0(markup_OS(O, Markup_Register),
294
0
        (ArchRegNames ? "x1" : "ra"));
295
0
    SStream_concat0(O, ", ");
296
0
    SStream_concat0(markup_OS(O, Markup_Register),
297
0
        (ArchRegNames ? "x8" : "s0"));
298
0
    SStream_concat0(O, "-");
299
300
0
    SStream_concat0(markup_OS(O, Markup_Register),
301
0
        (ArchRegNames ? "x9" : "s1"));
302
0
    break;
303
0
  case RISCVZC_RLISTENCODE_RA_S0_S2:
304
0
    SStream_concat0(markup_OS(O, Markup_Register),
305
0
        (ArchRegNames ? "x1" : "ra"));
306
0
    SStream_concat0(O, ", ");
307
0
    SStream_concat0(markup_OS(O, Markup_Register),
308
0
        (ArchRegNames ? "x8" : "s0"));
309
0
    SStream_concat0(O, "-");
310
311
0
    SStream_concat0(markup_OS(O, Markup_Register),
312
0
        (ArchRegNames ? "x9" : "s2"));
313
0
    if (ArchRegNames) {
314
0
      SStream_concat0(O, ", ");
315
0
      SStream_concat0(markup_OS(O, Markup_Register), "x18");
316
0
    }
317
0
    break;
318
0
  case RISCVZC_RLISTENCODE_RA_S0_S3:
319
0
  case RISCVZC_RLISTENCODE_RA_S0_S4:
320
0
  case RISCVZC_RLISTENCODE_RA_S0_S5:
321
0
  case RISCVZC_RLISTENCODE_RA_S0_S6:
322
0
  case RISCVZC_RLISTENCODE_RA_S0_S7:
323
0
  case RISCVZC_RLISTENCODE_RA_S0_S8:
324
0
  case RISCVZC_RLISTENCODE_RA_S0_S9:
325
0
  case RISCVZC_RLISTENCODE_RA_S0_S11:
326
0
    SStream_concat0(markup_OS(O, Markup_Register),
327
0
        (ArchRegNames ? "x1" : "ra"));
328
0
    SStream_concat0(O, ", ");
329
0
    SStream_concat0(markup_OS(O, Markup_Register),
330
0
        (ArchRegNames ? "x8" : "s0"));
331
0
    SStream_concat0(O, "-");
332
333
0
    if (ArchRegNames) {
334
0
      SStream_concat0(markup_OS(O, Markup_Register), "x9");
335
0
      SStream_concat0(O, ", ");
336
0
      SStream_concat0(markup_OS(O, Markup_Register), "x18");
337
0
      SStream_concat0(O, "-");
338
0
    }
339
0
    SStream_concat0(
340
0
      markup_OS(O, Markup_Register),
341
0
      doGetRegisterName(
342
0
        RISCV_X19 +
343
0
        (Imm == RISCVZC_RLISTENCODE_RA_S0_S11 ?
344
0
           8 :
345
0
           Imm - RISCVZC_RLISTENCODE_RA_S0_S3)));
346
0
    break;
347
0
  default:
348
0
    CS_ASSERT(0 && "invalid register list");
349
0
  }
350
0
  SStream_concat0(O, "}");
351
0
}
352
353
void printRegReg(MCInst *MI, unsigned OpNo, SStream *O)
354
286
{
355
286
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_RegReg, OpNo);
356
286
  MCOperand *MO = MCInst_getOperand(MI, (OpNo));
357
358
286
  CS_ASSERT(MCOperand_isReg(MO) &&
359
286
      "printRegReg can only print register operands");
360
286
  if (MCOperand_getReg(MO) == RISCV_NoRegister)
361
0
    return;
362
286
  printRegName(O, MCOperand_getReg(MO));
363
364
286
  SStream_concat0(O, "(");
365
286
  MCOperand *MO1 = MCInst_getOperand(MI, (OpNo + 1));
366
286
  CS_ASSERT(MCOperand_isReg(MO1) &&
367
286
      "printRegReg can only print register operands");
368
286
  printRegName(O, MCOperand_getReg(MO1));
369
286
  SStream_concat0(O, ")");
370
286
}
371
372
void printSpimm(MCInst *MI, unsigned OpNo, SStream *O)
373
0
{
374
0
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_Spimm, OpNo);
375
0
  int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
376
0
  unsigned Opcode = MCInst_getOpcode(MI);
377
0
  bool IsRV64 = RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit);
378
0
  bool IsEABI = RISCV_getFeatureBits(MI->csh->mode, RISCV_FeatureRVE);
379
0
  int64_t Spimm = 0;
380
0
  int64_t RlistVal = MCOperand_getImm(MCInst_getOperand(MI, (0)));
381
0
  CS_ASSERT(RlistVal != 16 && "Incorrect rlist.");
382
0
  unsigned Base = RISCVZC_getStackAdjBase(RlistVal, IsRV64, IsEABI);
383
0
  Spimm = Imm + Base;
384
0
  CS_ASSERT((Spimm >= Base && Spimm <= Base + 48) && "Incorrect spimm");
385
0
  if (Opcode == RISCV_CM_PUSH)
386
0
    Spimm = -Spimm;
387
388
0
  RISCVZC_printSpimm(Spimm, markup_OS(O, Markup_Immediate));
389
0
}
390
391
void printVMaskReg(MCInst *MI, unsigned OpNo, SStream *O)
392
5.40k
{
393
5.40k
  RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_VMaskReg, OpNo);
394
5.40k
  MCOperand *MO = MCInst_getOperand(MI, (OpNo));
395
396
5.40k
  CS_ASSERT(MCOperand_isReg(MO) &&
397
5.40k
      "printVMaskReg can only print register operands");
398
5.40k
  if (MCOperand_getReg(MO) == RISCV_NoRegister)
399
2.75k
    return;
400
2.65k
  SStream_concat0(O, ", ");
401
2.65k
  printRegName(O, MCOperand_getReg(MO));
402
2.65k
  SStream_concat0(O, ".t");
403
2.65k
}
404
405
void RISCV_LLVM_printInstruction(MCInst *MI, SStream *O,
406
         void * /* MCRegisterInfo* */ info)
407
80.0k
{
408
80.0k
  MI->MRI = (MCRegisterInfo *)info;
409
410
80.0k
  MCInst_setIsAlias(MI, false);
411
80.0k
  bool usesAliasDetails = detail_is_set(MI) && isAliasDetail(MI) &&
412
80.0k
        !isRealDetail(MI);
413
80.0k
  MI->flat_insn->usesAliasDetails = usesAliasDetails;
414
415
80.0k
  MCInst Uncompressed;
416
80.0k
  MCInst_Init(&Uncompressed, MI->csh->arch);
417
80.0k
  MCInst *MIUncompressed = MI;
418
80.0k
  bool is_uncompressed = false;
419
420
80.0k
  bool textReal = isRealSyntax(MI);
421
80.0k
  bool detailReal = isRealDetail(MI);
422
423
80.0k
  if (!textReal || (detail_is_set(MI) && !detailReal)) {
424
    // Side-effectful check for compressed instructions that also creates the equivalent
425
    // uncompressed instruction in case of returning true
426
    // False means no side effect happened
427
    // (LLVM doesn't have an API for doing a pure check)
428
80.0k
    if (uncompressInst(&Uncompressed, MI)) {
429
39.2k
      MIUncompressed = &Uncompressed;
430
39.2k
      Uncompressed.address = MI->address;
431
39.2k
      Uncompressed.MRI = MI->MRI;
432
39.2k
      Uncompressed.csh = MI->csh;
433
39.2k
      Uncompressed.flat_insn = MI->flat_insn;
434
39.2k
      is_uncompressed = true;
435
39.2k
    }
436
80.0k
  }
437
438
80.0k
  if (isRealSyntax(MI)) {
439
0
    printInstruction(MI, MI->address, O);
440
80.0k
  } else {
441
80.0k
    if (isUncompressedRealSyntax(MI)) {
442
0
      printInstruction(MIUncompressed,
443
0
           MIUncompressed->address, O);
444
80.0k
    } else {
445
      // Side-effectful check for alias instructions that prints to the SStream if it returns true
446
      // False means no printing to stream happened
447
80.0k
      if (printAliasInstr(MI, MI->address, O)) {
448
2.19k
        MCInst_setIsAlias(MI, true);
449
77.8k
      } else { // the instruction is not an alias
450
77.8k
        if (!is_uncompressed) {
451
38.5k
          printInstruction(MI, MI->address, O);
452
39.2k
        } else if (printAliasInstr(
453
39.2k
               MIUncompressed,
454
39.2k
               MIUncompressed->address,
455
39.2k
               O)) {
456
7.39k
          MCInst_setIsAlias(MI, true);
457
31.8k
        } else {
458
31.8k
          printInstruction(
459
31.8k
            MIUncompressed,
460
31.8k
            MIUncompressed->address, O);
461
31.8k
        }
462
77.8k
      }
463
80.0k
    }
464
80.0k
  }
465
466
80.0k
  bool textAndDetailModesMatch = (isRealSyntax(MI) && isRealDetail(MI)) ||
467
80.0k
               (isUncompressedRealSyntax(MI) &&
468
0
          isUncompressedRealDetail(MI)) ||
469
80.0k
               (isAliasSyntax(MI) && isAliasDetail(MI));
470
471
80.0k
  if (detail_is_set(MI) && !textAndDetailModesMatch) {
472
0
    SStream_Close(O);
473
    // discard the text operands
474
0
    memset(MI->flat_insn->detail->riscv.operands, 0,
475
0
           sizeof(MI->flat_insn->detail->riscv.operands));
476
0
    MI->flat_insn->detail->riscv.op_count = 0;
477
478
    // re-disassemble again with no printing in order to obtain the requested details
479
    // including the whole operands array
480
0
    if (isRealDetail(MI)) {
481
0
      printInstruction(MI, MI->address, O);
482
0
    } else if (isUncompressedRealDetail(MI)) {
483
0
      printInstruction(MIUncompressed,
484
0
           MIUncompressed->address, O);
485
0
    } else if (!printAliasInstr(MI, MI->address, O)) {
486
0
      if (!is_uncompressed) {
487
0
        printInstruction(MI, MI->address, O);
488
0
      } else if (!printAliasInstr(MIUncompressed,
489
0
                MIUncompressed->address,
490
0
                O)) {
491
0
        printInstruction(MIUncompressed,
492
0
             MIUncompressed->address, O);
493
0
      } else {
494
        /* Nothing, printAliasInstr returned true and did its side effect */
495
0
      }
496
0
    }
497
498
    // re-open the stream to restore the usual state
499
0
    SStream_Open(O);
500
0
  }
501
502
80.0k
  RISCV_add_groups(MI);
503
80.0k
  RISCV_compact_operands(MI);
504
80.0k
  RISCV_set_alias_id(MI, O);
505
80.0k
}
506
507
const char *getSysRegName(unsigned reg)
508
0
{
509
0
  const RISCV_SysReg *SysReg = RISCV_lookupSysRegByEncoding(reg);
510
0
  return SysReg->Name;
511
0
}
512
513
const char *RISCV_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx)
514
27.7k
{
515
27.7k
  return getRegisterName(RegNo, AltIdx);
516
27.7k
}
517
518
bool isCompressed(MCInst *MI)
519
0
{
520
0
  MCInst unused;
521
0
  MCInst_Init(&unused, MI->csh->arch);
522
0
  return uncompressInst(&unused, MI);
523
0
}