/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 | 110k | { |
73 | 110k | return getRegisterName(Reg, ArchRegNames ? RISCV_NoRegAltName : |
74 | 110k | RISCV_ABIRegAltName); |
75 | 110k | } |
76 | | |
77 | | static inline void printRegName(SStream *O, MCRegister Reg) |
78 | 223k | { |
79 | 223k | SStream_concat0(markup_OS(O, Markup_Register), doGetRegisterName(Reg)); |
80 | 223k | } |
81 | | |
82 | | bool haveRequiredFeatures(const RISCV_SysReg *Reg, MCInst *MI) |
83 | 646 | { |
84 | | // Not in 32-bit mode. |
85 | 646 | if (Reg->isRV32Only && |
86 | 487 | RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit)) |
87 | 230 | return false; |
88 | | |
89 | 416 | return true; |
90 | 646 | } |
91 | | |
92 | | static inline void printOperand(MCInst *MI, unsigned OpNo, SStream *O) |
93 | 138k | { |
94 | 138k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_Operand, OpNo); |
95 | | |
96 | 138k | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
97 | | |
98 | 138k | if (MCOperand_isReg(MO)) { |
99 | 105k | printRegName(O, MCOperand_getReg(MO)); |
100 | 105k | return; |
101 | 105k | } |
102 | | |
103 | 32.9k | if (MCOperand_isImm(MO)) { |
104 | 32.9k | printInt64(markup_OS(O, Markup_Immediate), |
105 | 32.9k | MCOperand_getImm(MO)); |
106 | 32.9k | return; |
107 | 32.9k | } |
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 | 5.43k | { |
116 | 5.43k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_BranchOperand, OpNo); |
117 | 5.43k | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
118 | 5.43k | if (!MCOperand_isImm(MO)) |
119 | 0 | return printOperand(MI, OpNo, O); |
120 | | |
121 | 5.43k | if (MI->csh->PrintBranchImmAsAddress) { |
122 | 5.43k | uint64_t Target = Address + MCOperand_getImm(MO); |
123 | 5.43k | if (!RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit)) |
124 | 2.86k | Target &= 0xffffffff; |
125 | 5.43k | printUInt64(markup_OS(O, Markup_Target), Target); |
126 | 5.43k | } else { |
127 | 0 | printInt64(markup_OS(O, Markup_Target), MCOperand_getImm(MO)); |
128 | 0 | } |
129 | 5.43k | } |
130 | | |
131 | | void printCSRSystemRegister(MCInst *MI, unsigned OpNo, SStream *O) |
132 | 1.81k | { |
133 | 1.81k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_CSRSystemRegister, OpNo); |
134 | 1.81k | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
135 | 1.81k | const RISCV_SysReg *SysReg = RISCV_lookupSysRegByEncoding(Imm); |
136 | 1.81k | if (SysReg && haveRequiredFeatures(SysReg, MI)) |
137 | 416 | SStream_concat0(markup_OS(O, Markup_Register), SysReg->Name); |
138 | 1.39k | else |
139 | 1.39k | printUInt64(markup_OS(O, Markup_Register), Imm); |
140 | 1.81k | } |
141 | | |
142 | | void printFenceArg(MCInst *MI, unsigned OpNo, SStream *O) |
143 | 1.08k | { |
144 | 1.08k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FenceArg, OpNo); |
145 | 1.08k | unsigned FenceArg = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
146 | 1.08k | CS_ASSERT(((FenceArg >> 4) == 0) && |
147 | 1.08k | "Invalid immediate in printFenceArg"); |
148 | | |
149 | 1.08k | if ((FenceArg & RISCVFenceField_I) != 0) |
150 | 475 | SStream_concat0(O, "i"); |
151 | | |
152 | 1.08k | if ((FenceArg & RISCVFenceField_O) != 0) |
153 | 258 | SStream_concat0(O, "o"); |
154 | | |
155 | 1.08k | if ((FenceArg & RISCVFenceField_R) != 0) |
156 | 483 | SStream_concat0(O, "r"); |
157 | | |
158 | 1.08k | if ((FenceArg & RISCVFenceField_W) != 0) |
159 | 443 | SStream_concat0(O, "w"); |
160 | | |
161 | 1.08k | if (FenceArg == 0) |
162 | 384 | SStream_concat0(O, "0"); |
163 | 1.08k | } |
164 | | |
165 | | void printFRMArg(MCInst *MI, unsigned OpNo, SStream *O) |
166 | 3.52k | { |
167 | 3.52k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FRMArg, OpNo); |
168 | 3.52k | unsigned FRMArg = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
169 | 3.52k | if (!(MI->csh->syntax & CS_OPT_SYNTAX_NO_ALIAS_TEXT) && |
170 | 3.52k | FRMArg == RISCVFPRndMode_DYN) |
171 | 427 | return; |
172 | 3.09k | SStream_concat(O, "%s", ", "); |
173 | 3.09k | SStream_concat0(O, RISCVFPRndMode_roundingModeToString(FRMArg)); |
174 | 3.09k | } |
175 | | |
176 | | void printFRMArgLegacy(MCInst *MI, unsigned OpNo, SStream *O) |
177 | 466 | { |
178 | 466 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FRMArgLegacy, OpNo); |
179 | 466 | 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 | 466 | if (FRMArg == RISCVFPRndMode_RNE) |
184 | 42 | return; |
185 | 424 | SStream_concat(O, "%s", ", "); |
186 | 424 | SStream_concat0(O, RISCVFPRndMode_roundingModeToString(FRMArg)); |
187 | 424 | } |
188 | | |
189 | | void printFPImmOperand(MCInst *MI, unsigned OpNo, SStream *O) |
190 | 1.04k | { |
191 | 1.04k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_FPImmOperand, OpNo); |
192 | 1.04k | unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); |
193 | 1.04k | if (Imm == 1) { |
194 | 68 | SStream_concat0(markup_OS(O, Markup_Immediate), "min"); |
195 | 977 | } else if (Imm == 30) { |
196 | 533 | SStream_concat0(markup_OS(O, Markup_Immediate), "inf"); |
197 | 533 | } else if (Imm == 31) { |
198 | 20 | SStream_concat0(markup_OS(O, Markup_Immediate), "nan"); |
199 | 424 | } else { |
200 | 424 | 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 | 424 | if (FPVal == (int)(FPVal)) |
206 | 351 | printfFloat(markup_OS(O, Markup_Immediate), "%.1f", |
207 | 351 | FPVal); |
208 | 73 | else |
209 | 73 | printfFloat(markup_OS(O, Markup_Immediate), "%.12g", |
210 | 73 | FPVal); |
211 | 424 | } |
212 | 1.04k | } |
213 | | |
214 | | void printZeroOffsetMemOp(MCInst *MI, unsigned OpNo, SStream *O) |
215 | 1.76k | { |
216 | 1.76k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_ZeroOffsetMemOp, OpNo); |
217 | 1.76k | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
218 | | |
219 | 1.76k | CS_ASSERT(MCOperand_isReg(MO) && |
220 | 1.76k | "printZeroOffsetMemOp can only print register operands"); |
221 | 1.76k | SStream_concat0(O, "("); |
222 | 1.76k | printRegName(O, MCOperand_getReg(MO)); |
223 | 1.76k | SStream_concat0(O, ")"); |
224 | 1.76k | } |
225 | | |
226 | | void printVTypeI(MCInst *MI, unsigned OpNo, SStream *O) |
227 | 2.09k | { |
228 | 2.09k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_VTypeI, OpNo); |
229 | 2.09k | 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 | 2.09k | if (RISCVVType_getVLMUL(Imm) == RISCVII_LMUL_RESERVED || |
233 | 2.07k | RISCVVType_getSEW(Imm) > 64 || (Imm >> 8) != 0) { |
234 | 1.13k | printUInt64(O, Imm); |
235 | 1.13k | return; |
236 | 1.13k | } |
237 | | // Print the text form. |
238 | 962 | printVType(Imm, O); |
239 | 962 | } |
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 | 766 | { |
321 | 766 | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_RegReg, OpNo); |
322 | 766 | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
323 | | |
324 | 766 | CS_ASSERT(MCOperand_isReg(MO) && |
325 | 766 | "printRegReg can only print register operands"); |
326 | 766 | if (MCOperand_getReg(MO) == RISCV_NoRegister) |
327 | 0 | return; |
328 | 766 | printRegName(O, MCOperand_getReg(MO)); |
329 | | |
330 | 766 | SStream_concat0(O, "("); |
331 | 766 | MCOperand *MO1 = MCInst_getOperand(MI, (OpNo + 1)); |
332 | 766 | CS_ASSERT(MCOperand_isReg(MO1) && |
333 | 766 | "printRegReg can only print register operands"); |
334 | 766 | printRegName(O, MCOperand_getReg(MO1)); |
335 | 766 | SStream_concat0(O, ")"); |
336 | 766 | } |
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 | 4.43k | { |
359 | 4.43k | RISCV_add_cs_detail_0(MI, RISCV_OP_GROUP_VMaskReg, OpNo); |
360 | 4.43k | MCOperand *MO = MCInst_getOperand(MI, (OpNo)); |
361 | | |
362 | 4.43k | CS_ASSERT(MCOperand_isReg(MO) && |
363 | 4.43k | "printVMaskReg can only print register operands"); |
364 | 4.43k | if (MCOperand_getReg(MO) == RISCV_NoRegister) |
365 | 2.60k | return; |
366 | 1.83k | SStream_concat0(O, ", "); |
367 | 1.83k | printRegName(O, MCOperand_getReg(MO)); |
368 | 1.83k | SStream_concat0(O, ".t"); |
369 | 1.83k | } |
370 | | |
371 | | void RISCV_LLVM_printInstruction(MCInst *MI, SStream *O, |
372 | | void * /* MCRegisterInfo* */ info) |
373 | 62.0k | { |
374 | 62.0k | MI->MRI = (MCRegisterInfo *)info; |
375 | | |
376 | 62.0k | MCInst_setIsAlias(MI, false); |
377 | 62.0k | bool usesAliasDetails = map_use_alias_details(MI); |
378 | 62.0k | MI->flat_insn->usesAliasDetails = usesAliasDetails; |
379 | | |
380 | | /* check for a non-compressed instruction */ |
381 | 62.0k | MCInst Uncompressed; |
382 | 62.0k | MCInst_Init(&Uncompressed, MI->csh->arch); |
383 | | |
384 | 62.0k | MCInst *McInstr = MI; |
385 | 62.0k | bool is_uncompressed = false; |
386 | | // side-effectful check for compressed instructions that creates the equivalent uncompressed instruction in case of true |
387 | | // (LLVM doesn't generate an API for doing a pure check) |
388 | 62.0k | if (uncompressInst(&Uncompressed, MI)) { |
389 | 32.3k | McInstr = &Uncompressed; |
390 | 32.3k | Uncompressed.address = MI->address; |
391 | 32.3k | Uncompressed.MRI = MI->MRI; |
392 | 32.3k | Uncompressed.csh = MI->csh; |
393 | 32.3k | Uncompressed.flat_insn = MI->flat_insn; |
394 | 32.3k | is_uncompressed = true; |
395 | 32.3k | } |
396 | | |
397 | | // print the exact instruction text and done |
398 | 62.0k | bool print_exact_text = |
399 | 62.0k | (MI->csh->syntax & CS_OPT_SYNTAX_NO_ALIAS_TEXT) || |
400 | 62.0k | (is_uncompressed && |
401 | 32.3k | MI->csh->syntax & CS_OPT_SYNTAX_NO_ALIAS_TEXT_COMPRESSED); |
402 | 62.0k | if (print_exact_text) { |
403 | 0 | printInstruction(MI, MI->address, O); |
404 | 62.0k | } else { |
405 | | // side-effectful check for alias instructions that prints to the SStream if true |
406 | 62.0k | if (printAliasInstr(McInstr, MI->address, O)) { |
407 | 8.31k | MCInst_setIsAlias(MI, true); |
408 | | // do we still want the exact details even if the text is alias ? |
409 | 8.31k | if (!usesAliasDetails && detail_is_set(MI)) { |
410 | | // disable actual printing |
411 | 0 | SStream_Close(O); |
412 | | // discard the alias operands |
413 | 0 | memset(MI->flat_insn->detail->riscv.operands, 0, |
414 | 0 | sizeof(MI->flat_insn->detail->riscv |
415 | 0 | .operands)); |
416 | 0 | MI->flat_insn->detail->riscv.op_count = 0; |
417 | | // re-disassemble again with no printing in order to obtain the full details |
418 | | // including the whole operands array |
419 | 0 | printInstruction(MI, MI->address, O); |
420 | | // re-open the stream to restore the usual state |
421 | 0 | SStream_Open(O); |
422 | 0 | } |
423 | 8.31k | } else // the instruction is not an alias |
424 | 53.7k | printInstruction(McInstr, MI->address, O); |
425 | 62.0k | } |
426 | 62.0k | RISCV_add_groups(MI); |
427 | 62.0k | RISCV_add_missing_write_access(MI); |
428 | 62.0k | RISCV_compact_operands(MI); |
429 | 62.0k | RISCV_set_alias_id(MI, O); |
430 | 62.0k | } |
431 | | |
432 | | const char *getSysRegName(unsigned reg) |
433 | 0 | { |
434 | 0 | const RISCV_SysReg *SysReg = RISCV_lookupSysRegByEncoding(reg); |
435 | 0 | return SysReg->Name; |
436 | 0 | } |
437 | | |
438 | | const char *RISCV_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx) |
439 | 19.1k | { |
440 | 19.1k | return getRegisterName(RegNo, AltIdx); |
441 | 19.1k | } |
442 | | |
443 | | bool isCompressed(MCInst *MI) |
444 | 62.0k | { |
445 | 62.0k | MCInst unused; |
446 | 62.0k | MCInst_Init(&unused, MI->csh->arch); |
447 | 62.0k | return uncompressInst(&unused, MI); |
448 | 62.0k | } |