/src/capstonenext/arch/RISCV/RISCVMapping.c
Line | Count | Source (jump to first uncovered line) |
1 | | |
2 | | #ifdef CAPSTONE_HAS_RISCV |
3 | | |
4 | | #include <stdio.h> // debug |
5 | | #include <string.h> |
6 | | |
7 | | #include "../../Mapping.h" |
8 | | #include "../../utils.h" |
9 | | #include "../../cs_simple_types.h" |
10 | | |
11 | | #include "RISCVMapping.h" |
12 | | #include "RISCVInstPrinter.h" |
13 | | |
14 | | #define GET_INSTRINFO_ENUM |
15 | | #include "RISCVGenInstrInfo.inc" |
16 | | |
17 | | #ifndef CAPSTONE_DIET |
18 | | static const name_map reg_name_maps[] = { |
19 | | { RISCV_REG_INVALID, NULL }, |
20 | | |
21 | | { RISCV_REG_X0, "zero" }, |
22 | | { RISCV_REG_X1, "ra" }, |
23 | | { RISCV_REG_X2, "sp" }, |
24 | | { RISCV_REG_X3, "gp" }, |
25 | | { RISCV_REG_X4, "tp" }, |
26 | | { RISCV_REG_X5, "t0" }, |
27 | | { RISCV_REG_X6, "t1" }, |
28 | | { RISCV_REG_X7, "t2" }, |
29 | | { RISCV_REG_X8, "s0" }, |
30 | | { RISCV_REG_X9, "s1" }, |
31 | | { RISCV_REG_X10, "a0" }, |
32 | | { RISCV_REG_X11, "a1" }, |
33 | | { RISCV_REG_X12, "a2" }, |
34 | | { RISCV_REG_X13, "a3" }, |
35 | | { RISCV_REG_X14, "a4" }, |
36 | | { RISCV_REG_X15, "a5" }, |
37 | | { RISCV_REG_X16, "a6" }, |
38 | | { RISCV_REG_X17, "a7" }, |
39 | | { RISCV_REG_X18, "s2" }, |
40 | | { RISCV_REG_X19, "s3" }, |
41 | | { RISCV_REG_X20, "s4" }, |
42 | | { RISCV_REG_X21, "s5" }, |
43 | | { RISCV_REG_X22, "s6" }, |
44 | | { RISCV_REG_X23, "s7" }, |
45 | | { RISCV_REG_X24, "s8" }, |
46 | | { RISCV_REG_X25, "s9" }, |
47 | | { RISCV_REG_X26, "s10" }, |
48 | | { RISCV_REG_X27, "s11" }, |
49 | | { RISCV_REG_X28, "t3" }, |
50 | | { RISCV_REG_X29, "t4" }, |
51 | | { RISCV_REG_X30, "t5" }, |
52 | | { RISCV_REG_X31, "t6" }, |
53 | | |
54 | | { RISCV_REG_F0_32, "ft0" }, |
55 | | { RISCV_REG_F0_64, "ft0" }, |
56 | | { RISCV_REG_F1_32, "ft1" }, |
57 | | { RISCV_REG_F1_64, "ft1" }, |
58 | | { RISCV_REG_F2_32, "ft2" }, |
59 | | { RISCV_REG_F2_64, "ft2" }, |
60 | | { RISCV_REG_F3_32, "ft3" }, |
61 | | { RISCV_REG_F3_64, "ft3" }, |
62 | | { RISCV_REG_F4_32, "ft4" }, |
63 | | { RISCV_REG_F4_64, "ft4" }, |
64 | | { RISCV_REG_F5_32, "ft5" }, |
65 | | { RISCV_REG_F5_64, "ft5" }, |
66 | | { RISCV_REG_F6_32, "ft6" }, |
67 | | { RISCV_REG_F6_64, "ft6" }, |
68 | | { RISCV_REG_F7_32, "ft7" }, |
69 | | { RISCV_REG_F7_64, "ft7" }, |
70 | | { RISCV_REG_F8_32, "fs0" }, |
71 | | { RISCV_REG_F8_64, "fs0" }, |
72 | | { RISCV_REG_F9_32, "fs1" }, |
73 | | { RISCV_REG_F9_64, "fs1" }, |
74 | | { RISCV_REG_F10_32, "fa0" }, |
75 | | { RISCV_REG_F10_64, "fa0" }, |
76 | | { RISCV_REG_F11_32, "fa1" }, |
77 | | { RISCV_REG_F11_64, "fa1" }, |
78 | | { RISCV_REG_F12_32, "fa2" }, |
79 | | { RISCV_REG_F12_64, "fa2" }, |
80 | | { RISCV_REG_F13_32, "fa3" }, |
81 | | { RISCV_REG_F13_64, "fa3" }, |
82 | | { RISCV_REG_F14_32, "fa4" }, |
83 | | { RISCV_REG_F14_64, "fa4" }, |
84 | | { RISCV_REG_F15_32, "fa5" }, |
85 | | { RISCV_REG_F15_64, "fa5" }, |
86 | | { RISCV_REG_F16_32, "fa6" }, |
87 | | { RISCV_REG_F16_64, "fa6" }, |
88 | | { RISCV_REG_F17_32, "fa7" }, |
89 | | { RISCV_REG_F17_64, "fa7" }, |
90 | | { RISCV_REG_F18_32, "fs2" }, |
91 | | { RISCV_REG_F18_64, "fs2" }, |
92 | | { RISCV_REG_F19_32, "fs3" }, |
93 | | { RISCV_REG_F19_64, "fs3" }, |
94 | | { RISCV_REG_F20_32, "fs4" }, |
95 | | { RISCV_REG_F20_64, "fs4" }, |
96 | | { RISCV_REG_F21_32, "fs5" }, |
97 | | { RISCV_REG_F21_64, "fs5" }, |
98 | | { RISCV_REG_F22_32, "fs6" }, |
99 | | { RISCV_REG_F22_64, "fs6" }, |
100 | | { RISCV_REG_F23_32, "fs7" }, |
101 | | { RISCV_REG_F23_64, "fs7" }, |
102 | | { RISCV_REG_F24_32, "fs8" }, |
103 | | { RISCV_REG_F24_64, "fs8" }, |
104 | | { RISCV_REG_F25_32, "fs9" }, |
105 | | { RISCV_REG_F25_64, "fs9" }, |
106 | | { RISCV_REG_F26_32, "fs10" }, |
107 | | { RISCV_REG_F26_64, "fs10" }, |
108 | | { RISCV_REG_F27_32, "fs11" }, |
109 | | { RISCV_REG_F27_64, "fs11" }, |
110 | | { RISCV_REG_F28_32, "ft8" }, |
111 | | { RISCV_REG_F28_64, "ft8" }, |
112 | | { RISCV_REG_F29_32, "ft9" }, |
113 | | { RISCV_REG_F29_64, "ft9" }, |
114 | | { RISCV_REG_F30_32, "ft10" }, |
115 | | { RISCV_REG_F30_64, "ft10" }, |
116 | | { RISCV_REG_F31_32, "ft11" }, |
117 | | { RISCV_REG_F31_64, "ft11" }, |
118 | | }; |
119 | | #endif |
120 | | |
121 | | const char *RISCV_reg_name(csh handle, unsigned int reg) |
122 | 0 | { |
123 | 0 | #ifndef CAPSTONE_DIET |
124 | 0 | if (reg >= RISCV_REG_ENDING) |
125 | 0 | return NULL; |
126 | 0 | return reg_name_maps[reg].name; |
127 | | #else |
128 | | return NULL; |
129 | | #endif |
130 | 0 | } |
131 | | |
132 | | static const insn_map insns[] = { |
133 | | // dummy item |
134 | | { |
135 | | 0, 0, |
136 | | #ifndef CAPSTONE_DIET |
137 | | {0}, {0}, {0}, 0, 0 |
138 | | #endif |
139 | | }, |
140 | | |
141 | | #include "RISCVMappingInsn.inc" |
142 | | }; |
143 | | |
144 | | #ifndef CAPSTONE_DIET |
145 | | |
146 | | static const map_insn_ops insn_operands[] = { |
147 | | #include "RISCVMappingInsnOp.inc" |
148 | | }; |
149 | | |
150 | | #endif |
151 | | |
152 | 157k | void RISCV_add_cs_detail(MCInst *MI, unsigned OpNum) { |
153 | 157k | if (!detail_is_set(MI)) |
154 | 0 | return; |
155 | | |
156 | 157k | cs_op_type op_type = map_get_op_type(MI, OpNum); |
157 | | |
158 | 157k | if (op_type == CS_OP_IMM) { |
159 | 24.8k | RISCV_get_detail_op(MI, 0)->type = RISCV_OP_IMM; |
160 | 24.8k | RISCV_get_detail_op(MI, 0)->imm = MCInst_getOpVal(MI, OpNum); |
161 | 24.8k | RISCV_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum); |
162 | 24.8k | RISCV_inc_op_count(MI); |
163 | 24.8k | } |
164 | 132k | else if (op_type == CS_OP_REG) { |
165 | 132k | RISCV_get_detail_op(MI, 0)->type = RISCV_OP_REG; |
166 | 132k | RISCV_get_detail_op(MI, 0)->reg = MCInst_getOpVal(MI, OpNum); |
167 | 132k | RISCV_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum); |
168 | 132k | RISCV_inc_op_count(MI); |
169 | 132k | } |
170 | 0 | else { |
171 | 0 | CS_ASSERT(0 && "Op type not handled."); |
172 | 0 | } |
173 | 157k | } |
174 | | |
175 | | // given internal insn id, return public instruction info |
176 | | void RISCV_get_insn_id(cs_struct * h, cs_insn * insn, unsigned int id) |
177 | 95.2k | { |
178 | 95.2k | unsigned int i; |
179 | | |
180 | 95.2k | i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); |
181 | 95.2k | if (i != 0) { |
182 | 95.2k | insn->id = insns[i].mapid; |
183 | | |
184 | 95.2k | if (h->detail_opt) { |
185 | 95.2k | #ifndef CAPSTONE_DIET |
186 | 95.2k | memcpy(insn->detail->regs_read, |
187 | 95.2k | insns[i].regs_use, sizeof(insns[i].regs_use)); |
188 | 95.2k | insn->detail->regs_read_count = (uint8_t)count_positive(insns[i].regs_use); |
189 | | |
190 | 95.2k | memcpy(insn->detail->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod)); |
191 | 95.2k | insn->detail->regs_write_count = (uint8_t)count_positive(insns[i].regs_mod); |
192 | | |
193 | 95.2k | memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups)); |
194 | 95.2k | insn->detail->groups_count = (uint8_t)count_positive8(insns[i].groups); |
195 | | |
196 | 95.2k | if (insns[i].branch || insns[i].indirect_branch) { |
197 | | // this insn also belongs to JUMP group. add JUMP group |
198 | 2.64k | insn->detail->groups[insn->detail->groups_count] = RISCV_GRP_JUMP; |
199 | 2.64k | insn->detail->groups_count++; |
200 | 2.64k | } |
201 | 95.2k | #endif |
202 | 95.2k | } |
203 | 95.2k | } |
204 | 95.2k | } |
205 | | |
206 | | static const name_map insn_name_maps[] = { |
207 | | {RISCV_INS_INVALID, NULL}, |
208 | | |
209 | | #include "RISCVGenInsnNameMaps.inc" |
210 | | }; |
211 | | |
212 | | const char *RISCV_insn_name(csh handle, unsigned int id) |
213 | 95.2k | { |
214 | 95.2k | #ifndef CAPSTONE_DIET |
215 | 95.2k | if (id >= RISCV_INS_ENDING) |
216 | 0 | return NULL; |
217 | | |
218 | 95.2k | return insn_name_maps[id].name; |
219 | | #else |
220 | | return NULL; |
221 | | #endif |
222 | 95.2k | } |
223 | | |
224 | | #ifndef CAPSTONE_DIET |
225 | | static const name_map group_name_maps[] = { |
226 | | // generic groups |
227 | | { RISCV_GRP_INVALID, NULL }, |
228 | | { RISCV_GRP_JUMP, "jump" }, |
229 | | { RISCV_GRP_CALL, "call" }, |
230 | | { RISCV_GRP_RET, "ret" }, |
231 | | { RISCV_GRP_INT, "int" }, |
232 | | { RISCV_GRP_IRET, "iret" }, |
233 | | { RISCV_GRP_PRIVILEGE, "privileged" }, |
234 | | { RISCV_GRP_BRANCH_RELATIVE, "branch_relative" }, |
235 | | |
236 | | // architecture specific |
237 | | { RISCV_GRP_ISRV32, "isrv32" }, |
238 | | { RISCV_GRP_ISRV64, "isrv64" }, |
239 | | { RISCV_GRP_HASSTDEXTA, "hasStdExtA" }, |
240 | | { RISCV_GRP_HASSTDEXTC, "hasStdExtC" }, |
241 | | { RISCV_GRP_HASSTDEXTD, "hasStdExtD" }, |
242 | | { RISCV_GRP_HASSTDEXTF, "hasStdExtF" }, |
243 | | { RISCV_GRP_HASSTDEXTM, "hasStdExtM" }, |
244 | | |
245 | | /* |
246 | | { RISCV_GRP_ISRVA, "isrva" }, |
247 | | { RISCV_GRP_ISRVC, "isrvc" }, |
248 | | { RISCV_GRP_ISRVD, "isrvd" }, |
249 | | { RISCV_GRP_ISRVCD, "isrvcd" }, |
250 | | { RISCV_GRP_ISRVF, "isrvf" }, |
251 | | { RISCV_GRP_ISRV32C, "isrv32c" }, |
252 | | { RISCV_GRP_ISRV32CF, "isrv32cf" }, |
253 | | { RISCV_GRP_ISRVM, "isrvm" }, |
254 | | { RISCV_GRP_ISRV64A, "isrv64a" }, |
255 | | { RISCV_GRP_ISRV64C, "isrv64c" }, |
256 | | { RISCV_GRP_ISRV64D, "isrv64d" }, |
257 | | { RISCV_GRP_ISRV64F, "isrv64f" }, |
258 | | { RISCV_GRP_ISRV64M, "isrv64m" } |
259 | | */ |
260 | | { RISCV_GRP_ENDING, NULL } |
261 | | }; |
262 | | #endif |
263 | | |
264 | | const char *RISCV_group_name(csh handle, unsigned int id) |
265 | 42.2k | { |
266 | 42.2k | #ifndef CAPSTONE_DIET |
267 | | // verify group id |
268 | 42.2k | if (id >= RISCV_GRP_ENDING || |
269 | 42.2k | (id > RISCV_GRP_BRANCH_RELATIVE && id < RISCV_GRP_ISRV32)) |
270 | 0 | return NULL; |
271 | 42.2k | return id2name(group_name_maps, ARR_SIZE(group_name_maps), id); |
272 | | #else |
273 | | return NULL; |
274 | | #endif |
275 | 42.2k | } |
276 | | |
277 | | // map instruction name to public instruction ID |
278 | | riscv_reg RISCV_map_insn(const char *name) |
279 | 0 | { |
280 | | // handle special alias first |
281 | 0 | unsigned int i; |
282 | | |
283 | | // NOTE: skip first NULL name in insn_name_maps |
284 | 0 | i = name2id(&insn_name_maps[1], ARR_SIZE(insn_name_maps) - 1, name); |
285 | |
|
286 | 0 | return (i != -1) ? i : RISCV_REG_INVALID; |
287 | 0 | } |
288 | | |
289 | | // map internal raw register to 'public' register |
290 | | riscv_reg RISCV_map_register(unsigned int r) |
291 | 0 | { |
292 | 0 | static const unsigned int map[] = { 0, |
293 | 0 | RISCV_REG_X0, |
294 | 0 | RISCV_REG_X1, |
295 | 0 | RISCV_REG_X2, |
296 | 0 | RISCV_REG_X3, |
297 | 0 | RISCV_REG_X4, |
298 | 0 | RISCV_REG_X5, |
299 | 0 | RISCV_REG_X6, |
300 | 0 | RISCV_REG_X7, |
301 | 0 | RISCV_REG_X8, |
302 | 0 | RISCV_REG_X9, |
303 | 0 | RISCV_REG_X10, |
304 | 0 | RISCV_REG_X11, |
305 | 0 | RISCV_REG_X12, |
306 | 0 | RISCV_REG_X13, |
307 | 0 | RISCV_REG_X14, |
308 | 0 | RISCV_REG_X15, |
309 | 0 | RISCV_REG_X16, |
310 | 0 | RISCV_REG_X17, |
311 | 0 | RISCV_REG_X18, |
312 | 0 | RISCV_REG_X19, |
313 | 0 | RISCV_REG_X20, |
314 | 0 | RISCV_REG_X21, |
315 | 0 | RISCV_REG_X22, |
316 | 0 | RISCV_REG_X23, |
317 | 0 | RISCV_REG_X24, |
318 | 0 | RISCV_REG_X25, |
319 | 0 | RISCV_REG_X26, |
320 | 0 | RISCV_REG_X27, |
321 | 0 | RISCV_REG_X28, |
322 | 0 | RISCV_REG_X29, |
323 | 0 | RISCV_REG_X30, |
324 | 0 | RISCV_REG_X31, |
325 | |
|
326 | 0 | RISCV_REG_F0_32, |
327 | 0 | RISCV_REG_F0_64, |
328 | 0 | RISCV_REG_F1_32, |
329 | 0 | RISCV_REG_F1_64, |
330 | 0 | RISCV_REG_F2_32, |
331 | 0 | RISCV_REG_F2_64, |
332 | 0 | RISCV_REG_F3_32, |
333 | 0 | RISCV_REG_F3_64, |
334 | 0 | RISCV_REG_F4_32, |
335 | 0 | RISCV_REG_F4_64, |
336 | 0 | RISCV_REG_F5_32, |
337 | 0 | RISCV_REG_F5_64, |
338 | 0 | RISCV_REG_F6_32, |
339 | 0 | RISCV_REG_F6_64, |
340 | 0 | RISCV_REG_F7_32, |
341 | 0 | RISCV_REG_F7_64, |
342 | 0 | RISCV_REG_F8_32, |
343 | 0 | RISCV_REG_F8_64, |
344 | 0 | RISCV_REG_F9_32, |
345 | 0 | RISCV_REG_F9_64, |
346 | 0 | RISCV_REG_F10_32, |
347 | 0 | RISCV_REG_F10_64, |
348 | 0 | RISCV_REG_F11_32, |
349 | 0 | RISCV_REG_F11_64, |
350 | 0 | RISCV_REG_F12_32, |
351 | 0 | RISCV_REG_F12_64, |
352 | 0 | RISCV_REG_F13_32, |
353 | 0 | RISCV_REG_F13_64, |
354 | 0 | RISCV_REG_F14_32, |
355 | 0 | RISCV_REG_F14_64, |
356 | 0 | RISCV_REG_F15_32, |
357 | 0 | RISCV_REG_F15_64, |
358 | 0 | RISCV_REG_F16_32, |
359 | 0 | RISCV_REG_F16_64, |
360 | 0 | RISCV_REG_F17_32, |
361 | 0 | RISCV_REG_F17_64, |
362 | 0 | RISCV_REG_F18_32, |
363 | 0 | RISCV_REG_F18_64, |
364 | 0 | RISCV_REG_F19_32, |
365 | 0 | RISCV_REG_F19_64, |
366 | 0 | RISCV_REG_F20_32, |
367 | 0 | RISCV_REG_F20_64, |
368 | 0 | RISCV_REG_F21_32, |
369 | 0 | RISCV_REG_F21_64, |
370 | 0 | RISCV_REG_F22_32, |
371 | 0 | RISCV_REG_F22_64, |
372 | 0 | RISCV_REG_F23_32, |
373 | 0 | RISCV_REG_F23_64, |
374 | 0 | RISCV_REG_F24_32, |
375 | 0 | RISCV_REG_F24_64, |
376 | 0 | RISCV_REG_F25_32, |
377 | 0 | RISCV_REG_F25_64, |
378 | 0 | RISCV_REG_F26_32, |
379 | 0 | RISCV_REG_F26_64, |
380 | 0 | RISCV_REG_F27_32, |
381 | 0 | RISCV_REG_F27_64, |
382 | 0 | RISCV_REG_F28_32, |
383 | 0 | RISCV_REG_F28_64, |
384 | 0 | RISCV_REG_F29_32, |
385 | 0 | RISCV_REG_F29_64, |
386 | 0 | RISCV_REG_F30_32, |
387 | 0 | RISCV_REG_F30_64, |
388 | 0 | RISCV_REG_F31_32, |
389 | 0 | RISCV_REG_F31_64, |
390 | 0 | }; |
391 | |
|
392 | 0 | if (r < ARR_SIZE(map)) |
393 | 0 | return map[r]; |
394 | | |
395 | | // cannot find this register |
396 | 0 | return 0; |
397 | 0 | } |
398 | | |
399 | | #endif |