/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/platform.h> |
28 | | #include "../../MathExtras.h" |
29 | | |
30 | | #include "RISCVMapping.h" |
31 | | #include "RISCVInstPrinter.h" |
32 | | |
33 | | #define GET_SUBTARGETINFO_ENUM |
34 | | #include "RISCVGenSubtargetInfo.inc" |
35 | | |
36 | | #define GET_INSTRINFO_ENUM |
37 | | #include "RISCVGenInstrInfo.inc" |
38 | | |
39 | | #define GET_REGINFO_ENUM |
40 | | #include "RISCVGenRegisterInfo.inc" |
41 | | |
42 | | #define GET_SysRegsList_IMPL |
43 | | #include "RISCVGenSystemOperands.inc" |
44 | | |
45 | | #define GEN_UNCOMPRESS_INSTR |
46 | | #include "RISCVGenCompressedInstructionsInfo.inc" |
47 | | |
48 | | #include "RISCVMapping.h" |
49 | | #include "../../Mapping.h" |
50 | | |
51 | | #define CONCAT(a, b) CONCAT_(a, b) |
52 | | #define CONCAT_(a, b) a##_##b |
53 | | |
54 | | #define DEBUG_TYPE "asm-printer" |
55 | | |
56 | | static void printCustomAliasOperand(MCInst *MI, uint64_t Address, |
57 | | unsigned OpIdx, unsigned PrintMethodIdx, |
58 | | SStream *OS); |
59 | | static inline void printRegName(SStream *O, MCRegister Reg); |
60 | | static inline void printOperand(MCInst *MI, unsigned OpNo, SStream *O); |
61 | | // Include the auto-generated portion of the assembly writer. |
62 | | #define PRINT_ALIAS_INSTR |
63 | | #include "RISCVGenAsmWriter.inc" |
64 | | |
65 | | // Print architectural register names rather than the ABI names (such as x2 |
66 | | // instead of sp). |
67 | | // TODO: Make RISCVInstPrinter_doGetRegisterName non-static so that this can a |
68 | | // member. |
69 | | static bool ArchRegNames; |
70 | | |
71 | | const char *doGetRegisterName(MCRegister Reg) |
72 | 61.7k | { |
73 | 61.7k | return getRegisterName(Reg, ArchRegNames ? RISCV_NoRegAltName : |
74 | 61.7k | RISCV_ABIRegAltName); |
75 | 61.7k | } |
76 | | |
77 | | static inline void printRegName(SStream *O, MCRegister Reg) |
78 | 219k | { |
79 | 219k | SStream_concat0(markup_OS(O, Markup_Register), doGetRegisterName(Reg)); |
80 | 219k | } |
81 | | |
82 | | bool haveRequiredFeatures(const RISCV_SysReg *Reg, MCInst *MI) |
83 | 480 | { |
84 | | // Not in 32-bit mode. |
85 | 480 | if (Reg->isRV32Only && |
86 | 384 | RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit)) |
87 | 86 | return false; |
88 | | |
89 | 394 | return true; |
90 | 480 | } |
91 | | |
92 | | static inline void printOperand(MCInst *MI, unsigned OpNo, SStream *O) |
93 | 79.4k | { |
94 | 79.4k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_Operand, OpNo); |
95 | | |
96 | 79.4k | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
97 | | |
98 | 79.4k | if (MCOperand_isReg(MO)) { |
99 | 59.1k | printRegName(O, MCOperand_getReg(MO)); |
100 | 59.1k | return; |
101 | 59.1k | } |
102 | | |
103 | 20.3k | if (MCOperand_isImm(MO)) { |
104 | 20.3k | printInt64(markup_OS(O, Markup_Immediate), |
105 | 20.3k | MCOperand_getImm(MO)); |
106 | 20.3k | return; |
107 | 20.3k | } |
108 | | |
109 | 0 | CS_ASSERT(MCOperand_isExpr(MO) && |
110 | 0 | "Unknown operand kind in printOperand"); |
111 | 0 | printExpr(O, MCOperand_getExpr(MO)); |
112 | 0 | } |
113 | | |
114 | | void printBranchOperand(MCInst *MI, uint64_t Address, unsigned OpNo, SStream *O) |
115 | 3.61k | { |
116 | 3.61k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_BranchOperand, OpNo); |
117 | 3.61k | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
118 | 3.61k | if (!MCOperand_isImm(MO)) |
119 | 0 | return printOperand(MI, OpNo, O); |
120 | | |
121 | 3.61k | if (MI->csh->PrintBranchImmAsAddress) { |
122 | 3.61k | uint64_t Target = Address + MCOperand_getImm(MO); |
123 | 3.61k | if (!RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit)) |
124 | 1.82k | Target &= 0xffffffff; |
125 | 3.61k | printUInt64(markup_OS(O, Markup_Target), Target); |
126 | 3.61k | } else { |
127 | 0 | printInt64(markup_OS(O, Markup_Target), MCOperand_getImm(MO)); |
128 | 0 | } |
129 | 3.61k | } |
130 | | |
131 | | void printCSRSystemRegister(MCInst *MI, unsigned OpNo, SStream *O) |
132 | 975 | { |
133 | 975 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_CSRSystemRegister, OpNo); |
134 | 975 | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
135 | 975 | const RISCV_SysReg *SysReg = RISCV_lookupSysRegByEncoding(Imm); |
136 | 975 | if (SysReg && haveRequiredFeatures(SysReg, MI)) |
137 | 394 | SStream_concat0(markup_OS(O, Markup_Register), SysReg->Name); |
138 | 581 | else |
139 | 581 | printUInt64(markup_OS(O, Markup_Register), Imm); |
140 | 975 | } |
141 | | |
142 | | void printFenceArg(MCInst *MI, unsigned OpNo, SStream *O) |
143 | 1.46k | { |
144 | 1.46k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FenceArg, OpNo); |
145 | 1.46k | unsigned FenceArg = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
146 | 1.46k | CS_ASSERT(((FenceArg >> 4) == 0) && |
147 | 1.46k | "Invalid immediate in printFenceArg"); |
148 | | |
149 | 1.46k | if ((FenceArg & RISCVFenceField_I) != 0) |
150 | 746 | SStream_concat0(O, "i"); |
151 | | |
152 | 1.46k | if ((FenceArg & RISCVFenceField_O) != 0) |
153 | 392 | SStream_concat0(O, "o"); |
154 | | |
155 | 1.46k | if ((FenceArg & RISCVFenceField_R) != 0) |
156 | 750 | SStream_concat0(O, "r"); |
157 | | |
158 | 1.46k | if ((FenceArg & RISCVFenceField_W) != 0) |
159 | 698 | SStream_concat0(O, "w"); |
160 | | |
161 | 1.46k | if (FenceArg == 0) |
162 | 360 | SStream_concat0(O, "0"); |
163 | 1.46k | } |
164 | | |
165 | | void printFRMArg(MCInst *MI, unsigned OpNo, SStream *O) |
166 | 940 | { |
167 | 940 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FRMArg, OpNo); |
168 | 940 | unsigned FRMArg = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
169 | 940 | if (!(MI->csh->syntax & CS_OPT_SYNTAX_NO_ALIAS_TEXT) && |
170 | 940 | FRMArg == RISCVFPRndMode_DYN) |
171 | 125 | return; |
172 | 815 | SStream_concat(O, "%s", ", "); |
173 | 815 | SStream_concat0(O, RISCVFPRndMode_roundingModeToString(FRMArg)); |
174 | 815 | } |
175 | | |
176 | | void printFRMArgLegacy(MCInst *MI, unsigned OpNo, SStream *O) |
177 | 173 | { |
178 | 173 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FRMArgLegacy, OpNo); |
179 | 173 | unsigned FRMArg = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
180 | | // Never print rounding mode if it's the default 'rne'. This ensures the |
181 | | // output can still be parsed by older tools that erroneously failed to |
182 | | // accept a rounding mode. |
183 | 173 | if (FRMArg == RISCVFPRndMode_RNE) |
184 | 7 | return; |
185 | 166 | SStream_concat(O, "%s", ", "); |
186 | 166 | SStream_concat0(O, RISCVFPRndMode_roundingModeToString(FRMArg)); |
187 | 166 | } |
188 | | |
189 | | void printFPImmOperand(MCInst *MI, unsigned OpNo, SStream *O) |
190 | 431 | { |
191 | 431 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FPImmOperand, OpNo); |
192 | 431 | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
193 | 431 | if (Imm == 1) { |
194 | 71 | SStream_concat0(markup_OS(O, Markup_Immediate), "min"); |
195 | 360 | } else if (Imm == 30) { |
196 | 197 | SStream_concat0(markup_OS(O, Markup_Immediate), "inf"); |
197 | 197 | } else if (Imm == 31) { |
198 | 16 | SStream_concat0(markup_OS(O, Markup_Immediate), "nan"); |
199 | 147 | } else { |
200 | 147 | float FPVal = getFPImm(Imm); |
201 | | // If the value is an integer, print a .0 fraction. Otherwise, use %g to |
202 | | // which will not print trailing zeros and will use scientific notation |
203 | | // if it is shorter than printing as a decimal. The smallest value requires |
204 | | // 12 digits of precision including the decimal. |
205 | 147 | if (FPVal == (int)(FPVal)) |
206 | 122 | printfFloat(markup_OS(O, Markup_Immediate), "%.1f", |
207 | 122 | FPVal); |
208 | 25 | else |
209 | 25 | printfFloat(markup_OS(O, Markup_Immediate), "%.12g", |
210 | 25 | FPVal); |
211 | 147 | } |
212 | 431 | } |
213 | | |
214 | | void printZeroOffsetMemOp(MCInst *MI, unsigned OpNo, SStream *O) |
215 | 1.23k | { |
216 | 1.23k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_ZeroOffsetMemOp, OpNo); |
217 | 1.23k | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
218 | | |
219 | 1.23k | CS_ASSERT(MCOperand_isReg(MO) && |
220 | 1.23k | "printZeroOffsetMemOp can only print register operands"); |
221 | 1.23k | SStream_concat0(O, "("); |
222 | 1.23k | printRegName(O, MCOperand_getReg(MO)); |
223 | 1.23k | SStream_concat0(O, ")"); |
224 | 1.23k | } |
225 | | |
226 | | void printVTypeI(MCInst *MI, unsigned OpNo, SStream *O) |
227 | 337 | { |
228 | 337 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_VTypeI, OpNo); |
229 | 337 | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
230 | | // Print the raw immediate for reserved values: vlmul[2:0]=4, vsew[2:0]=0b1xx, |
231 | | // or non-zero in bits 8 and above. |
232 | 337 | if (RISCVVType_getVLMUL(Imm) == RISCVII_LMUL_RESERVED || |
233 | 327 | RISCVVType_getSEW(Imm) > 64 || (Imm >> 8) != 0) { |
234 | 256 | printUInt64(O, Imm); |
235 | 256 | return; |
236 | 256 | } |
237 | | // Print the text form. |
238 | 81 | printVType(Imm, O); |
239 | 81 | } |
240 | | |
241 | | void printRlist(MCInst *MI, unsigned OpNo, SStream *O) |
242 | 0 | { |
243 | 0 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_Rlist, OpNo); |
244 | 0 | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
245 | 0 | SStream_concat0(O, "{"); |
246 | 0 | switch (Imm) { |
247 | 0 | case RISCVZC_RLISTENCODE_RA: |
248 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
249 | 0 | (ArchRegNames ? "x1" : "ra")); |
250 | 0 | break; |
251 | 0 | case RISCVZC_RLISTENCODE_RA_S0: |
252 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
253 | 0 | (ArchRegNames ? "x1" : "ra")); |
254 | 0 | SStream_concat0(O, ", "); |
255 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
256 | 0 | (ArchRegNames ? "x8" : "s0")); |
257 | 0 | break; |
258 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S1: |
259 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
260 | 0 | (ArchRegNames ? "x1" : "ra")); |
261 | 0 | SStream_concat0(O, ", "); |
262 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
263 | 0 | (ArchRegNames ? "x8" : "s0")); |
264 | 0 | SStream_concat0(O, "-"); |
265 | |
|
266 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
267 | 0 | (ArchRegNames ? "x9" : "s1")); |
268 | 0 | break; |
269 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S2: |
270 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
271 | 0 | (ArchRegNames ? "x1" : "ra")); |
272 | 0 | SStream_concat0(O, ", "); |
273 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
274 | 0 | (ArchRegNames ? "x8" : "s0")); |
275 | 0 | SStream_concat0(O, "-"); |
276 | |
|
277 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
278 | 0 | (ArchRegNames ? "x9" : "s2")); |
279 | 0 | if (ArchRegNames) { |
280 | 0 | SStream_concat0(O, ", "); |
281 | 0 | SStream_concat0(markup_OS(O, Markup_Register), "x18"); |
282 | 0 | } |
283 | 0 | break; |
284 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S3: |
285 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S4: |
286 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S5: |
287 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S6: |
288 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S7: |
289 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S8: |
290 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S9: |
291 | 0 | case RISCVZC_RLISTENCODE_RA_S0_S11: |
292 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
293 | 0 | (ArchRegNames ? "x1" : "ra")); |
294 | 0 | SStream_concat0(O, ", "); |
295 | 0 | SStream_concat0(markup_OS(O, Markup_Register), |
296 | 0 | (ArchRegNames ? "x8" : "s0")); |
297 | 0 | SStream_concat0(O, "-"); |
298 | |
|
299 | 0 | if (ArchRegNames) { |
300 | 0 | SStream_concat0(markup_OS(O, Markup_Register), "x9"); |
301 | 0 | SStream_concat0(O, ", "); |
302 | 0 | SStream_concat0(markup_OS(O, Markup_Register), "x18"); |
303 | 0 | SStream_concat0(O, "-"); |
304 | 0 | } |
305 | 0 | SStream_concat0( |
306 | 0 | markup_OS(O, Markup_Register), |
307 | 0 | doGetRegisterName( |
308 | 0 | RISCV_X19 + |
309 | 0 | (Imm == RISCVZC_RLISTENCODE_RA_S0_S11 ? |
310 | 0 | 8 : |
311 | 0 | Imm - RISCVZC_RLISTENCODE_RA_S0_S3))); |
312 | 0 | break; |
313 | 0 | default: |
314 | 0 | CS_ASSERT(0 && "invalid register list"); |
315 | 0 | } |
316 | 0 | SStream_concat0(O, "}"); |
317 | 0 | } |
318 | | |
319 | | void printRegReg(MCInst *MI, unsigned OpNo, SStream *O) |
320 | 277 | { |
321 | 277 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_RegReg, OpNo); |
322 | 277 | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
323 | | |
324 | 277 | CS_ASSERT(MCOperand_isReg(MO) && |
325 | 277 | "printRegReg can only print register operands"); |
326 | 277 | if (MCOperand_getReg(MO) == RISCV_NoRegister) |
327 | 0 | return; |
328 | 277 | printRegName(O, MCOperand_getReg(MO)); |
329 | | |
330 | 277 | SStream_concat0(O, "("); |
331 | 277 | MCOperand *MO1 = MCInst_getOperand(MI, (OpNo + 1)); |
332 | 277 | CS_ASSERT(MCOperand_isReg(MO1) && |
333 | 277 | "printRegReg can only print register operands"); |
334 | 277 | printRegName(O, MCOperand_getReg(MO1)); |
335 | 277 | SStream_concat0(O, ")"); |
336 | 277 | } |
337 | | |
338 | | void printSpimm(MCInst *MI, unsigned OpNo, SStream *O) |
339 | 0 | { |
340 | 0 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_Spimm, OpNo); |
341 | 0 | int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
342 | 0 | unsigned Opcode = MCInst_getOpcode(MI); |
343 | 0 | bool IsRV64 = RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit); |
344 | 0 | bool IsEABI = RISCV_getFeatureBits(MI->csh->mode, RISCV_FeatureRVE); |
345 | 0 | int64_t Spimm = 0; |
346 | 0 | int64_t RlistVal = MCOperand_getImm(MCInst_getOperand(MI, (0))); |
347 | 0 | CS_ASSERT(RlistVal != 16 && "Incorrect rlist."); |
348 | 0 | unsigned Base = RISCVZC_getStackAdjBase(RlistVal, IsRV64, IsEABI); |
349 | 0 | Spimm = Imm + Base; |
350 | 0 | CS_ASSERT((Spimm >= Base && Spimm <= Base + 48) && "Incorrect spimm"); |
351 | 0 | if (Opcode == RISCV_CM_PUSH) |
352 | 0 | Spimm = -Spimm; |
353 | |
|
354 | 0 | RISCVZC_printSpimm(Spimm, markup_OS(O, Markup_Immediate)); |
355 | 0 | } |
356 | | |
357 | | void printVMaskReg(MCInst *MI, unsigned OpNo, SStream *O) |
358 | 2.05k | { |
359 | 2.05k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_VMaskReg, OpNo); |
360 | 2.05k | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
361 | | |
362 | 2.05k | CS_ASSERT(MCOperand_isReg(MO) && |
363 | 2.05k | "printVMaskReg can only print register operands"); |
364 | 2.05k | if (MCOperand_getReg(MO) == RISCV_NoRegister) |
365 | 1.25k | return; |
366 | 798 | SStream_concat0(O, ", "); |
367 | 798 | printRegName(O, MCOperand_getReg(MO)); |
368 | 798 | SStream_concat0(O, ".t"); |
369 | 798 | } |
370 | | |
371 | | void RISCV_LLVM_printInstruction(MCInst *MI, SStream *O, |
372 | | void * /* MCRegisterInfo* */ info) |
373 | 37.3k | { |
374 | 37.3k | MI->MRI = (MCRegisterInfo *)info; |
375 | | |
376 | 37.3k | MCInst_setIsAlias(MI, false); |
377 | | |
378 | | /* check for a non-compressed instruction */ |
379 | 37.3k | MCInst Uncompressed; |
380 | 37.3k | MCInst_Init(&Uncompressed, MI->csh->arch); |
381 | | |
382 | 37.3k | MCInst *McInstr = MI; |
383 | 37.3k | bool is_uncompressed = false; |
384 | | // side-effectful check for compressed instructions that creates the equivalent uncompressed instruction in case of true |
385 | | // (LLVM doesn't generate an API for doing a pure check) |
386 | 37.3k | if (uncompressInst(&Uncompressed, MI)) { |
387 | 22.6k | McInstr = &Uncompressed; |
388 | 22.6k | Uncompressed.address = MI->address; |
389 | 22.6k | Uncompressed.MRI = MI->MRI; |
390 | 22.6k | Uncompressed.csh = MI->csh; |
391 | 22.6k | Uncompressed.flat_insn = MI->flat_insn; |
392 | 22.6k | is_uncompressed = true; |
393 | 22.6k | } |
394 | | |
395 | | // print the exact instruction text and done |
396 | 37.3k | bool print_exact_text = |
397 | 37.3k | (MI->csh->syntax & CS_OPT_SYNTAX_NO_ALIAS_TEXT) || |
398 | 37.3k | (is_uncompressed && |
399 | 22.6k | MI->csh->syntax & CS_OPT_SYNTAX_NO_ALIAS_TEXT_COMPRESSED); |
400 | 37.3k | if (print_exact_text) { |
401 | 0 | printInstruction(MI, MI->address, O); |
402 | 37.3k | } else { |
403 | | // side-effectful check for alias instructions that prints to the SStream if true |
404 | 37.3k | if (printAliasInstr(McInstr, MI->address, O)) { |
405 | 6.89k | MCInst_setIsAlias(MI, true); |
406 | | // do we still want the exact details even if the text is alias ? |
407 | 6.89k | if (!map_use_alias_details(MI) && detail_is_set(MI)) { |
408 | | // disable actual printing |
409 | 0 | SStream_Close(O); |
410 | | // discard the alias operands |
411 | 0 | memset(MI->flat_insn->detail->riscv.operands, 0, |
412 | 0 | sizeof(MI->flat_insn->detail->riscv |
413 | 0 | .operands)); |
414 | 0 | MI->flat_insn->detail->riscv.op_count = 0; |
415 | | // re-disassemble again with no printing in order to obtain the full details |
416 | | // including the whole operands array |
417 | 0 | printInstruction(MI, MI->address, O); |
418 | | // re-open the stream to restore the usual state |
419 | 0 | SStream_Open(O); |
420 | 0 | } |
421 | 6.89k | } else // the instruction is not an alias |
422 | 30.4k | printInstruction(McInstr, MI->address, O); |
423 | 37.3k | } |
424 | 37.3k | RISCV_add_groups(MI); |
425 | 37.3k | RISCV_add_missing_write_access(MI); |
426 | 37.3k | RISCV_compact_operands(MI); |
427 | 37.3k | RISCV_set_alias_id(MI, O); |
428 | 37.3k | } |
429 | | |
430 | | const char *getSysRegName(unsigned reg) |
431 | 0 | { |
432 | 0 | const RISCV_SysReg *SysReg = RISCV_lookupSysRegByEncoding(reg); |
433 | 0 | return SysReg->Name; |
434 | 0 | } |
435 | | |
436 | | const char *RISCV_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx) |
437 | 8.91k | { |
438 | 8.91k | return getRegisterName(RegNo, AltIdx); |
439 | 8.91k | } |
440 | | |
441 | | bool isCompressed(MCInst *MI) |
442 | 37.3k | { |
443 | 37.3k | MCInst unused; |
444 | 37.3k | MCInst_Init(&unused, MI->csh->arch); |
445 | 37.3k | return uncompressInst(&unused, MI); |
446 | 37.3k | } |