/src/capstonenext/arch/RISCV/RISCVInstPrinter.c
Line  | Count  | Source  | 
1  |  | //===-- RISCVInstPrinter.cpp - Convert RISCV MCInst to asm syntax ---------===//  | 
2  |  | //  | 
3  |  | //                     The LLVM Compiler Infrastructure  | 
4  |  | //  | 
5  |  | // This file is distributed under the University of Illinois Open Source  | 
6  |  | // License. See LICENSE.TXT for details.  | 
7  |  | //  | 
8  |  | //===----------------------------------------------------------------------===//  | 
9  |  | //  | 
10  |  | // This class prints an RISCV MCInst to a .s file.  | 
11  |  | //  | 
12  |  | //===----------------------------------------------------------------------===//  | 
13  |  |  | 
14  |  | #ifdef CAPSTONE_HAS_RISCV  | 
15  |  |  | 
16  |  | #include <stdio.h> // DEBUG  | 
17  |  | #include <stdlib.h>  | 
18  |  | #include <string.h>  | 
19  |  | #include <capstone/platform.h>  | 
20  |  |  | 
21  |  | #include "RISCVInstPrinter.h"  | 
22  |  | #include "RISCVBaseInfo.h"  | 
23  |  | #include "../../MCInst.h"  | 
24  |  | #include "../../SStream.h"  | 
25  |  | #include "../../MCRegisterInfo.h"  | 
26  |  | #include "../../utils.h"  | 
27  |  | #include "../../Mapping.h"  | 
28  |  | #include "RISCVMapping.h"  | 
29  |  |  | 
30  |  | //#include "RISCVDisassembler.h"  | 
31  |  |  | 
32  |  | #define GET_REGINFO_ENUM  | 
33  |  | #define GET_REGINFO_MC_DESC  | 
34  |  | #include "RISCVGenRegisterInfo.inc"  | 
35  |  | #define GET_INSTRINFO_ENUM  | 
36  |  | #include "RISCVGenInstrInfo.inc"  | 
37  |  |  | 
38  |  | // Autogenerated by tblgen.  | 
39  |  | static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI);  | 
40  |  | static bool printAliasInstr(MCInst *MI, SStream *OS, void *info);  | 
41  |  | static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);  | 
42  |  | static void printFenceArg(MCInst *MI, unsigned OpNo, SStream *O);  | 
43  |  | static void printCSRSystemRegister(MCInst *, unsigned, SStream *);  | 
44  |  | static void printFRMArg(MCInst *MI, unsigned OpNo, SStream *O);  | 
45  |  | static void printCustomAliasOperand(MCInst *, unsigned, unsigned, SStream *);  | 
46  |  | /// getRegisterName - This method is automatically generated by tblgen  | 
47  |  | /// from the register set description.  This returns the assembler name  | 
48  |  | /// for the specified register.  | 
49  |  | static const char *getRegisterName(unsigned RegNo, unsigned AltIdx);  | 
50  |  |  | 
51  |  | // Include the auto-generated portion of the assembly writer.  | 
52  |  | #define PRINT_ALIAS_INSTR  | 
53  |  | #include "RISCVGenAsmWriter.inc"  | 
54  |  |  | 
55  |  | static void fixDetailOfEffectiveAddr(MCInst *MI)  | 
56  | 16.0k  | { | 
57  |  |   // Operands for load and store instructions in RISCV vary widely  | 
58  | 16.0k  |   unsigned id = MI->flat_insn->id;  | 
59  | 16.0k  |   unsigned reg = 0;  | 
60  | 16.0k  |   int64_t imm = 0;  | 
61  | 16.0k  |   uint8_t access = 0;  | 
62  |  |  | 
63  | 16.0k  |   switch (id) { | 
64  | 0  |   case RISCV_INS_C_FLD:  | 
65  | 0  |   case RISCV_INS_C_LW:  | 
66  | 0  |   case RISCV_INS_C_FLW:  | 
67  | 0  |   case RISCV_INS_C_LD:  | 
68  | 0  |   case RISCV_INS_C_FSD:  | 
69  | 0  |   case RISCV_INS_C_SW:  | 
70  | 0  |   case RISCV_INS_C_FSW:  | 
71  | 0  |   case RISCV_INS_C_SD:  | 
72  | 0  |   case RISCV_INS_C_FLDSP:  | 
73  | 0  |   case RISCV_INS_C_LWSP:  | 
74  | 0  |   case RISCV_INS_C_FLWSP:  | 
75  | 0  |   case RISCV_INS_C_LDSP:  | 
76  | 0  |   case RISCV_INS_C_FSDSP:  | 
77  | 0  |   case RISCV_INS_C_SWSP:  | 
78  | 0  |   case RISCV_INS_C_FSWSP:  | 
79  | 0  |   case RISCV_INS_C_SDSP:  | 
80  | 324  |   case RISCV_INS_FLW:  | 
81  | 652  |   case RISCV_INS_FSW:  | 
82  | 848  |   case RISCV_INS_FLD:  | 
83  | 922  |   case RISCV_INS_FSD:  | 
84  | 1.30k  |   case RISCV_INS_LB:  | 
85  | 1.42k  |   case RISCV_INS_LBU:  | 
86  | 1.50k  |   case RISCV_INS_LD:  | 
87  | 1.60k  |   case RISCV_INS_LH:  | 
88  | 1.83k  |   case RISCV_INS_LHU:  | 
89  | 2.39k  |   case RISCV_INS_LW:  | 
90  | 2.49k  |   case RISCV_INS_LWU:  | 
91  | 2.75k  |   case RISCV_INS_SB:  | 
92  | 3.11k  |   case RISCV_INS_SD:  | 
93  | 3.88k  |   case RISCV_INS_SH:  | 
94  | 4.76k  |   case RISCV_INS_SW: { | 
95  | 4.76k  |     CS_ASSERT(3 == MI->flat_insn->detail->riscv.op_count);  | 
96  | 4.76k  |     CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -3)->type);  | 
97  | 4.76k  |     CS_ASSERT(RISCV_OP_IMM == RISCV_get_detail_op(MI, -2)->type);  | 
98  | 4.76k  |     CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -1)->type);  | 
99  |  |  | 
100  | 4.76k  |     imm = RISCV_get_detail_op(MI, -2)->imm;  | 
101  | 4.76k  |     reg = RISCV_get_detail_op(MI, -1)->reg;  | 
102  | 4.76k  |     access = RISCV_get_detail_op(MI, -1)->access;  | 
103  |  |  | 
104  | 4.76k  |     RISCV_get_detail_op(MI, -2)->type = RISCV_OP_MEM;  | 
105  | 4.76k  |     RISCV_get_detail_op(MI, -2)->mem.base = reg;  | 
106  | 4.76k  |     RISCV_get_detail_op(MI, -2)->mem.disp = imm;  | 
107  | 4.76k  |     RISCV_get_detail_op(MI, -2)->access = access;  | 
108  |  |  | 
109  | 4.76k  |     RISCV_dec_op_count(MI);  | 
110  |  |  | 
111  | 4.76k  |     break;  | 
112  | 3.88k  |   }  | 
113  | 35  |   case RISCV_INS_LR_W:  | 
114  | 102  |   case RISCV_INS_LR_W_AQ:  | 
115  | 607  |   case RISCV_INS_LR_W_AQ_RL:  | 
116  | 643  |   case RISCV_INS_LR_W_RL:  | 
117  | 662  |   case RISCV_INS_LR_D:  | 
118  | 701  |   case RISCV_INS_LR_D_AQ:  | 
119  | 1.84k  |   case RISCV_INS_LR_D_AQ_RL:  | 
120  | 1.93k  |   case RISCV_INS_LR_D_RL: { | 
121  | 1.93k  |     CS_ASSERT(2 == MI->flat_insn->detail->riscv.op_count);  | 
122  | 1.93k  |     CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -1)->type);  | 
123  | 1.93k  |     CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -2)->type);  | 
124  |  |  | 
125  | 1.93k  |     reg = RISCV_get_detail_op(MI, -1)->reg;  | 
126  |  |  | 
127  | 1.93k  |     RISCV_get_detail_op(MI, -1)->type = RISCV_OP_MEM;  | 
128  | 1.93k  |     RISCV_get_detail_op(MI, -1)->mem.base = reg;  | 
129  | 1.93k  |     RISCV_get_detail_op(MI, -1)->mem.disp = 0;  | 
130  |  |  | 
131  | 1.93k  |     break;  | 
132  | 1.84k  |   }  | 
133  | 34  |   case RISCV_INS_SC_W:  | 
134  | 101  |   case RISCV_INS_SC_W_AQ:  | 
135  | 296  |   case RISCV_INS_SC_W_AQ_RL:  | 
136  | 365  |   case RISCV_INS_SC_W_RL:  | 
137  | 399  |   case RISCV_INS_SC_D:  | 
138  | 418  |   case RISCV_INS_SC_D_AQ:  | 
139  | 665  |   case RISCV_INS_SC_D_AQ_RL:  | 
140  | 733  |   case RISCV_INS_SC_D_RL:  | 
141  | 816  |   case RISCV_INS_AMOADD_D:  | 
142  | 852  |   case RISCV_INS_AMOADD_D_AQ:  | 
143  | 1.55k  |   case RISCV_INS_AMOADD_D_AQ_RL:  | 
144  | 1.65k  |   case RISCV_INS_AMOADD_D_RL:  | 
145  | 1.72k  |   case RISCV_INS_AMOADD_W:  | 
146  | 1.93k  |   case RISCV_INS_AMOADD_W_AQ:  | 
147  | 2.08k  |   case RISCV_INS_AMOADD_W_AQ_RL:  | 
148  | 2.58k  |   case RISCV_INS_AMOADD_W_RL:  | 
149  | 2.73k  |   case RISCV_INS_AMOAND_D:  | 
150  | 2.77k  |   case RISCV_INS_AMOAND_D_AQ:  | 
151  | 2.78k  |   case RISCV_INS_AMOAND_D_AQ_RL:  | 
152  | 2.99k  |   case RISCV_INS_AMOAND_D_RL:  | 
153  | 3.02k  |   case RISCV_INS_AMOAND_W:  | 
154  | 3.09k  |   case RISCV_INS_AMOAND_W_AQ:  | 
155  | 3.16k  |   case RISCV_INS_AMOAND_W_AQ_RL:  | 
156  | 3.23k  |   case RISCV_INS_AMOAND_W_RL:  | 
157  | 3.82k  |   case RISCV_INS_AMOMAXU_D:  | 
158  | 3.92k  |   case RISCV_INS_AMOMAXU_D_AQ:  | 
159  | 3.99k  |   case RISCV_INS_AMOMAXU_D_AQ_RL:  | 
160  | 4.02k  |   case RISCV_INS_AMOMAXU_D_RL:  | 
161  | 4.06k  |   case RISCV_INS_AMOMAXU_W:  | 
162  | 4.09k  |   case RISCV_INS_AMOMAXU_W_AQ:  | 
163  | 4.16k  |   case RISCV_INS_AMOMAXU_W_AQ_RL:  | 
164  | 4.23k  |   case RISCV_INS_AMOMAXU_W_RL:  | 
165  | 4.26k  |   case RISCV_INS_AMOMAX_D:  | 
166  | 4.30k  |   case RISCV_INS_AMOMAX_D_AQ:  | 
167  | 4.33k  |   case RISCV_INS_AMOMAX_D_AQ_RL:  | 
168  | 4.40k  |   case RISCV_INS_AMOMAX_D_RL:  | 
169  | 4.46k  |   case RISCV_INS_AMOMAX_W:  | 
170  | 4.53k  |   case RISCV_INS_AMOMAX_W_AQ:  | 
171  | 4.74k  |   case RISCV_INS_AMOMAX_W_AQ_RL:  | 
172  | 4.82k  |   case RISCV_INS_AMOMAX_W_RL:  | 
173  | 4.85k  |   case RISCV_INS_AMOMINU_D:  | 
174  | 4.89k  |   case RISCV_INS_AMOMINU_D_AQ:  | 
175  | 4.92k  |   case RISCV_INS_AMOMINU_D_AQ_RL:  | 
176  | 5.00k  |   case RISCV_INS_AMOMINU_D_RL:  | 
177  | 5.06k  |   case RISCV_INS_AMOMINU_W:  | 
178  | 5.13k  |   case RISCV_INS_AMOMINU_W_AQ:  | 
179  | 5.33k  |   case RISCV_INS_AMOMINU_W_AQ_RL:  | 
180  | 5.35k  |   case RISCV_INS_AMOMINU_W_RL:  | 
181  | 6.90k  |   case RISCV_INS_AMOMIN_D:  | 
182  | 7.30k  |   case RISCV_INS_AMOMIN_D_AQ:  | 
183  | 7.37k  |   case RISCV_INS_AMOMIN_D_AQ_RL:  | 
184  | 7.44k  |   case RISCV_INS_AMOMIN_D_RL:  | 
185  | 7.48k  |   case RISCV_INS_AMOMIN_W:  | 
186  | 7.51k  |   case RISCV_INS_AMOMIN_W_AQ:  | 
187  | 7.55k  |   case RISCV_INS_AMOMIN_W_AQ_RL:  | 
188  | 7.58k  |   case RISCV_INS_AMOMIN_W_RL:  | 
189  | 7.65k  |   case RISCV_INS_AMOOR_D:  | 
190  | 7.67k  |   case RISCV_INS_AMOOR_D_AQ:  | 
191  | 7.75k  |   case RISCV_INS_AMOOR_D_AQ_RL:  | 
192  | 7.77k  |   case RISCV_INS_AMOOR_D_RL:  | 
193  | 7.84k  |   case RISCV_INS_AMOOR_W:  | 
194  | 7.91k  |   case RISCV_INS_AMOOR_W_AQ:  | 
195  | 7.94k  |   case RISCV_INS_AMOOR_W_AQ_RL:  | 
196  | 8.01k  |   case RISCV_INS_AMOOR_W_RL:  | 
197  | 8.08k  |   case RISCV_INS_AMOSWAP_D:  | 
198  | 8.15k  |   case RISCV_INS_AMOSWAP_D_AQ:  | 
199  | 8.31k  |   case RISCV_INS_AMOSWAP_D_AQ_RL:  | 
200  | 8.39k  |   case RISCV_INS_AMOSWAP_D_RL:  | 
201  | 8.42k  |   case RISCV_INS_AMOSWAP_W:  | 
202  | 8.46k  |   case RISCV_INS_AMOSWAP_W_AQ:  | 
203  | 8.49k  |   case RISCV_INS_AMOSWAP_W_AQ_RL:  | 
204  | 8.54k  |   case RISCV_INS_AMOSWAP_W_RL:  | 
205  | 8.78k  |   case RISCV_INS_AMOXOR_D:  | 
206  | 8.82k  |   case RISCV_INS_AMOXOR_D_AQ:  | 
207  | 8.91k  |   case RISCV_INS_AMOXOR_D_AQ_RL:  | 
208  | 8.97k  |   case RISCV_INS_AMOXOR_D_RL:  | 
209  | 9.04k  |   case RISCV_INS_AMOXOR_W:  | 
210  | 9.06k  |   case RISCV_INS_AMOXOR_W_AQ:  | 
211  | 9.11k  |   case RISCV_INS_AMOXOR_W_AQ_RL:  | 
212  | 9.31k  |   case RISCV_INS_AMOXOR_W_RL: { | 
213  | 9.31k  |     CS_ASSERT(3 == MI->flat_insn->detail->riscv.op_count);  | 
214  | 9.31k  |     CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -3)->type);  | 
215  | 9.31k  |     CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -2)->type);  | 
216  | 9.31k  |     CS_ASSERT(RISCV_OP_REG == RISCV_get_detail_op(MI, -1)->type);  | 
217  |  |  | 
218  | 9.31k  |     reg = RISCV_get_detail_op(MI, -1)->reg;  | 
219  |  |  | 
220  | 9.31k  |     RISCV_get_detail_op(MI, -1)->type = RISCV_OP_MEM;  | 
221  | 9.31k  |     RISCV_get_detail_op(MI, -1)->mem.base = reg;  | 
222  | 9.31k  |     RISCV_get_detail_op(MI, -1)->mem.disp = 0;  | 
223  |  |  | 
224  | 9.31k  |     break;  | 
225  | 9.11k  |   }  | 
226  | 0  |   default: { | 
227  | 0  |     CS_ASSERT(0 && "id is not a RISC-V memory instruction");  | 
228  | 0  |     break;  | 
229  | 9.11k  |   }  | 
230  | 16.0k  |   }  | 
231  | 16.0k  |   return;  | 
232  | 16.0k  | }  | 
233  |  |  | 
234  |  | //void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O,  | 
235  |  | //                                 StringRef Annot, const MCSubtargetInfo &STI)  | 
236  |  | void RISCV_printInst(MCInst *MI, SStream *O, void *info)  | 
237  | 258k  | { | 
238  | 258k  |   MCRegisterInfo *MRI = (MCRegisterInfo *)info;  | 
239  |  |   //bool Res = false;  | 
240  |  |   //MCInst *NewMI = MI;  | 
241  |  |   // TODO: RISCV compressd instructions.  | 
242  |  |   //MCInst UncompressedMI;  | 
243  |  |   //if (!NoAliases)  | 
244  |  |   //Res = uncompressInst(UncompressedMI, *MI, MRI, STI);  | 
245  |  |   //if (Res)  | 
246  |  |   //NewMI = const_cast<MCInst *>(&UncompressedMI);  | 
247  | 258k  |   if (/*NoAliases ||*/ !printAliasInstr(MI, O, info))  | 
248  | 189k  |     printInstruction(MI, O, MRI);  | 
249  |  |   //printAnnotation(O, Annot);  | 
250  |  |   // fix load/store type insttuction  | 
251  | 258k  |   if (MI->csh->detail_opt &&  | 
252  | 258k  |       MI->flat_insn->detail->riscv.need_effective_addr)  | 
253  | 17.4k  |     fixDetailOfEffectiveAddr(MI);  | 
254  |  |  | 
255  | 258k  |   return;  | 
256  | 258k  | }  | 
257  |  |  | 
258  |  | static void printRegName(SStream *OS, unsigned RegNo)  | 
259  | 437k  | { | 
260  | 437k  |   SStream_concat0(OS, getRegisterName(RegNo, RISCV_ABIRegAltName));  | 
261  | 437k  | }  | 
262  |  |  | 
263  |  | /**  | 
264  |  | void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,  | 
265  |  |                                     raw_ostream &O, const char *Modifier)   | 
266  |  | */  | 
267  |  | static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
268  | 236k  | { | 
269  | 236k  |   unsigned reg;  | 
270  | 236k  |   int64_t Imm = 0;  | 
271  |  |  | 
272  | 236k  |   RISCV_add_cs_detail(MI, OpNo);  | 
273  |  |  | 
274  | 236k  |   MCOperand *MO = MCInst_getOperand(MI, OpNo);  | 
275  |  |  | 
276  | 236k  |   if (MCOperand_isReg(MO)) { | 
277  | 202k  |     reg = MCOperand_getReg(MO);  | 
278  | 202k  |     printRegName(O, reg);  | 
279  | 202k  |   } else { | 
280  | 34.2k  |     CS_ASSERT(MCOperand_isImm(MO) &&  | 
281  | 34.2k  |         "Unknown operand kind in printOperand");  | 
282  | 34.2k  |     Imm = MCOperand_getImm(MO);  | 
283  | 34.2k  |     if (Imm >= 0) { | 
284  | 30.4k  |       if (Imm > HEX_THRESHOLD)  | 
285  | 19.1k  |         SStream_concat(O, "0x%" PRIx64, Imm);  | 
286  | 11.3k  |       else  | 
287  | 11.3k  |         SStream_concat(O, "%" PRIu64, Imm);  | 
288  | 30.4k  |     } else { | 
289  | 3.74k  |       if (Imm < -HEX_THRESHOLD)  | 
290  | 3.66k  |         SStream_concat(O, "-0x%" PRIx64, -Imm);  | 
291  | 82  |       else  | 
292  | 82  |         SStream_concat(O, "-%" PRIu64, -Imm);  | 
293  | 3.74k  |     }  | 
294  | 34.2k  |   }  | 
295  |  |  | 
296  |  |   //CS_ASSERT(MO.isExpr() && "Unknown operand kind in printOperand");  | 
297  |  |  | 
298  | 236k  |   return;  | 
299  | 236k  | }  | 
300  |  |  | 
301  |  | static const char *getCSRSystemRegisterName(unsigned CsrNo)  | 
302  | 152k  | { | 
303  | 152k  |   switch (CsrNo) { | 
304  |  |   /*  | 
305  |  |    * From RISC-V Privileged Architecture Version 1.10.  | 
306  |  |    * In the same order as Table 2.5.  | 
307  |  |    */  | 
308  | 1.02k  |   case 0x0000:  | 
309  | 1.02k  |     return "ustatus";  | 
310  | 450  |   case 0x0004:  | 
311  | 450  |     return "uie";  | 
312  | 163  |   case 0x0005:  | 
313  | 163  |     return "utvec";  | 
314  |  |  | 
315  | 179  |   case 0x0040:  | 
316  | 179  |     return "uscratch";  | 
317  | 138  |   case 0x0041:  | 
318  | 138  |     return "uepc";  | 
319  | 1.09k  |   case 0x0042:  | 
320  | 1.09k  |     return "ucause";  | 
321  | 380  |   case 0x0043:  | 
322  | 380  |     return "utval";  | 
323  | 391  |   case 0x0044:  | 
324  | 391  |     return "uip";  | 
325  |  |  | 
326  | 1.18k  |   case 0x0001:  | 
327  | 1.18k  |     return "fflags";  | 
328  | 1.24k  |   case 0x0002:  | 
329  | 1.24k  |     return "frm";  | 
330  | 1.45k  |   case 0x0003:  | 
331  | 1.45k  |     return "fcsr";  | 
332  |  |  | 
333  | 2.08k  |   case 0x0c00:  | 
334  | 2.08k  |     return "cycle";  | 
335  | 2.30k  |   case 0x0c01:  | 
336  | 2.30k  |     return "time";  | 
337  | 842  |   case 0x0c02:  | 
338  | 842  |     return "instret";  | 
339  | 239  |   case 0x0c03:  | 
340  | 239  |     return "hpmcounter3";  | 
341  | 1.22k  |   case 0x0c04:  | 
342  | 1.22k  |     return "hpmcounter4";  | 
343  | 731  |   case 0x0c05:  | 
344  | 731  |     return "hpmcounter5";  | 
345  | 385  |   case 0x0c06:  | 
346  | 385  |     return "hpmcounter6";  | 
347  | 703  |   case 0x0c07:  | 
348  | 703  |     return "hpmcounter7";  | 
349  | 999  |   case 0x0c08:  | 
350  | 999  |     return "hpmcounter8";  | 
351  | 400  |   case 0x0c09:  | 
352  | 400  |     return "hpmcounter9";  | 
353  | 720  |   case 0x0c0a:  | 
354  | 720  |     return "hpmcounter10";  | 
355  | 1.12k  |   case 0x0c0b:  | 
356  | 1.12k  |     return "hpmcounter11";  | 
357  | 1.22k  |   case 0x0c0c:  | 
358  | 1.22k  |     return "hpmcounter12";  | 
359  | 463  |   case 0x0c0d:  | 
360  | 463  |     return "hpmcounter13";  | 
361  | 224  |   case 0x0c0e:  | 
362  | 224  |     return "hpmcounter14";  | 
363  | 412  |   case 0x0c0f:  | 
364  | 412  |     return "hpmcounter15";  | 
365  | 349  |   case 0x0c10:  | 
366  | 349  |     return "hpmcounter16";  | 
367  | 494  |   case 0x0c11:  | 
368  | 494  |     return "hpmcounter17";  | 
369  | 188  |   case 0x0c12:  | 
370  | 188  |     return "hpmcounter18";  | 
371  | 115  |   case 0x0c13:  | 
372  | 115  |     return "hpmcounter19";  | 
373  | 1.44k  |   case 0x0c14:  | 
374  | 1.44k  |     return "hpmcounter20";  | 
375  | 153  |   case 0x0c15:  | 
376  | 153  |     return "hpmcounter21";  | 
377  | 323  |   case 0x0c16:  | 
378  | 323  |     return "hpmcounter22";  | 
379  | 1.46k  |   case 0x0c17:  | 
380  | 1.46k  |     return "hpmcounter23";  | 
381  | 586  |   case 0x0c18:  | 
382  | 586  |     return "hpmcounter24";  | 
383  | 1.79k  |   case 0x0c19:  | 
384  | 1.79k  |     return "hpmcounter25";  | 
385  | 559  |   case 0x0c1a:  | 
386  | 559  |     return "hpmcounter26";  | 
387  | 1.47k  |   case 0x0c1b:  | 
388  | 1.47k  |     return "hpmcounter27";  | 
389  | 394  |   case 0x0c1c:  | 
390  | 394  |     return "hpmcounter28";  | 
391  | 172  |   case 0x0c1d:  | 
392  | 172  |     return "hpmcounter29";  | 
393  | 659  |   case 0x0c1e:  | 
394  | 659  |     return "hpmcounter30";  | 
395  | 243  |   case 0x0c1f:  | 
396  | 243  |     return "hpmcounter31";  | 
397  | 822  |   case 0x0c80:  | 
398  | 822  |     return "cycleh";  | 
399  | 114  |   case 0x0c81:  | 
400  | 114  |     return "timeh";  | 
401  | 1.46k  |   case 0x0c82:  | 
402  | 1.46k  |     return "instreth";  | 
403  | 521  |   case 0x0c83:  | 
404  | 521  |     return "hpmcounter3h";  | 
405  | 274  |   case 0x0c84:  | 
406  | 274  |     return "hpmcounter4h";  | 
407  | 152  |   case 0x0c85:  | 
408  | 152  |     return "hpmcounter5h";  | 
409  | 679  |   case 0x0c86:  | 
410  | 679  |     return "hpmcounter6h";  | 
411  | 462  |   case 0x0c87:  | 
412  | 462  |     return "hpmcounter7h";  | 
413  | 601  |   case 0x0c88:  | 
414  | 601  |     return "hpmcounter8h";  | 
415  | 104  |   case 0x0c89:  | 
416  | 104  |     return "hpmcounter9h";  | 
417  | 616  |   case 0x0c8a:  | 
418  | 616  |     return "hpmcounter10h";  | 
419  | 459  |   case 0x0c8b:  | 
420  | 459  |     return "hpmcounter11h";  | 
421  | 635  |   case 0x0c8c:  | 
422  | 635  |     return "hpmcounter12h";  | 
423  | 960  |   case 0x0c8d:  | 
424  | 960  |     return "hpmcounter13h";  | 
425  | 204  |   case 0x0c8e:  | 
426  | 204  |     return "hpmcounter14h";  | 
427  | 733  |   case 0x0c8f:  | 
428  | 733  |     return "hpmcounter15h";  | 
429  | 996  |   case 0x0c90:  | 
430  | 996  |     return "hpmcounter16h";  | 
431  | 187  |   case 0x0c91:  | 
432  | 187  |     return "hpmcounter17h";  | 
433  | 908  |   case 0x0c92:  | 
434  | 908  |     return "hpmcounter18h";  | 
435  | 363  |   case 0x0c93:  | 
436  | 363  |     return "hpmcounter19h";  | 
437  | 293  |   case 0x0c94:  | 
438  | 293  |     return "hpmcounter20h";  | 
439  | 400  |   case 0x0c95:  | 
440  | 400  |     return "hpmcounter21h";  | 
441  | 238  |   case 0x0c96:  | 
442  | 238  |     return "hpmcounter22h";  | 
443  | 353  |   case 0x0c97:  | 
444  | 353  |     return "hpmcounter23h";  | 
445  | 368  |   case 0x0c98:  | 
446  | 368  |     return "hpmcounter24h";  | 
447  | 976  |   case 0x0c99:  | 
448  | 976  |     return "hpmcounter25h";  | 
449  | 681  |   case 0x0c9a:  | 
450  | 681  |     return "hpmcounter26h";  | 
451  | 1.19k  |   case 0x0c9b:  | 
452  | 1.19k  |     return "hpmcounter27h";  | 
453  | 1.67k  |   case 0x0c9c:  | 
454  | 1.67k  |     return "hpmcounter28h";  | 
455  | 1.53k  |   case 0x0c9d:  | 
456  | 1.53k  |     return "hpmcounter29h";  | 
457  | 460  |   case 0x0c9e:  | 
458  | 460  |     return "hpmcounter30h";  | 
459  | 1.30k  |   case 0x0c9f:  | 
460  | 1.30k  |     return "hpmcounter31h";  | 
461  |  |  | 
462  | 545  |   case 0x0100:  | 
463  | 545  |     return "sstatus";  | 
464  | 693  |   case 0x0102:  | 
465  | 693  |     return "sedeleg";  | 
466  | 697  |   case 0x0103:  | 
467  | 697  |     return "sideleg";  | 
468  | 579  |   case 0x0104:  | 
469  | 579  |     return "sie";  | 
470  | 1.13k  |   case 0x0105:  | 
471  | 1.13k  |     return "stvec";  | 
472  | 774  |   case 0x0106:  | 
473  | 774  |     return "scounteren";  | 
474  |  |  | 
475  | 146  |   case 0x0140:  | 
476  | 146  |     return "sscratch";  | 
477  | 164  |   case 0x0141:  | 
478  | 164  |     return "sepc";  | 
479  | 269  |   case 0x0142:  | 
480  | 269  |     return "scause";  | 
481  | 344  |   case 0x0143:  | 
482  | 344  |     return "stval";  | 
483  | 581  |   case 0x0144:  | 
484  | 581  |     return "sip";  | 
485  |  |  | 
486  | 267  |   case 0x0180:  | 
487  | 267  |     return "satp";  | 
488  |  |  | 
489  | 140  |   case 0x0f11:  | 
490  | 140  |     return "mvendorid";  | 
491  | 285  |   case 0x0f12:  | 
492  | 285  |     return "marchid";  | 
493  | 422  |   case 0x0f13:  | 
494  | 422  |     return "mimpid";  | 
495  | 141  |   case 0x0f14:  | 
496  | 141  |     return "mhartid";  | 
497  |  |  | 
498  | 143  |   case 0x0300:  | 
499  | 143  |     return "mstatus";  | 
500  | 202  |   case 0x0301:  | 
501  | 202  |     return "misa";  | 
502  | 1.43k  |   case 0x0302:  | 
503  | 1.43k  |     return "medeleg";  | 
504  | 232  |   case 0x0303:  | 
505  | 232  |     return "mideleg";  | 
506  | 228  |   case 0x0304:  | 
507  | 228  |     return "mie";  | 
508  | 909  |   case 0x0305:  | 
509  | 909  |     return "mtvec";  | 
510  | 177  |   case 0x0306:  | 
511  | 177  |     return "mcounteren";  | 
512  |  |  | 
513  | 284  |   case 0x0340:  | 
514  | 284  |     return "mscratch";  | 
515  | 1.15k  |   case 0x0341:  | 
516  | 1.15k  |     return "mepc";  | 
517  | 369  |   case 0x0342:  | 
518  | 369  |     return "mcause";  | 
519  | 241  |   case 0x0343:  | 
520  | 241  |     return "mtval";  | 
521  | 1.43k  |   case 0x0344:  | 
522  | 1.43k  |     return "mip";  | 
523  |  |  | 
524  | 120  |   case 0x03a0:  | 
525  | 120  |     return "pmpcfg0";  | 
526  | 303  |   case 0x03a1:  | 
527  | 303  |     return "pmpcfg1";  | 
528  | 827  |   case 0x03a2:  | 
529  | 827  |     return "pmpcfg2";  | 
530  | 199  |   case 0x03a3:  | 
531  | 199  |     return "pmpcfg3";  | 
532  | 525  |   case 0x03b0:  | 
533  | 525  |     return "pmpaddr0";  | 
534  | 476  |   case 0x03b1:  | 
535  | 476  |     return "pmpaddr1";  | 
536  | 1.06k  |   case 0x03b2:  | 
537  | 1.06k  |     return "pmpaddr2";  | 
538  | 706  |   case 0x03b3:  | 
539  | 706  |     return "pmpaddr3";  | 
540  | 153  |   case 0x03b4:  | 
541  | 153  |     return "pmpaddr4";  | 
542  | 475  |   case 0x03b5:  | 
543  | 475  |     return "pmpaddr5";  | 
544  | 46  |   case 0x03b6:  | 
545  | 46  |     return "pmpaddr6";  | 
546  | 543  |   case 0x03b7:  | 
547  | 543  |     return "pmpaddr7";  | 
548  | 157  |   case 0x03b8:  | 
549  | 157  |     return "pmpaddr8";  | 
550  | 862  |   case 0x03b9:  | 
551  | 862  |     return "pmpaddr9";  | 
552  | 139  |   case 0x03ba:  | 
553  | 139  |     return "pmpaddr10";  | 
554  | 1.03k  |   case 0x03bb:  | 
555  | 1.03k  |     return "pmpaddr11";  | 
556  | 525  |   case 0x03bc:  | 
557  | 525  |     return "pmpaddr12";  | 
558  | 222  |   case 0x03bd:  | 
559  | 222  |     return "pmpaddr13";  | 
560  | 568  |   case 0x03be:  | 
561  | 568  |     return "pmpaddr14";  | 
562  | 1.19k  |   case 0x03bf:  | 
563  | 1.19k  |     return "pmpaddr15";  | 
564  |  |  | 
565  | 522  |   case 0x0b00:  | 
566  | 522  |     return "mcycle";  | 
567  | 634  |   case 0x0b02:  | 
568  | 634  |     return "minstret";  | 
569  | 698  |   case 0x0b03:  | 
570  | 698  |     return "mhpmcounter3";  | 
571  | 980  |   case 0x0b04:  | 
572  | 980  |     return "mhpmcounter4";  | 
573  | 612  |   case 0x0b05:  | 
574  | 612  |     return "mhpmcounter5";  | 
575  | 516  |   case 0x0b06:  | 
576  | 516  |     return "mhpmcounter6";  | 
577  | 564  |   case 0x0b07:  | 
578  | 564  |     return "mhpmcounter7";  | 
579  | 150  |   case 0x0b08:  | 
580  | 150  |     return "mhpmcounter8";  | 
581  | 139  |   case 0x0b09:  | 
582  | 139  |     return "mhpmcounter9";  | 
583  | 100  |   case 0x0b0a:  | 
584  | 100  |     return "mhpmcounter10";  | 
585  | 599  |   case 0x0b0b:  | 
586  | 599  |     return "mhpmcounter11";  | 
587  | 294  |   case 0x0b0c:  | 
588  | 294  |     return "mhpmcounter12";  | 
589  | 202  |   case 0x0b0d:  | 
590  | 202  |     return "mhpmcounter13";  | 
591  | 147  |   case 0x0b0e:  | 
592  | 147  |     return "mhpmcounter14";  | 
593  | 383  |   case 0x0b0f:  | 
594  | 383  |     return "mhpmcounter15";  | 
595  | 591  |   case 0x0b10:  | 
596  | 591  |     return "mhpmcounter16";  | 
597  | 465  |   case 0x0b11:  | 
598  | 465  |     return "mhpmcounter17";  | 
599  | 672  |   case 0x0b12:  | 
600  | 672  |     return "mhpmcounter18";  | 
601  | 475  |   case 0x0b13:  | 
602  | 475  |     return "mhpmcounter19";  | 
603  | 139  |   case 0x0b14:  | 
604  | 139  |     return "mhpmcounter20";  | 
605  | 144  |   case 0x0b15:  | 
606  | 144  |     return "mhpmcounter21";  | 
607  | 116  |   case 0x0b16:  | 
608  | 116  |     return "mhpmcounter22";  | 
609  | 144  |   case 0x0b17:  | 
610  | 144  |     return "mhpmcounter23";  | 
611  | 160  |   case 0x0b18:  | 
612  | 160  |     return "mhpmcounter24";  | 
613  | 215  |   case 0x0b19:  | 
614  | 215  |     return "mhpmcounter25";  | 
615  | 364  |   case 0x0b1a:  | 
616  | 364  |     return "mhpmcounter26";  | 
617  | 347  |   case 0x0b1b:  | 
618  | 347  |     return "mhpmcounter27";  | 
619  | 476  |   case 0x0b1c:  | 
620  | 476  |     return "mhpmcounter28";  | 
621  | 481  |   case 0x0b1d:  | 
622  | 481  |     return "mhpmcounter29";  | 
623  | 151  |   case 0x0b1e:  | 
624  | 151  |     return "mhpmcounter30";  | 
625  | 390  |   case 0x0b1f:  | 
626  | 390  |     return "mhpmcounter31";  | 
627  | 1.48k  |   case 0x0b80:  | 
628  | 1.48k  |     return "mcycleh";  | 
629  | 358  |   case 0x0b82:  | 
630  | 358  |     return "minstreth";  | 
631  | 99  |   case 0x0b83:  | 
632  | 99  |     return "mhpmcounter3h";  | 
633  | 376  |   case 0x0b84:  | 
634  | 376  |     return "mhpmcounter4h";  | 
635  | 127  |   case 0x0b85:  | 
636  | 127  |     return "mhpmcounter5h";  | 
637  | 198  |   case 0x0b86:  | 
638  | 198  |     return "mhpmcounter6h";  | 
639  | 309  |   case 0x0b87:  | 
640  | 309  |     return "mhpmcounter7h";  | 
641  | 160  |   case 0x0b88:  | 
642  | 160  |     return "mhpmcounter8h";  | 
643  | 617  |   case 0x0b89:  | 
644  | 617  |     return "mhpmcounter9h";  | 
645  | 455  |   case 0x0b8a:  | 
646  | 455  |     return "mhpmcounter10h";  | 
647  | 2.07k  |   case 0x0b8b:  | 
648  | 2.07k  |     return "mhpmcounter11h";  | 
649  | 88  |   case 0x0b8c:  | 
650  | 88  |     return "mhpmcounter12h";  | 
651  | 141  |   case 0x0b8d:  | 
652  | 141  |     return "mhpmcounter13h";  | 
653  | 1.01k  |   case 0x0b8e:  | 
654  | 1.01k  |     return "mhpmcounter14h";  | 
655  | 574  |   case 0x0b8f:  | 
656  | 574  |     return "mhpmcounter15h";  | 
657  | 659  |   case 0x0b90:  | 
658  | 659  |     return "mhpmcounter16h";  | 
659  | 136  |   case 0x0b91:  | 
660  | 136  |     return "mhpmcounter17h";  | 
661  | 306  |   case 0x0b92:  | 
662  | 306  |     return "mhpmcounter18h";  | 
663  | 450  |   case 0x0b93:  | 
664  | 450  |     return "mhpmcounter19h";  | 
665  | 127  |   case 0x0b94:  | 
666  | 127  |     return "mhpmcounter20h";  | 
667  | 133  |   case 0x0b95:  | 
668  | 133  |     return "mhpmcounter21h";  | 
669  | 190  |   case 0x0b96:  | 
670  | 190  |     return "mhpmcounter22h";  | 
671  | 277  |   case 0x0b97:  | 
672  | 277  |     return "mhpmcounter23h";  | 
673  | 566  |   case 0x0b98:  | 
674  | 566  |     return "mhpmcounter24h";  | 
675  | 649  |   case 0x0b99:  | 
676  | 649  |     return "mhpmcounter25h";  | 
677  | 196  |   case 0x0b9a:  | 
678  | 196  |     return "mhpmcounter26h";  | 
679  | 1.03k  |   case 0x0b9b:  | 
680  | 1.03k  |     return "mhpmcounter27h";  | 
681  | 1.43k  |   case 0x0b9c:  | 
682  | 1.43k  |     return "mhpmcounter28h";  | 
683  | 805  |   case 0x0b9d:  | 
684  | 805  |     return "mhpmcounter29h";  | 
685  | 306  |   case 0x0b9e:  | 
686  | 306  |     return "mhpmcounter30h";  | 
687  | 638  |   case 0x0b9f:  | 
688  | 638  |     return "mhpmcounter31h";  | 
689  |  |  | 
690  | 110  |   case 0x0323:  | 
691  | 110  |     return "mhpmevent3";  | 
692  | 225  |   case 0x0324:  | 
693  | 225  |     return "mhpmevent4";  | 
694  | 446  |   case 0x0325:  | 
695  | 446  |     return "mhpmevent5";  | 
696  | 121  |   case 0x0326:  | 
697  | 121  |     return "mhpmevent6";  | 
698  | 234  |   case 0x0327:  | 
699  | 234  |     return "mhpmevent7";  | 
700  | 2.43k  |   case 0x0328:  | 
701  | 2.43k  |     return "mhpmevent8";  | 
702  | 380  |   case 0x0329:  | 
703  | 380  |     return "mhpmevent9";  | 
704  | 864  |   case 0x032a:  | 
705  | 864  |     return "mhpmevent10";  | 
706  | 721  |   case 0x032b:  | 
707  | 721  |     return "mhpmevent11";  | 
708  | 280  |   case 0x032c:  | 
709  | 280  |     return "mhpmevent12";  | 
710  | 600  |   case 0x032d:  | 
711  | 600  |     return "mhpmevent13";  | 
712  | 502  |   case 0x032e:  | 
713  | 502  |     return "mhpmevent14";  | 
714  | 166  |   case 0x032f:  | 
715  | 166  |     return "mhpmevent15";  | 
716  | 268  |   case 0x0330:  | 
717  | 268  |     return "mhpmevent16";  | 
718  | 914  |   case 0x0331:  | 
719  | 914  |     return "mhpmevent17";  | 
720  | 1.34k  |   case 0x0332:  | 
721  | 1.34k  |     return "mhpmevent18";  | 
722  | 84  |   case 0x0333:  | 
723  | 84  |     return "mhpmevent19";  | 
724  | 782  |   case 0x0334:  | 
725  | 782  |     return "mhpmevent20";  | 
726  | 425  |   case 0x0335:  | 
727  | 425  |     return "mhpmevent21";  | 
728  | 123  |   case 0x0336:  | 
729  | 123  |     return "mhpmevent22";  | 
730  | 378  |   case 0x0337:  | 
731  | 378  |     return "mhpmevent23";  | 
732  | 86  |   case 0x0338:  | 
733  | 86  |     return "mhpmevent24";  | 
734  | 846  |   case 0x0339:  | 
735  | 846  |     return "mhpmevent25";  | 
736  | 160  |   case 0x033a:  | 
737  | 160  |     return "mhpmevent26";  | 
738  | 704  |   case 0x033b:  | 
739  | 704  |     return "mhpmevent27";  | 
740  | 316  |   case 0x033c:  | 
741  | 316  |     return "mhpmevent28";  | 
742  | 1.15k  |   case 0x033d:  | 
743  | 1.15k  |     return "mhpmevent29";  | 
744  | 631  |   case 0x033e:  | 
745  | 631  |     return "mhpmevent30";  | 
746  | 522  |   case 0x033f:  | 
747  | 522  |     return "mhpmevent31";  | 
748  |  |  | 
749  | 86  |   case 0x07a0:  | 
750  | 86  |     return "tselect";  | 
751  | 105  |   case 0x07a1:  | 
752  | 105  |     return "tdata1";  | 
753  | 1.00k  |   case 0x07a2:  | 
754  | 1.00k  |     return "tdata2";  | 
755  | 382  |   case 0x07a3:  | 
756  | 382  |     return "tdata3";  | 
757  |  |  | 
758  | 170  |   case 0x07b0:  | 
759  | 170  |     return "dcsr";  | 
760  | 407  |   case 0x07b1:  | 
761  | 407  |     return "dpc";  | 
762  | 110  |   case 0x07b2:  | 
763  | 110  |     return "dscratch";  | 
764  | 152k  |   }  | 
765  | 29.2k  |   return NULL;  | 
766  | 152k  | }  | 
767  |  |  | 
768  |  | static void printCSRSystemRegister(MCInst *MI, unsigned OpNo,  | 
769  |  |            //const MCSubtargetInfo &STI,  | 
770  |  |            SStream *O)  | 
771  | 152k  | { | 
772  | 152k  |   unsigned Imm = MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
773  | 152k  |   const char *Name = getCSRSystemRegisterName(Imm);  | 
774  |  |  | 
775  | 152k  |   if (Name) { | 
776  | 122k  |     SStream_concat0(O, Name);  | 
777  | 122k  |   } else { | 
778  | 29.2k  |     SStream_concat(O, "%u", Imm);  | 
779  | 29.2k  |   }  | 
780  | 152k  | }  | 
781  |  |  | 
782  |  | static void printFenceArg(MCInst *MI, unsigned OpNo, SStream *O)  | 
783  | 5.54k  | { | 
784  | 5.54k  |   unsigned FenceArg = MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
785  |  |   //CS_ASSERT (((FenceArg >> 4) == 0) && "Invalid immediate in printFenceArg");  | 
786  |  |  | 
787  | 5.54k  |   if ((FenceArg & RISCVFenceField_I) != 0)  | 
788  | 2.54k  |     SStream_concat0(O, "i");  | 
789  | 5.54k  |   if ((FenceArg & RISCVFenceField_O) != 0)  | 
790  | 2.16k  |     SStream_concat0(O, "o");  | 
791  | 5.54k  |   if ((FenceArg & RISCVFenceField_R) != 0)  | 
792  | 2.25k  |     SStream_concat0(O, "r");  | 
793  | 5.54k  |   if ((FenceArg & RISCVFenceField_W) != 0)  | 
794  | 2.53k  |     SStream_concat0(O, "w");  | 
795  | 5.54k  |   if (FenceArg == 0)  | 
796  | 1.54k  |     SStream_concat0(O, "unknown");  | 
797  | 5.54k  | }  | 
798  |  |  | 
799  |  | static void printFRMArg(MCInst *MI, unsigned OpNo, SStream *O)  | 
800  | 24.7k  | { | 
801  | 24.7k  |   enum RoundingMode FRMArg = (enum RoundingMode)MCOperand_getImm(  | 
802  | 24.7k  |     MCInst_getOperand(MI, OpNo));  | 
803  |  | #if 0  | 
804  |  |   auto FRMArg =  | 
805  |  |       static_cast<RISCVFPRndMode::RoundingMode>(MI->getOperand(OpNo).getImm());  | 
806  |  |   O << RISCVFPRndMode::roundingModeToString(FRMArg);  | 
807  |  | #endif  | 
808  | 24.7k  |   SStream_concat0(O, roundingModeToString(FRMArg));  | 
809  | 24.7k  | }  | 
810  |  |  | 
811  |  | #endif // CAPSTONE_HAS_RISCV  |