1 | | |
2 | | |
3 | | |
4 | | |
5 | | |
6 | | |
7 | | |
8 | | |
9 | | |
10 | | |
11 | | |
12 | | |
13 | | |
14 | | |
15 | | |
16 | | |
17 | | |
18 | | |
19 | | |
20 | | |
21 | | |
22 | | |
23 | | |
24 | | |
25 | | |
26 | | |
27 | | |
28 | | |
29 | | |
30 | | |
31 | | |
32 | | |
33 | | |
34 | | |
35 | | |
36 | | |
37 | | |
38 | | |
39 | | |
40 | | |
41 | | |
42 | | |
43 | | |
44 | | |
45 | | |
46 | | |
47 | | |
48 | | |
49 | | |
50 | | |
51 | | |
52 | | |
53 | | |
54 | | |
55 | | |
56 | | |
57 | | |
58 | | |
59 | | |
60 | | |
61 | | |
62 | | |
63 | | |
64 | | |
65 | | |
66 | | |
67 | | |
68 | | |
69 | | |
70 | | |
71 | | |
72 | | |
73 | | |
74 | | |
75 | | |
76 | | |
77 | | |
78 | | |
79 | | |
80 | | |
81 | | |
82 | | |
83 | | |
84 | | |
85 | | |
86 | | |
87 | | |
88 | | |
89 | | |
90 | | |
91 | | |
92 | | |
93 | | |
94 | | |
95 | | |
96 | | |
97 | | |
98 | | |
99 | | |
100 | | |
101 | | |
102 | | |
103 | | |
104 | | |
105 | | |
106 | | |
107 | | |
108 | | |
109 | | |
110 | | |
111 | | |
112 | | |
113 | | |
114 | | |
115 | | |
116 | | |
117 | | |
118 | | |
119 | | |
120 | | |
121 | | |
122 | | |
123 | | |
124 | | |
125 | | |
126 | | |
127 | | |
128 | | |
129 | | |
130 | | |
131 | | |
132 | | |
133 | | |
134 | | |
135 | | |
136 | | |
137 | | |
138 | | |
139 | | |
140 | | |
141 | | |
142 | | |
143 | | |
144 | | |
145 | | |
146 | | |
147 | | |
148 | | |
149 | | |
150 | | |
151 | | |
152 | | |
153 | | |
154 | | |
155 | | |
156 | | |
157 | | |
158 | | |
159 | | |
160 | | |
161 | | |
162 | | |
163 | | |
164 | | |
165 | | |
166 | | |
167 | | |
168 | | |
169 | | |
170 | | |
171 | | |
172 | | |
173 | | |
174 | | |
175 | | |
176 | | |
177 | | |
178 | | |
179 | | |
180 | | |
181 | | |
182 | | |
183 | | |
184 | | |
185 | | |
186 | | |
187 | | |
188 | | |
189 | | |
190 | | |
191 | | |
192 | | |
193 | | |
194 | | |
195 | | |
196 | | |
197 | | |
198 | | |
199 | | |
200 | | |
201 | | |
202 | | |
203 | | |
204 | | |
205 | | |
206 | | |
207 | | |
208 | | |
209 | | |
210 | | |
211 | | |
212 | | |
213 | | |
214 | | |
215 | | |
216 | | |
217 | | |
218 | | |
219 | | |
220 | | |
221 | | |
222 | | |
223 | | |
224 | | |
225 | | |
226 | | |
227 | | |
228 | | |
229 | | |
230 | | |
231 | | |
232 | | |
233 | | |
234 | | |
235 | | |
236 | | |
237 | | |
238 | | |
239 | | |
240 | | |
241 | | |
242 | | |
243 | | |
244 | | |
245 | | |
246 | | |
247 | | |
248 | | |
249 | | |
250 | | |
251 | | |
252 | | |
253 | | |
254 | | |
255 | | |
256 | | |
257 | | |
258 | | |
259 | | |
260 | | |
261 | | |
262 | | |
263 | | |
264 | | |
265 | | |
266 | | |
267 | | |
268 | | |
269 | | |
270 | | |
271 | | |
272 | | |
273 | | |
274 | | |
275 | | |
276 | | |
277 | | |
278 | | |
279 | | |
280 | | |
281 | | |
282 | | |
283 | | |
284 | | |
285 | | |
286 | | |
287 | | |
288 | | |
289 | | |
290 | | |
291 | | |
292 | | |
293 | | |
294 | | |
295 | | |
296 | | |
297 | | |
298 | | |
299 | | |
300 | | |
301 | | |
302 | | |
303 | | |
304 | | |
305 | | |
306 | | |
307 | | |
308 | | |
309 | | |
310 | | |
311 | | |
312 | | |
313 | | |
314 | | |
315 | | |
316 | | |
317 | | |
318 | | |
319 | | |
320 | | |
321 | | |
322 | | |
323 | | |
324 | | |
325 | | |
326 | | |
327 | | |
328 | | |
329 | | |
330 | | |
331 | | |
332 | | |
333 | | |
334 | | |
335 | | |
336 | | |
337 | | |
338 | | |
339 | | |
340 | | |
341 | | |
342 | | |
343 | | |
344 | | |
345 | | |
346 | | |
347 | | |
348 | | |
349 | | |
350 | | |
351 | | |
352 | | |
353 | | |
354 | | |
355 | | |
356 | | |
357 | | |
358 | | |
359 | | |
360 | | |
361 | | |
362 | | |
363 | | |
364 | | |
365 | | |
366 | | |
367 | | |
368 | | |
369 | | |
370 | | |
371 | | |
372 | | |
373 | | |
374 | | |
375 | | |
376 | | |
377 | | |
378 | | |
379 | | |
380 | | |
381 | | |
382 | | |
383 | | |
384 | | |
385 | | |
386 | | |
387 | | |
388 | | |
389 | | |
390 | | |
391 | | |
392 | | |
393 | | |
394 | | |
395 | | |
396 | | |
397 | | |
398 | | |
399 | | |
400 | | |
401 | | |
402 | | |
403 | | |
404 | | |
405 | | |
406 | | |
407 | | |
408 | | |
409 | | |
410 | | |
411 | | |
412 | | |
413 | | |
414 | | |
415 | | |
416 | | |
417 | | |
418 | | |
419 | | |
420 | | |
421 | | |
422 | | |
423 | | |
424 | | |
425 | | |
426 | | |
427 | | |
428 | | |
429 | | |
430 | | |
431 | | |
432 | | |
433 | | |
434 | | |
435 | | |
436 | | |
437 | | |
438 | | |
439 | | |
440 | | |
441 | | |
442 | | |
443 | | |
444 | | |
445 | | |
446 | | |
447 | | |
448 | | |
449 | | |
450 | | |
451 | | |
452 | | |
453 | | |
454 | | |
455 | | |
456 | | |
457 | | |
458 | | |
459 | | |
460 | | |
461 | | |
462 | | |
463 | | |
464 | | |
465 | | |
466 | | |
467 | | |
468 | | |
469 | | |
470 | | |
471 | | |
472 | | |
473 | | |
474 | | |
475 | | |
476 | | |
477 | | |
478 | | |
479 | | |
480 | | |
481 | | |
482 | | |
483 | | |
484 | | |
485 | | |
486 | | |
487 | | |
488 | | |
489 | | |
490 | | |
491 | | |
492 | | |
493 | | |
494 | | |
495 | | |
496 | | |
497 | | |
498 | | |
499 | | |
500 | | |
501 | | |
502 | | |
503 | | |
504 | | |
505 | | |
506 | | |
507 | | |
508 | | |
509 | | |
510 | | |
511 | | |
512 | | |
513 | | |
514 | | |
515 | | |
516 | | |
517 | | |
518 | | |
519 | | |
520 | | |
521 | | |
522 | | |
523 | | |
524 | | |
525 | | |
526 | | |
527 | | |
528 | | |
529 | | |
530 | | |
531 | | |
532 | | |
533 | | |
534 | | |
535 | | |
536 | | |
537 | | |
538 | | |
539 | | |
540 | | |
541 | | |
542 | | |
543 | | |
544 | | |
545 | | |
546 | | |
547 | | |
548 | | |
549 | | |
550 | | |
551 | | |
552 | | |
553 | | |
554 | | |
555 | | |
556 | | |
557 | | |
558 | | |
559 | | |
560 | | |
561 | | |
562 | | |
563 | | |
564 | | |
565 | | |
566 | | |
567 | | |
568 | | |
569 | | |
570 | | |
571 | | |
572 | | |
573 | | |
574 | | |
575 | | |
576 | | |
577 | | |
578 | | |
579 | | |
| | #undef DISASSEMBLE_32BIT | #undef DISASSEMBLE_128BIT | #if __riscv_xlen == 32 | #define DISASSEMBLE_32BIT | #elif __riscv_xlen == 128 | #define DISASSEMBLE_128BIT | #endif | | | #define RV_SHIFT(v,n) ((n)<0? ((v)>>-(n)) : ((v)<<(n))) | #define RV_GET_BITS(v,hi,lo,offs) \ | RV_SHIFT((v)&(((1<<((hi)-(lo)+1))-1)<<(offs)),((lo)-(offs))) | #define RV_GET_BIT(v,n,offs) RV_GET_BITS(v,n,n,offs) | #define RV_GET_SIGNBIT(v,n,offs) (((v)&(1<<(offs)))? ~((1<<(n))-1): 0) | | #define RV_I_IMM(v) ((INT32)(RV_GET_BITS(v,10,0,20)| \ | RV_GET_SIGNBIT(v,11,31))) | #define RV_S_IMM(v) ((INT32)(RV_GET_BITS(v,10,5,25)|RV_GET_BITS(v,4,0,7)| \ | RV_GET_SIGNBIT(v,11,31))) | #define RV_B_IMM(v) ((INT32)(RV_GET_BITS(v,10,5,25)|RV_GET_BITS(v,4,1,8)| \ | RV_GET_BIT(v,7,11)|RV_GET_SIGNBIT(v,12,31))) | #define RV_U_IMM(v) RV_GET_BITS(v,31-12,12-12,12) | #define RV_J_IMM(v) ((INT32)(RV_GET_BITS(v,10,1,21)|RV_GET_BIT(v,11,20)| \ | RV_GET_BITS(v,19,12,12)|RV_GET_SIGNBIT(v,20,31))) | #define RV_CSR_IMM(v) RV_GET_BITS(v,4,0,15) | #define RV_FUNCT3(v) RV_GET_BITS(v,2,0,12) | #define RV_FUNCT7(v) RV_GET_BITS(v,6,0,25) | #define RV_FUNCT12(v) RV_GET_BITS(v,11,0,20) | | #define RV_REG(v,offs) RV_GET_BITS(v,4,0,offs) | #define RV_REGD(v) RV_REG(v,7) | #define RV_REGS1(v) RV_REG(v,15) | #define RV_REGS2(v) RV_REG(v,20) | #define RV_CSR(v) RV_GET_BITS(v,11,0,20) | | #define RV_CI_IMM(v) ((INT32)(RV_GET_BITS(v,4,0,2)|RV_GET_SIGNBIT(v,5,12))) | #define RV_CIW_IMM(v) (RV_GET_BITS(v,5,4,11)|RV_GET_BITS(v,9,6,7)| \ | RV_GET_BIT(v,2,6)|RV_GET_BIT(v,3,5)) | #define RV_CB_IMM(v) ((INT32)(RV_GET_BITS(v,4,3,10)|RV_GET_BITS(v,7,6,5)| \ | RV_GET_BITS(v,2,1,3)|RV_GET_BIT(v,5,2)| \ | RV_GET_SIGNBIT(v,8,12))) | #define RV_CJ_IMM(v) ((INT32)(RV_GET_BIT(v,4,11)|RV_GET_BITS(v,9,8,9)| \ | RV_GET_BIT(v,10,8)|RV_GET_BIT(v,6,7)| \ | RV_GET_BIT(v,7,6)|RV_GET_BITS(v,3,1,3)| \ | RV_GET_BIT(v,5,2)|RV_GET_SIGNBIT(v,11,12))) | #define RV_CFUNCT3(v) RV_GET_BITS(v,2,0,13) | | #define RV_REGC(v,offs) (RV_GET_BITS(v,2,0,offs)+8) | #define RV_REGCS2(v) RV_REG(v,2) | #define RV_REGCDS1(v) RV_REG(v,7) | #define RV_REGCD_(v) RV_REGC(v,2) | #define RV_REGCS1_(v) RV_REGC(v,7) | #define RV_REGCS2_(v) RV_REGC(v,2) | | | static const char *riscv_regname(unsigned n) | { | static const char * const regnames[] = { | "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", | "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", | "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", | "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", | }; | return regnames[n&0x3f]; | } | | static const char *riscv_fregname(unsigned n) | { | static const char * const regnames[] = { | "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", | "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", | "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", | "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11", | }; | return regnames[n&0x3f]; | } | | void riscv_disassemble_code(void *addr, size_t bytes) | { | static const char * const rvcq1_op[] = { "sub ", "xor ", "or ", "and ", | "subw", "addw" }; | static const char * const load_op[] = {"lb ", "lh ", "lw ", "ld ", | "lbu", "lhu", "lwu" }; | static const char * const op_imm_op[] = { "addi", "*sl", "slti", "sltiu", | "xori", "*sr", "ori", "andi"}; | static const char * const store_op[] = {"sb", "sh", "sw", "sd"}; | static const char * const op_op[] = {"*add", "sll", "slt", "sltu", | "xor", "*srl", "or", "and"}; | static const char * const mul_op[] = {"mul", "mulh", "mulhsu", "mulhu", | "div", "divu", "rem", "remu"}; | static const char * const branch_op[] = {"beq ", "bne ", NULL, NULL, | "blt ", "bge ", "bltu", "bgeu"}; | static const char * const system_op[] = {"rw","rs","rc"}; | const unsigned INT16 *parcel = addr; | | while (bytes >= 2) { | unsigned INT32 instr = *parcel; | if ((instr&3) != 3) { | | fprintf(stderr, "%p %04x ", parcel, instr); | switch (((instr&3)<<3) | RV_CFUNCT3(instr)) { | case 0: | if (!(instr & 0x1f30)) | fprintf(stderr, "illegal\n"); | else | fprintf(stderr, "addi %s,%s,%d\n", | riscv_regname(RV_REGCD_(instr)), riscv_regname(2), | (int)RV_CIW_IMM(instr)); | break; | case 1: | #ifdef DISASSEMBLE_128BIT | fprintf(stderr, "lq %s,%d(%s)\n", | riscv_regname(RV_REGCD_(instr)), | (int)(RV_GET_BIT(instr,5,12)|RV_GET_BIT(instr,4,11)| | RV_GET_BIT(instr,8,10)|RV_GET_BITS(instr,7,6,5)), | riscv_regname(RV_REGCS1_(instr))); | #else | fprintf(stderr, "fld %s,%d(%s)\n", | riscv_fregname(RV_REGCD_(instr)), | (int)(RV_GET_BITS(instr,5,3,10)|RV_GET_BITS(instr,7,6,5)), | riscv_regname(RV_REGCS1_(instr))); | #endif | break; | case 2: | fprintf(stderr, "lw %s,%d(%s)\n", | riscv_regname(RV_REGCD_(instr)), | (int)(RV_GET_BITS(instr,5,3,10)| | RV_GET_BIT(instr,2,6)|RV_GET_BIT(instr,6,5)), | riscv_regname(RV_REGCS1_(instr))); | break; | case 3: | #ifdef DISASSEMBLE_32BIT | fprintf(stderr, "flw %s,%d(%s)\n", | riscv_fregname(RV_REGCD_(instr)), | (int)(RV_GET_BITS(instr,5,3,10)| | RV_GET_BIT(instr,2,6)|RV_GET_BIT(instr,6,5)), | riscv_regname(RV_REGCS1_(instr))); | #else | fprintf(stderr, "ld %s,%d(%s)\n", | riscv_regname(RV_REGCD_(instr)), | (int)(RV_GET_BITS(instr,5,3,10)|RV_GET_BITS(instr,7,6,5)), | riscv_regname(RV_REGCS1_(instr))); | #endif | break; | case 4: | fprintf(stderr, "reserved\n"); | break; | case 5: | #ifdef DISASSEMBLE_128BIT | fprintf(stderr, "sq %s,%d(%s)\n", | riscv_regname(RV_REGCS2_(instr)), | (int)(RV_GET_BIT(instr,5,12)|RV_GET_BIT(instr,4,11)| | RV_GET_BIT(instr,8,10)|RV_GET_BITS(instr,7,6,5)), | riscv_regname(RV_REGCS1_(instr))); | #else | fprintf(stderr, "fsd %s,%d(%s)\n", | riscv_fregname(RV_REGCS2_(instr)), | (int)(RV_GET_BITS(instr,5,3,10)|RV_GET_BITS(instr,7,6,5)), | riscv_regname(RV_REGCS1_(instr))); | #endif | break; | case 6: | fprintf(stderr, "sw %s,%d(%s)\n", | riscv_regname(RV_REGCS2_(instr)), | (int)(RV_GET_BITS(instr,5,3,10)| | RV_GET_BIT(instr,2,6)|RV_GET_BIT(instr,6,5)), | riscv_regname(RV_REGCS1_(instr))); | break; | case 7: | #ifdef DISASSEMBLE_32BIT | fprintf(stderr, "fsw %s,%d(%s)\n", | riscv_fregname(RV_REGCS2_(instr)), | (int)(RV_GET_BITS(instr,5,3,10)| | RV_GET_BIT(instr,2,6)|RV_GET_BIT(instr,6,5)), | riscv_regname(RV_REGCS1_(instr))); | #else | fprintf(stderr, "sd %s,%d(%s)\n", | riscv_regname(RV_REGCS2_(instr)), | (int)(RV_GET_BITS(instr,5,3,10)|RV_GET_BITS(instr,7,6,5)), | riscv_regname(RV_REGCS1_(instr))); | #endif | break; | case 8: | fprintf(stderr, "addi %s,%s,%d\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname(RV_REGCDS1(instr)), | (int)RV_CI_IMM(instr)); | break; | case 9: | #ifdef DISASSEMBLE_32BIT | fprintf(stderr, "jal %s,%p\n", | riscv_regname(1), | ((const char *)parcel)+RV_CJ_IMM(instr)); | #else | fprintf(stderr, "addiw %s,%s,%d\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname(RV_REGCDS1(instr)), | (int)RV_CI_IMM(instr)); | #endif | break; | case 10: | fprintf(stderr, "addi %s,%s,%d\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname(0), | (int)RV_CI_IMM(instr)); | break; | case 11: | if (((instr >> 7) & 31) == 2) | fprintf(stderr, "addi %s,%s,%d\n", | riscv_regname(2), riscv_regname(2), | (int)(INT32)(RV_GET_BIT(instr,4,6)|RV_GET_BIT(instr,6,5)| | RV_GET_BITS(instr,8,7,3)|RV_GET_BIT(instr,5,2)| | RV_GET_SIGNBIT(instr,9,12))); | else | fprintf(stderr, "lui %s,0x%x\n", | riscv_regname(RV_REGCDS1(instr)), | (unsigned)(RV_CI_IMM(instr)&0xfffff)); | break; | case 12: | switch ((instr >> 10) & 3) { | case 0: | #ifdef DISASSEMBLE_128BIT | fprintf(stderr, "srli %s,%s,%u\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname(RV_REGCDS1(instr)), | (unsigned)((instr & 0x107c)? | (((instr & 0x1000)? 96 : 0)+ | RV_GET_BITS(instr,4,0,2)) : 64)); | #else | fprintf(stderr, "srli %s,%s,%u\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname(RV_REGCDS1(instr)), | (unsigned)((RV_GET_BIT(instr,5,12)|RV_GET_BITS(instr,4,0,2)))); | #endif | break; | case 1: | #ifdef DISASSEMBLE_128BIT | fprintf(stderr, "srai %s,%s,%u\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname(RV_REGCDS1(instr)), | (unsigned)((instr & 0x107c)? | (((instr & 0x1000)? 96 : 0)+ | RV_GET_BITS(instr,4,0,2)) : 64)); | #else | fprintf(stderr, "srai %s,%s,%u\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname(RV_REGCDS1(instr)), | (unsigned)((RV_GET_BIT(instr,5,12)|RV_GET_BITS(instr,4,0,2)))); | #endif | break; | case 2: | fprintf(stderr, "andi %s,%s,%d\n", | riscv_regname(RV_REGCS1_(instr)), | riscv_regname(RV_REGCS1_(instr)), | (int)RV_CI_IMM(instr)); | break; | break; | case 3: | if ((instr & 0x1000) && ((instr >> 5)&3) >= 2) | fprintf(stderr, "???\n"); | else | fprintf(stderr, "%s %s,%s,%s\n", | rvcq1_op[RV_GET_BIT(instr,2,12)|RV_GET_BITS(instr,1,0,5)], | riscv_regname(RV_REGCS1_(instr)), | riscv_regname(RV_REGCS1_(instr)), | riscv_regname(RV_REGCS2_(instr))); | break; | } | break; | case 13: | fprintf(stderr, "j %s,%p\n", | riscv_regname(1), | ((const char *)parcel)+RV_CJ_IMM(instr)); | break; | case 14: | fprintf(stderr, "beq %s,%s,%p\n", | riscv_regname(RV_REGCS1_(instr)), | riscv_regname(0), | ((const char *)parcel)+RV_CB_IMM(instr)); | break; | case 15: | fprintf(stderr, "bne %s,%s,%p\n", | riscv_regname(RV_REGCS1_(instr)), | riscv_regname(0), | ((const char *)parcel)+RV_CB_IMM(instr)); | break; | case 16: | #ifdef DISASSEMBLE_128BIT | if (!(instr & 0x107c)) | fprintf(stderr, "slli %s,%s,%u\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname(RV_REGCDS1(instr)), | 64u); | else | #endif | fprintf(stderr, "slli %s,%s,%u\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname(RV_REGCDS1(instr)), | (unsigned)((RV_GET_BIT(instr,5,12)|RV_GET_BITS(instr,4,0,2)))); | break; | case 17: | #ifdef DISASSEMBLE_128BIT | fprintf(stderr, "lq %s,%d(%s)\n", | riscv_regname(RV_REGCDS1(instr)), | (int)(RV_GET_BIT(instr,5,12)| | RV_GET_BIT(instr,4,6)|RV_GET_BITS(instr,9,6,2)), | riscv_regname(2)); | #else | fprintf(stderr, "fld %s,%d(%s)\n", | riscv_fregname(RV_REGCDS1(instr)), | (int)(RV_GET_BIT(instr,5,12)| | RV_GET_BITS(instr,4,3,5)|RV_GET_BITS(instr,8,6,2)), | riscv_regname(2)); | #endif | break; | case 18: | fprintf(stderr, "lw %s,%d(%s)\n", | riscv_regname(RV_REGCDS1(instr)), | (int)(RV_GET_BIT(instr,5,12)| | RV_GET_BITS(instr,4,2,4)|RV_GET_BITS(instr,7,6,2)), | riscv_regname(2)); | break; | case 19: | #ifdef DISASSEMBLE_32BIT | fprintf(stderr, "flw %s,%d(%s)\n", | riscv_fregname(RV_REGCDS1(instr)), | (int)(RV_GET_BIT(instr,5,12)| | RV_GET_BITS(instr,4,2,4)|RV_GET_BITS(instr,7,6,2)), | riscv_regname(2)); | #else | fprintf(stderr, "ld %s,%d(%s)\n", | riscv_regname(RV_REGCDS1(instr)), | (int)(RV_GET_BIT(instr,5,12)| | RV_GET_BITS(instr,4,3,5)|RV_GET_BITS(instr,8,6,2)), | riscv_regname(2)); | #endif | break; | case 20: | if (RV_REGCS2(instr)) { | fprintf(stderr, "add %s,%s,%s\n", | riscv_regname(RV_REGCDS1(instr)), | riscv_regname((instr & 0x1000)? RV_REGCDS1(instr) : 0), | riscv_regname(RV_REGCS2(instr))); | } else if ((instr & 0x1000) && !RV_REGCDS1(instr)) { | fprintf(stderr, "ebreak\n"); | } else { | fprintf(stderr, "jalr %s,%s,0\n", | riscv_regname((instr & 0x1000)? 1 : 0), | riscv_regname(RV_REGCDS1(instr))); | } | break; | case 21: | #ifdef DISASSEMBLE_128BIT | fprintf(stderr, "sq %s,%d(%s)\n", | riscv_regname(RV_REGCS2(instr)), | (int)(RV_GET_BITS(instr,5,4,11)|RV_GET_BITS(instr,9,6,7)), | riscv_regname(2)); | #else | fprintf(stderr, "fsd %s,%d(%s)\n", | riscv_fregname(RV_REGCS2(instr)), | (int)(RV_GET_BITS(instr,5,3,10)|RV_GET_BITS(instr,8,6,7)), | riscv_regname(2)); | #endif | break; | case 22: | fprintf(stderr, "sw %s,%d(%s)\n", | riscv_regname(RV_REGCS2(instr)), | (int)(RV_GET_BITS(instr,5,2,9)|RV_GET_BITS(instr,7,6,7)), | riscv_regname(2)); | break; | case 23: | #ifdef DISASSEMBLE_32BIT | fprintf(stderr, "fsw %s,%d(%s)\n", | riscv_fregname(RV_REGCS2(instr)), | (int)(RV_GET_BITS(instr,5,2,9)|RV_GET_BITS(instr,7,6,7)), | riscv_regname(2)); | #else | fprintf(stderr, "sd %s,%d(%s)\n", | riscv_regname(RV_REGCS2(instr)), | (int)(RV_GET_BITS(instr,5,3,10)|RV_GET_BITS(instr,8,6,7)), | riscv_regname(2)); | #endif | break; | } | bytes -= 2; | parcel++; | } else if((instr&0x1f) != 0x1f) { | | if (bytes < 4) break; | instr |= ((unsigned INT32)parcel[1])<<16; | fprintf(stderr, "%p %08x ", parcel, instr); | switch ((instr >> 2) & 0x1f) { | case 0: | if (RV_FUNCT3(instr) <= 6) | fprintf(stderr, "%s %s,%d(%s)\n", | load_op[RV_FUNCT3(instr)], | riscv_regname(RV_REGD(instr)), | (int)RV_I_IMM(instr), | riscv_regname(RV_REGS1(instr))); | else | fprintf(stderr, "???\n"); | break; | case 3: | switch(RV_FUNCT3(instr)) { | case 0: | fprintf(stderr, "fence %u,%u\n", | (unsigned)RV_GET_BITS(instr,3,0,24), | (unsigned)RV_GET_BITS(instr,3,0,20)); | break; | case 1: | fprintf(stderr, "fence.i\n"); | break; | default: | fprintf(stderr, "???\n"); | break; | } | break; | case 4: | case 6: | { | const char *op = op_imm_op[RV_FUNCT3(instr)]; | if (*op == '*') { | fprintf(stderr, "%s%ci%c %s,%s,%u\n", op+1, | ((instr & 0x40000000)? 'a':'l'), | ((instr&4)? 'w':' '), | riscv_regname(RV_REGD(instr)), | riscv_regname(RV_REGS1(instr)), | (unsigned)RV_GET_BITS(instr,5,0,20)); | } else | fprintf(stderr, "%s%-*c%s,%s,%d\n", op, | (int)(8-strlen(op)), ((instr&4)? 'w':' '), | riscv_regname(RV_REGD(instr)), | riscv_regname(RV_REGS1(instr)), | (int)RV_I_IMM(instr)); | } | break; | case 5: | fprintf(stderr, "auipc %s,0x%x\n", | riscv_regname(RV_REGD(instr)), | (unsigned)RV_U_IMM(instr)); | break; | case 8: | if (RV_FUNCT3(instr) <= 3) | fprintf(stderr, "%s %s,%d(%s)\n", | store_op[RV_FUNCT3(instr)], | riscv_regname(RV_REGS2(instr)), | (int)RV_S_IMM(instr), | riscv_regname(RV_REGS1(instr))); | else | fprintf(stderr, "???\n"); | break; | break; | case 12: | case 14: | { | const char *op = | ((instr & 0x02000000)? mul_op:op_op)[RV_FUNCT3(instr)]; | if (*op == '*') { | op++; | if (instr & 0x40000000) | op = (*op == 'a'? "sub":"sra"); | } | fprintf(stderr, "%s%-*c%s,%s,%s\n", op, | (int)(8-strlen(op)), ((instr&4)? 'w':' '), | riscv_regname(RV_REGD(instr)), | riscv_regname(RV_REGS1(instr)), | riscv_regname(RV_REGS2(instr))); | } | break; | case 13: | fprintf(stderr, "lui %s,0x%x\n", | riscv_regname(RV_REGD(instr)), | (unsigned)RV_U_IMM(instr)); | break; | case 24: | if (branch_op[RV_FUNCT3(instr)]) | fprintf(stderr, "%s %s,%s,%p\n", | branch_op[RV_FUNCT3(instr)], | riscv_regname(RV_REGS1(instr)), | riscv_regname(RV_REGS2(instr)), | ((const char *)parcel)+RV_B_IMM(instr)); | else | fprintf(stderr, "???\n"); | break; | case 25: | fprintf(stderr, "jalr %s,%s,%d\n", | riscv_regname(RV_REGD(instr)), | riscv_regname(RV_REGS1(instr)), | (int)RV_I_IMM(instr)); | break; | case 27: | fprintf(stderr, "jal %s,%p\n", | riscv_regname(RV_REGD(instr)), | ((const char *)parcel)+RV_J_IMM(instr)); | break; | case 28: | switch(RV_FUNCT3(instr)) { | case 0: | switch(RV_FUNCT12(instr)) { | case 0: | fprintf(stderr, "ecall\n"); | break; | case 1: | fprintf(stderr, "ebreak\n"); | break; | default: | fprintf(stderr, "???\n"); | break; | } | break; | case 1: | case 2: | case 3: | fprintf(stderr, "csr%s %s,%u,%s\n", | system_op[RV_FUNCT3(instr)-1], | riscv_regname(RV_REGD(instr)), | (unsigned)RV_CSR(instr), | riscv_regname(RV_REGS1(instr))); | break; | case 5: | case 6: | case 7: | fprintf(stderr, "csr%si %s,%u,%u\n", | system_op[RV_FUNCT3(instr)-5], | riscv_regname(RV_REGD(instr)), | (unsigned)RV_CSR(instr), | (unsigned)RV_CSR_IMM(instr)); | break; | default: | fprintf(stderr, "???\n"); | } | break; | case 1: | case 9: | case 11: | case 16: | case 17: | case 18: | case 19: | case 20: | default: | fprintf(stderr, "???\n"); | } | bytes -= 4; | parcel+=2; | } else { | | unsigned parcel_count, i; | if (!(instr & 0x20)) | parcel_count = 3; | else if(!(instr & 0x40)) | parcel_count = 4; | else if((instr & 0x7000) != 0x7000) | parcel_count = 5 + ((instr >> 12) & 7); | else | parcel_count = 1; | if (bytes < parcel_count * 2) | break; | fprintf(stderr, "%p ", parcel); | for (i = parcel_count; i > 0; ) { | fprintf(stderr, "%04x", parcel[--i]); | } | fprintf(stderr, "\n"); | bytes -= parcel_count * 2; | parcel += parcel_count; | } | } | if (bytes > 0) { | const unsigned char *rest = (const unsigned char *)parcel; | while(bytes > 0) { | fprintf(stderr, "%p %02x\n", rest, *rest); | --bytes; | rest++; | } | } | } | | |
|