target/rx: Emit all disassembly in one prt()
[qemu.git] / target / rx / disas.c
1 /*
2 * Renesas RX Disassembler
3 *
4 * Copyright (c) 2019 Yoshinori Sato <ysato@users.sourceforge.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2 or later, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "qemu/osdep.h"
20 #include "disas/dis-asm.h"
21 #include "qemu/bitops.h"
22 #include "cpu.h"
23
24 typedef struct DisasContext {
25 disassemble_info *dis;
26 uint32_t addr;
27 uint32_t pc;
28 } DisasContext;
29
30
31 static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
32 int i, int n)
33 {
34 bfd_byte buf;
35 while (++i <= n) {
36 ctx->dis->read_memory_func(ctx->addr++, &buf, 1, ctx->dis);
37 insn |= buf << (32 - i * 8);
38 }
39 return insn;
40 }
41
42 static int32_t li(DisasContext *ctx, int sz)
43 {
44 int32_t addr;
45 bfd_byte buf[4];
46 addr = ctx->addr;
47
48 switch (sz) {
49 case 1:
50 ctx->addr += 1;
51 ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
52 return (int8_t)buf[0];
53 case 2:
54 ctx->addr += 2;
55 ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
56 return ldsw_le_p(buf);
57 case 3:
58 ctx->addr += 3;
59 ctx->dis->read_memory_func(addr, buf, 3, ctx->dis);
60 return (int8_t)buf[2] << 16 | lduw_le_p(buf);
61 case 0:
62 ctx->addr += 4;
63 ctx->dis->read_memory_func(addr, buf, 4, ctx->dis);
64 return ldl_le_p(buf);
65 default:
66 g_assert_not_reached();
67 }
68 }
69
70 static int bdsp_s(DisasContext *ctx, int d)
71 {
72 /*
73 * 0 -> 8
74 * 1 -> 9
75 * 2 -> 10
76 * 3 -> 3
77 * :
78 * 7 -> 7
79 */
80 if (d < 3) {
81 d += 8;
82 }
83 return d;
84 }
85
86 /* Include the auto-generated decoder. */
87 #include "decode.inc.c"
88
89 #define prt(...) (ctx->dis->fprintf_func)((ctx->dis->stream), __VA_ARGS__)
90
91 #define RX_MEMORY_BYTE 0
92 #define RX_MEMORY_WORD 1
93 #define RX_MEMORY_LONG 2
94
95 #define RX_IM_BYTE 0
96 #define RX_IM_WORD 1
97 #define RX_IM_LONG 2
98 #define RX_IM_UWORD 3
99
100 static const char size[] = {'b', 'w', 'l'};
101 static const char cond[][4] = {
102 "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
103 "ge", "lt", "gt", "le", "o", "no", "ra", "f"
104 };
105 static const char psw[] = {
106 'c', 'z', 's', 'o', 0, 0, 0, 0,
107 'i', 'u', 0, 0, 0, 0, 0, 0,
108 };
109
110 static void rx_index_addr(DisasContext *ctx, char out[8], int ld, int mi)
111 {
112 uint32_t addr = ctx->addr;
113 uint8_t buf[2];
114 uint16_t dsp;
115
116 switch (ld) {
117 case 0:
118 /* No index; return empty string. */
119 out[0] = '\0';
120 return;
121 case 1:
122 ctx->addr += 1;
123 ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
124 dsp = buf[0];
125 break;
126 case 2:
127 ctx->addr += 2;
128 ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
129 dsp = lduw_le_p(buf);
130 break;
131 default:
132 g_assert_not_reached();
133 }
134
135 sprintf(out, "%u", dsp << (mi < 3 ? mi : 4 - mi));
136 }
137
138 static void prt_ldmi(DisasContext *ctx, const char *insn,
139 int ld, int mi, int rs, int rd)
140 {
141 static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"};
142 char dsp[8];
143
144 if (ld < 3) {
145 rx_index_addr(ctx, dsp, ld, mi);
146 prt("%s\t%s[r%d]%s, r%d", insn, dsp, rs, sizes[mi], rd);
147 } else {
148 prt("%s\tr%d, r%d", insn, rs, rd);
149 }
150 }
151
152 static void prt_ir(DisasContext *ctx, const char *insn, int imm, int rd)
153 {
154 if (imm < 0x100) {
155 prt("%s\t#%d, r%d", insn, imm, rd);
156 } else {
157 prt("%s\t#0x%08x, r%d", insn, imm, rd);
158 }
159 }
160
161 /* mov.[bwl] rs,dsp:[rd] */
162 static bool trans_MOV_rm(DisasContext *ctx, arg_MOV_rm *a)
163 {
164 if (a->dsp > 0) {
165 prt("mov.%c\tr%d,%d[r%d]",
166 size[a->sz], a->rs, a->dsp << a->sz, a->rd);
167 } else {
168 prt("mov.%c\tr%d,[r%d]",
169 size[a->sz], a->rs, a->rd);
170 }
171 return true;
172 }
173
174 /* mov.[bwl] dsp:[rs],rd */
175 static bool trans_MOV_mr(DisasContext *ctx, arg_MOV_mr *a)
176 {
177 if (a->dsp > 0) {
178 prt("mov.%c\t%d[r%d], r%d",
179 size[a->sz], a->dsp << a->sz, a->rs, a->rd);
180 } else {
181 prt("mov.%c\t[r%d], r%d",
182 size[a->sz], a->rs, a->rd);
183 }
184 return true;
185 }
186
187 /* mov.l #uimm4,rd */
188 /* mov.l #uimm8,rd */
189 /* mov.l #imm,rd */
190 static bool trans_MOV_ir(DisasContext *ctx, arg_MOV_ir *a)
191 {
192 prt_ir(ctx, "mov.l", a->imm, a->rd);
193 return true;
194 }
195
196 /* mov.[bwl] #uimm8,dsp:[rd] */
197 /* mov #imm, dsp:[rd] */
198 static bool trans_MOV_im(DisasContext *ctx, arg_MOV_im *a)
199 {
200 if (a->dsp > 0) {
201 prt("mov.%c\t#%d,%d[r%d]",
202 size[a->sz], a->imm, a->dsp << a->sz, a->rd);
203 } else {
204 prt("mov.%c\t#%d,[r%d]",
205 size[a->sz], a->imm, a->rd);
206 }
207 return true;
208 }
209
210 /* mov.[bwl] [ri,rb],rd */
211 static bool trans_MOV_ar(DisasContext *ctx, arg_MOV_ar *a)
212 {
213 prt("mov.%c\t[r%d,r%d], r%d", size[a->sz], a->ri, a->rb, a->rd);
214 return true;
215 }
216
217 /* mov.[bwl] rd,[ri,rb] */
218 static bool trans_MOV_ra(DisasContext *ctx, arg_MOV_ra *a)
219 {
220 prt("mov.%c\tr%d, [r%d, r%d]", size[a->sz], a->rs, a->ri, a->rb);
221 return true;
222 }
223
224
225 /* mov.[bwl] dsp:[rs],dsp:[rd] */
226 /* mov.[bwl] rs,dsp:[rd] */
227 /* mov.[bwl] dsp:[rs],rd */
228 /* mov.[bwl] rs,rd */
229 static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
230 {
231 char dspd[8], dsps[8], szc = size[a->sz];
232
233 if (a->lds == 3 && a->ldd == 3) {
234 /* mov.[bwl] rs,rd */
235 prt("mov.%c\tr%d, r%d", szc, a->rs, a->rd);
236 } else if (a->lds == 3) {
237 rx_index_addr(ctx, dspd, a->ldd, a->sz);
238 prt("mov.%c\tr%d, %s[r%d]", szc, a->rs, dspd, a->rd);
239 } else if (a->ldd == 3) {
240 rx_index_addr(ctx, dsps, a->lds, a->sz);
241 prt("mov.%c\t%s[r%d], r%d", szc, dsps, a->rs, a->rd);
242 } else {
243 rx_index_addr(ctx, dsps, a->lds, a->sz);
244 rx_index_addr(ctx, dspd, a->ldd, a->sz);
245 prt("mov.%c\t%s[r%d], %s[r%d]", szc, dsps, a->rs, dspd, a->rd);
246 }
247 return true;
248 }
249
250 /* mov.[bwl] rs,[rd+] */
251 /* mov.[bwl] rs,[-rd] */
252 static bool trans_MOV_rp(DisasContext *ctx, arg_MOV_rp *a)
253 {
254 if (a->ad) {
255 prt("mov.%c\tr%d, [-r%d]", size[a->sz], a->rs, a->rd);
256 } else {
257 prt("mov.%c\tr%d, [r%d+]", size[a->sz], a->rs, a->rd);
258 }
259 return true;
260 }
261
262 /* mov.[bwl] [rd+],rs */
263 /* mov.[bwl] [-rd],rs */
264 static bool trans_MOV_pr(DisasContext *ctx, arg_MOV_pr *a)
265 {
266 if (a->ad) {
267 prt("mov.%c\t[-r%d], r%d", size[a->sz], a->rd, a->rs);
268 } else {
269 prt("mov.%c\t[r%d+], r%d", size[a->sz], a->rd, a->rs);
270 }
271 return true;
272 }
273
274 /* movu.[bw] dsp5:[rs],rd */
275 static bool trans_MOVU_mr(DisasContext *ctx, arg_MOVU_mr *a)
276 {
277 if (a->dsp > 0) {
278 prt("movu.%c\t%d[r%d], r%d", size[a->sz],
279 a->dsp << a->sz, a->rs, a->rd);
280 } else {
281 prt("movu.%c\t[r%d], r%d", size[a->sz], a->rs, a->rd);
282 }
283 return true;
284 }
285
286 /* movu.[bw] rs,rd */
287 static bool trans_MOVU_rr(DisasContext *ctx, arg_MOVU_rr *a)
288 {
289 prt("movu.%c\tr%d, r%d", size[a->sz], a->rs, a->rd);
290 return true;
291 }
292
293 /* movu.[bw] [ri,rb],rd */
294 static bool trans_MOVU_ar(DisasContext *ctx, arg_MOVU_ar *a)
295 {
296 prt("mov.%c\t[r%d,r%d], r%d", size[a->sz], a->ri, a->rb, a->rd);
297 return true;
298 }
299
300 /* movu.[bw] [rs+],rd */
301 /* movu.[bw] [-rs],rd */
302 static bool trans_MOVU_pr(DisasContext *ctx, arg_MOVU_pr *a)
303 {
304 if (a->ad) {
305 prt("movu.%c\t[-r%d], r%d", size[a->sz], a->rd, a->rs);
306 } else {
307 prt("movu.%c\t[r%d+], r%d", size[a->sz], a->rd, a->rs);
308 }
309 return true;
310 }
311
312 /* pop rd */
313 static bool trans_POP(DisasContext *ctx, arg_POP *a)
314 {
315 prt("pop\tr%d", a->rd);
316 return true;
317 }
318
319 /* popc rx */
320 static bool trans_POPC(DisasContext *ctx, arg_POPC *a)
321 {
322 prt("pop\tr%s", rx_crname(a->cr));
323 return true;
324 }
325
326 /* popm rd-rd2 */
327 static bool trans_POPM(DisasContext *ctx, arg_POPM *a)
328 {
329 prt("popm\tr%d-r%d", a->rd, a->rd2);
330 return true;
331 }
332
333 /* push rs */
334 static bool trans_PUSH_r(DisasContext *ctx, arg_PUSH_r *a)
335 {
336 prt("push\tr%d", a->rs);
337 return true;
338 }
339
340 /* push dsp[rs] */
341 static bool trans_PUSH_m(DisasContext *ctx, arg_PUSH_m *a)
342 {
343 char dsp[8];
344
345 rx_index_addr(ctx, dsp, a->ld, a->sz);
346 prt("push\t%s[r%d]", dsp, a->rs);
347 return true;
348 }
349
350 /* pushc rx */
351 static bool trans_PUSHC(DisasContext *ctx, arg_PUSHC *a)
352 {
353 prt("push\t%s", rx_crname(a->cr));
354 return true;
355 }
356
357 /* pushm rs-rs2*/
358 static bool trans_PUSHM(DisasContext *ctx, arg_PUSHM *a)
359 {
360 prt("pushm\tr%d-r%d", a->rs, a->rs2);
361 return true;
362 }
363
364 /* xchg rs,rd */
365 static bool trans_XCHG_rr(DisasContext *ctx, arg_XCHG_rr *a)
366 {
367 prt("xchg\tr%d, r%d", a->rs, a->rd);
368 return true;
369 }
370 /* xchg dsp[rs].<mi>,rd */
371 static bool trans_XCHG_mr(DisasContext *ctx, arg_XCHG_mr *a)
372 {
373 prt_ldmi(ctx, "xchg", a->ld, a->mi, a->rs, a->rd);
374 return true;
375 }
376
377 /* stz #imm,rd */
378 static bool trans_STZ(DisasContext *ctx, arg_STZ *a)
379 {
380 prt_ir(ctx, "stz", a->imm, a->rd);
381 return true;
382 }
383
384 /* stnz #imm,rd */
385 static bool trans_STNZ(DisasContext *ctx, arg_STNZ *a)
386 {
387 prt_ir(ctx, "stnz", a->imm, a->rd);
388 return true;
389 }
390
391 /* rtsd #imm */
392 static bool trans_RTSD_i(DisasContext *ctx, arg_RTSD_i *a)
393 {
394 prt("rtsd\t#%d", a->imm << 2);
395 return true;
396 }
397
398 /* rtsd #imm, rd-rd2 */
399 static bool trans_RTSD_irr(DisasContext *ctx, arg_RTSD_irr *a)
400 {
401 prt("rtsd\t#%d, r%d - r%d", a->imm << 2, a->rd, a->rd2);
402 return true;
403 }
404
405 /* and #uimm:4, rd */
406 /* and #imm, rd */
407 static bool trans_AND_ir(DisasContext *ctx, arg_AND_ir *a)
408 {
409 prt_ir(ctx, "and", a->imm, a->rd);
410 return true;
411 }
412
413 /* and dsp[rs], rd */
414 /* and rs,rd */
415 static bool trans_AND_mr(DisasContext *ctx, arg_AND_mr *a)
416 {
417 prt_ldmi(ctx, "and", a->ld, a->mi, a->rs, a->rd);
418 return true;
419 }
420
421 /* and rs,rs2,rd */
422 static bool trans_AND_rrr(DisasContext *ctx, arg_AND_rrr *a)
423 {
424 prt("and\tr%d,r%d, r%d", a->rs, a->rs2, a->rd);
425 return true;
426 }
427
428 /* or #uimm:4, rd */
429 /* or #imm, rd */
430 static bool trans_OR_ir(DisasContext *ctx, arg_OR_ir *a)
431 {
432 prt_ir(ctx, "or", a->imm, a->rd);
433 return true;
434 }
435
436 /* or dsp[rs], rd */
437 /* or rs,rd */
438 static bool trans_OR_mr(DisasContext *ctx, arg_OR_mr *a)
439 {
440 prt_ldmi(ctx, "or", a->ld, a->mi, a->rs, a->rd);
441 return true;
442 }
443
444 /* or rs,rs2,rd */
445 static bool trans_OR_rrr(DisasContext *ctx, arg_OR_rrr *a)
446 {
447 prt("or\tr%d, r%d, r%d", a->rs, a->rs2, a->rd);
448 return true;
449 }
450
451 /* xor #imm, rd */
452 static bool trans_XOR_ir(DisasContext *ctx, arg_XOR_ir *a)
453 {
454 prt_ir(ctx, "xor", a->imm, a->rd);
455 return true;
456 }
457
458 /* xor dsp[rs], rd */
459 /* xor rs,rd */
460 static bool trans_XOR_mr(DisasContext *ctx, arg_XOR_mr *a)
461 {
462 prt_ldmi(ctx, "xor", a->ld, a->mi, a->rs, a->rd);
463 return true;
464 }
465
466 /* tst #imm, rd */
467 static bool trans_TST_ir(DisasContext *ctx, arg_TST_ir *a)
468 {
469 prt_ir(ctx, "tst", a->imm, a->rd);
470 return true;
471 }
472
473 /* tst dsp[rs], rd */
474 /* tst rs, rd */
475 static bool trans_TST_mr(DisasContext *ctx, arg_TST_mr *a)
476 {
477 prt_ldmi(ctx, "tst", a->ld, a->mi, a->rs, a->rd);
478 return true;
479 }
480
481 /* not rd */
482 /* not rs, rd */
483 static bool trans_NOT_rr(DisasContext *ctx, arg_NOT_rr *a)
484 {
485 if (a->rs != a->rd) {
486 prt("not\tr%d, r%d", a->rs, a->rd);
487 } else {
488 prt("not\tr%d", a->rs);
489 }
490 return true;
491 }
492
493 /* neg rd */
494 /* neg rs, rd */
495 static bool trans_NEG_rr(DisasContext *ctx, arg_NEG_rr *a)
496 {
497 if (a->rs != a->rd) {
498 prt("neg\tr%d, r%d", a->rs, a->rd);
499 } else {
500 prt("neg\tr%d", a->rs);
501 }
502 return true;
503 }
504
505 /* adc #imm, rd */
506 static bool trans_ADC_ir(DisasContext *ctx, arg_ADC_ir *a)
507 {
508 prt_ir(ctx, "adc", a->imm, a->rd);
509 return true;
510 }
511
512 /* adc rs, rd */
513 static bool trans_ADC_rr(DisasContext *ctx, arg_ADC_rr *a)
514 {
515 prt("adc\tr%d, r%d", a->rs, a->rd);
516 return true;
517 }
518
519 /* adc dsp[rs], rd */
520 static bool trans_ADC_mr(DisasContext *ctx, arg_ADC_mr *a)
521 {
522 char dsp[8];
523
524 rx_index_addr(ctx, dsp, a->ld, 2);
525 prt("adc\t%s[r%d], r%d", dsp, a->rs, a->rd);
526 return true;
527 }
528
529 /* add #uimm4, rd */
530 /* add #imm, rs, rd */
531 static bool trans_ADD_irr(DisasContext *ctx, arg_ADD_irr *a)
532 {
533 if (a->imm < 0x10 && a->rs2 == a->rd) {
534 prt("add\t#%d, r%d", a->imm, a->rd);
535 } else {
536 prt("add\t#0x%08x, r%d, r%d", a->imm, a->rs2, a->rd);
537 }
538 return true;
539 }
540
541 /* add rs, rd */
542 /* add dsp[rs], rd */
543 static bool trans_ADD_mr(DisasContext *ctx, arg_ADD_mr *a)
544 {
545 prt_ldmi(ctx, "add", a->ld, a->mi, a->rs, a->rd);
546 return true;
547 }
548
549 /* add rs, rs2, rd */
550 static bool trans_ADD_rrr(DisasContext *ctx, arg_ADD_rrr *a)
551 {
552 prt("add\tr%d, r%d, r%d", a->rs, a->rs2, a->rd);
553 return true;
554 }
555
556 /* cmp #imm4, rd */
557 /* cmp #imm8, rd */
558 /* cmp #imm, rs2 */
559 static bool trans_CMP_ir(DisasContext *ctx, arg_CMP_ir *a)
560 {
561 prt_ir(ctx, "cmp", a->imm, a->rs2);
562 return true;
563 }
564
565 /* cmp rs, rs2 */
566 /* cmp dsp[rs], rs2 */
567 static bool trans_CMP_mr(DisasContext *ctx, arg_CMP_mr *a)
568 {
569 prt_ldmi(ctx, "cmp", a->ld, a->mi, a->rs, a->rd);
570 return true;
571 }
572
573 /* sub #imm4, rd */
574 static bool trans_SUB_ir(DisasContext *ctx, arg_SUB_ir *a)
575 {
576 prt("sub\t#%d, r%d", a->imm, a->rd);
577 return true;
578 }
579
580 /* sub rs, rd */
581 /* sub dsp[rs], rd */
582 static bool trans_SUB_mr(DisasContext *ctx, arg_SUB_mr *a)
583 {
584 prt_ldmi(ctx, "sub", a->ld, a->mi, a->rs, a->rd);
585 return true;
586 }
587
588 /* sub rs, rs2, rd */
589 static bool trans_SUB_rrr(DisasContext *ctx, arg_SUB_rrr *a)
590 {
591 prt("sub\tr%d, r%d, r%d", a->rs, a->rs2, a->rd);
592 return true;
593 }
594
595 /* sbb rs, rd */
596 static bool trans_SBB_rr(DisasContext *ctx, arg_SBB_rr *a)
597 {
598 prt("sbb\tr%d, r%d", a->rs, a->rd);
599 return true;
600 }
601
602 /* sbb dsp[rs], rd */
603 static bool trans_SBB_mr(DisasContext *ctx, arg_SBB_mr *a)
604 {
605 prt_ldmi(ctx, "sbb", a->ld, RX_IM_LONG, a->rs, a->rd);
606 return true;
607 }
608
609 /* abs rd */
610 /* abs rs, rd */
611 static bool trans_ABS_rr(DisasContext *ctx, arg_ABS_rr *a)
612 {
613 if (a->rs != a->rd) {
614 prt("abs\tr%d, r%d", a->rs, a->rd);
615 } else {
616 prt("abs\tr%d", a->rs);
617 }
618 return true;
619 }
620
621 /* max #imm, rd */
622 static bool trans_MAX_ir(DisasContext *ctx, arg_MAX_ir *a)
623 {
624 prt_ir(ctx, "max", a->imm, a->rd);
625 return true;
626 }
627
628 /* max rs, rd */
629 /* max dsp[rs], rd */
630 static bool trans_MAX_mr(DisasContext *ctx, arg_MAX_mr *a)
631 {
632 prt_ldmi(ctx, "max", a->ld, a->mi, a->rs, a->rd);
633 return true;
634 }
635
636 /* min #imm, rd */
637 static bool trans_MIN_ir(DisasContext *ctx, arg_MIN_ir *a)
638 {
639 prt_ir(ctx, "min", a->imm, a->rd);
640 return true;
641 }
642
643 /* min rs, rd */
644 /* min dsp[rs], rd */
645 static bool trans_MIN_mr(DisasContext *ctx, arg_MIN_mr *a)
646 {
647 prt_ldmi(ctx, "min", a->ld, a->mi, a->rs, a->rd);
648 return true;
649 }
650
651 /* mul #uimm4, rd */
652 /* mul #imm, rd */
653 static bool trans_MUL_ir(DisasContext *ctx, arg_MUL_ir *a)
654 {
655 prt_ir(ctx, "mul", a->imm, a->rd);
656 return true;
657 }
658
659 /* mul rs, rd */
660 /* mul dsp[rs], rd */
661 static bool trans_MUL_mr(DisasContext *ctx, arg_MUL_mr *a)
662 {
663 prt_ldmi(ctx, "mul", a->ld, a->mi, a->rs, a->rd);
664 return true;
665 }
666
667 /* mul rs, rs2, rd */
668 static bool trans_MUL_rrr(DisasContext *ctx, arg_MUL_rrr *a)
669 {
670 prt("mul\tr%d,r%d,r%d", a->rs, a->rs2, a->rd);
671 return true;
672 }
673
674 /* emul #imm, rd */
675 static bool trans_EMUL_ir(DisasContext *ctx, arg_EMUL_ir *a)
676 {
677 prt_ir(ctx, "emul", a->imm, a->rd);
678 return true;
679 }
680
681 /* emul rs, rd */
682 /* emul dsp[rs], rd */
683 static bool trans_EMUL_mr(DisasContext *ctx, arg_EMUL_mr *a)
684 {
685 prt_ldmi(ctx, "emul", a->ld, a->mi, a->rs, a->rd);
686 return true;
687 }
688
689 /* emulu #imm, rd */
690 static bool trans_EMULU_ir(DisasContext *ctx, arg_EMULU_ir *a)
691 {
692 prt_ir(ctx, "emulu", a->imm, a->rd);
693 return true;
694 }
695
696 /* emulu rs, rd */
697 /* emulu dsp[rs], rd */
698 static bool trans_EMULU_mr(DisasContext *ctx, arg_EMULU_mr *a)
699 {
700 prt_ldmi(ctx, "emulu", a->ld, a->mi, a->rs, a->rd);
701 return true;
702 }
703
704 /* div #imm, rd */
705 static bool trans_DIV_ir(DisasContext *ctx, arg_DIV_ir *a)
706 {
707 prt_ir(ctx, "div", a->imm, a->rd);
708 return true;
709 }
710
711 /* div rs, rd */
712 /* div dsp[rs], rd */
713 static bool trans_DIV_mr(DisasContext *ctx, arg_DIV_mr *a)
714 {
715 prt_ldmi(ctx, "div", a->ld, a->mi, a->rs, a->rd);
716 return true;
717 }
718
719 /* divu #imm, rd */
720 static bool trans_DIVU_ir(DisasContext *ctx, arg_DIVU_ir *a)
721 {
722 prt_ir(ctx, "divu", a->imm, a->rd);
723 return true;
724 }
725
726 /* divu rs, rd */
727 /* divu dsp[rs], rd */
728 static bool trans_DIVU_mr(DisasContext *ctx, arg_DIVU_mr *a)
729 {
730 prt_ldmi(ctx, "divu", a->ld, a->mi, a->rs, a->rd);
731 return true;
732 }
733
734
735 /* shll #imm:5, rd */
736 /* shll #imm:5, rs, rd */
737 static bool trans_SHLL_irr(DisasContext *ctx, arg_SHLL_irr *a)
738 {
739 if (a->rs2 != a->rd) {
740 prt("shll\t#%d, r%d, r%d", a->imm, a->rs2, a->rd);
741 } else {
742 prt("shll\t#%d, r%d", a->imm, a->rd);
743 }
744 return true;
745 }
746
747 /* shll rs, rd */
748 static bool trans_SHLL_rr(DisasContext *ctx, arg_SHLL_rr *a)
749 {
750 prt("shll\tr%d, r%d", a->rs, a->rd);
751 return true;
752 }
753
754 /* shar #imm:5, rd */
755 /* shar #imm:5, rs, rd */
756 static bool trans_SHAR_irr(DisasContext *ctx, arg_SHAR_irr *a)
757 {
758 if (a->rs2 != a->rd) {
759 prt("shar\t#%d, r%d, r%d", a->imm, a->rs2, a->rd);
760 } else {
761 prt("shar\t#%d, r%d", a->imm, a->rd);
762 }
763 return true;
764 }
765
766 /* shar rs, rd */
767 static bool trans_SHAR_rr(DisasContext *ctx, arg_SHAR_rr *a)
768 {
769 prt("shar\tr%d, r%d", a->rs, a->rd);
770 return true;
771 }
772
773 /* shlr #imm:5, rd */
774 /* shlr #imm:5, rs, rd */
775 static bool trans_SHLR_irr(DisasContext *ctx, arg_SHLR_irr *a)
776 {
777 if (a->rs2 != a->rd) {
778 prt("shlr\t#%d, r%d, r%d", a->imm, a->rs2, a->rd);
779 } else {
780 prt("shlr\t#%d, r%d", a->imm, a->rd);
781 }
782 return true;
783 }
784
785 /* shlr rs, rd */
786 static bool trans_SHLR_rr(DisasContext *ctx, arg_SHLR_rr *a)
787 {
788 prt("shlr\tr%d, r%d", a->rs, a->rd);
789 return true;
790 }
791
792 /* rolc rd */
793 static bool trans_ROLC(DisasContext *ctx, arg_ROLC *a)
794 {
795 prt("rorc\tr%d", a->rd);
796 return true;
797 }
798
799 /* rorc rd */
800 static bool trans_RORC(DisasContext *ctx, arg_RORC *a)
801 {
802 prt("rorc\tr%d", a->rd);
803 return true;
804 }
805
806 /* rotl #imm, rd */
807 static bool trans_ROTL_ir(DisasContext *ctx, arg_ROTL_ir *a)
808 {
809 prt("rotl\t#%d, r%d", a->imm, a->rd);
810 return true;
811 }
812
813 /* rotl rs, rd */
814 static bool trans_ROTL_rr(DisasContext *ctx, arg_ROTL_rr *a)
815 {
816 prt("rotl\tr%d, r%d", a->rs, a->rd);
817 return true;
818 }
819
820 /* rotr #imm, rd */
821 static bool trans_ROTR_ir(DisasContext *ctx, arg_ROTR_ir *a)
822 {
823 prt("rotr\t#%d, r%d", a->imm, a->rd);
824 return true;
825 }
826
827 /* rotr rs, rd */
828 static bool trans_ROTR_rr(DisasContext *ctx, arg_ROTR_rr *a)
829 {
830 prt("rotr\tr%d, r%d", a->rs, a->rd);
831 return true;
832 }
833
834 /* revl rs, rd */
835 static bool trans_REVL(DisasContext *ctx, arg_REVL *a)
836 {
837 prt("revl\tr%d, r%d", a->rs, a->rd);
838 return true;
839 }
840
841 /* revw rs, rd */
842 static bool trans_REVW(DisasContext *ctx, arg_REVW *a)
843 {
844 prt("revw\tr%d, r%d", a->rs, a->rd);
845 return true;
846 }
847
848 /* conditional branch helper */
849 static void rx_bcnd_main(DisasContext *ctx, int cd, int len, int dst)
850 {
851 static const char sz[] = {'s', 'b', 'w', 'a'};
852 prt("b%s.%c\t%08x", cond[cd], sz[len - 1], ctx->pc + dst);
853 }
854
855 /* beq dsp:3 / bne dsp:3 */
856 /* beq dsp:8 / bne dsp:8 */
857 /* bc dsp:8 / bnc dsp:8 */
858 /* bgtu dsp:8 / bleu dsp:8 */
859 /* bpz dsp:8 / bn dsp:8 */
860 /* bge dsp:8 / blt dsp:8 */
861 /* bgt dsp:8 / ble dsp:8 */
862 /* bo dsp:8 / bno dsp:8 */
863 /* beq dsp:16 / bne dsp:16 */
864 static bool trans_BCnd(DisasContext *ctx, arg_BCnd *a)
865 {
866 rx_bcnd_main(ctx, a->cd, a->sz, a->dsp);
867 return true;
868 }
869
870 /* bra dsp:3 */
871 /* bra dsp:8 */
872 /* bra dsp:16 */
873 /* bra dsp:24 */
874 static bool trans_BRA(DisasContext *ctx, arg_BRA *a)
875 {
876 rx_bcnd_main(ctx, 14, a->sz, a->dsp);
877 return true;
878 }
879
880 /* bra rs */
881 static bool trans_BRA_l(DisasContext *ctx, arg_BRA_l *a)
882 {
883 prt("bra.l\tr%d", a->rd);
884 return true;
885 }
886
887 /* jmp rs */
888 static bool trans_JMP(DisasContext *ctx, arg_JMP *a)
889 {
890 prt("jmp\tr%d", a->rs);
891 return true;
892 }
893
894 /* jsr rs */
895 static bool trans_JSR(DisasContext *ctx, arg_JSR *a)
896 {
897 prt("jsr\tr%d", a->rs);
898 return true;
899 }
900
901 /* bsr dsp:16 */
902 /* bsr dsp:24 */
903 static bool trans_BSR(DisasContext *ctx, arg_BSR *a)
904 {
905 static const char sz[] = {'w', 'a'};
906 prt("bsr.%c\t%08x", sz[a->sz - 3], ctx->pc + a->dsp);
907 return true;
908 }
909
910 /* bsr rs */
911 static bool trans_BSR_l(DisasContext *ctx, arg_BSR_l *a)
912 {
913 prt("bsr.l\tr%d", a->rd);
914 return true;
915 }
916
917 /* rts */
918 static bool trans_RTS(DisasContext *ctx, arg_RTS *a)
919 {
920 prt("rts");
921 return true;
922 }
923
924 /* nop */
925 static bool trans_NOP(DisasContext *ctx, arg_NOP *a)
926 {
927 prt("nop");
928 return true;
929 }
930
931 /* scmpu */
932 static bool trans_SCMPU(DisasContext *ctx, arg_SCMPU *a)
933 {
934 prt("scmpu");
935 return true;
936 }
937
938 /* smovu */
939 static bool trans_SMOVU(DisasContext *ctx, arg_SMOVU *a)
940 {
941 prt("smovu");
942 return true;
943 }
944
945 /* smovf */
946 static bool trans_SMOVF(DisasContext *ctx, arg_SMOVF *a)
947 {
948 prt("smovf");
949 return true;
950 }
951
952 /* smovb */
953 static bool trans_SMOVB(DisasContext *ctx, arg_SMOVB *a)
954 {
955 prt("smovb");
956 return true;
957 }
958
959 /* suntile */
960 static bool trans_SUNTIL(DisasContext *ctx, arg_SUNTIL *a)
961 {
962 prt("suntil.%c", size[a->sz]);
963 return true;
964 }
965
966 /* swhile */
967 static bool trans_SWHILE(DisasContext *ctx, arg_SWHILE *a)
968 {
969 prt("swhile.%c", size[a->sz]);
970 return true;
971 }
972 /* sstr */
973 static bool trans_SSTR(DisasContext *ctx, arg_SSTR *a)
974 {
975 prt("sstr.%c", size[a->sz]);
976 return true;
977 }
978
979 /* rmpa */
980 static bool trans_RMPA(DisasContext *ctx, arg_RMPA *a)
981 {
982 prt("rmpa.%c", size[a->sz]);
983 return true;
984 }
985
986 /* mulhi rs,rs2 */
987 static bool trans_MULHI(DisasContext *ctx, arg_MULHI *a)
988 {
989 prt("mulhi\tr%d,r%d", a->rs, a->rs2);
990 return true;
991 }
992
993 /* mullo rs,rs2 */
994 static bool trans_MULLO(DisasContext *ctx, arg_MULLO *a)
995 {
996 prt("mullo\tr%d, r%d", a->rs, a->rs2);
997 return true;
998 }
999
1000 /* machi rs,rs2 */
1001 static bool trans_MACHI(DisasContext *ctx, arg_MACHI *a)
1002 {
1003 prt("machi\tr%d, r%d", a->rs, a->rs2);
1004 return true;
1005 }
1006
1007 /* maclo rs,rs2 */
1008 static bool trans_MACLO(DisasContext *ctx, arg_MACLO *a)
1009 {
1010 prt("maclo\tr%d, r%d", a->rs, a->rs2);
1011 return true;
1012 }
1013
1014 /* mvfachi rd */
1015 static bool trans_MVFACHI(DisasContext *ctx, arg_MVFACHI *a)
1016 {
1017 prt("mvfachi\tr%d", a->rd);
1018 return true;
1019 }
1020
1021 /* mvfacmi rd */
1022 static bool trans_MVFACMI(DisasContext *ctx, arg_MVFACMI *a)
1023 {
1024 prt("mvfacmi\tr%d", a->rd);
1025 return true;
1026 }
1027
1028 /* mvtachi rs */
1029 static bool trans_MVTACHI(DisasContext *ctx, arg_MVTACHI *a)
1030 {
1031 prt("mvtachi\tr%d", a->rs);
1032 return true;
1033 }
1034
1035 /* mvtaclo rs */
1036 static bool trans_MVTACLO(DisasContext *ctx, arg_MVTACLO *a)
1037 {
1038 prt("mvtaclo\tr%d", a->rs);
1039 return true;
1040 }
1041
1042 /* racw #imm */
1043 static bool trans_RACW(DisasContext *ctx, arg_RACW *a)
1044 {
1045 prt("racw\t#%d", a->imm + 1);
1046 return true;
1047 }
1048
1049 /* sat rd */
1050 static bool trans_SAT(DisasContext *ctx, arg_SAT *a)
1051 {
1052 prt("sat\tr%d", a->rd);
1053 return true;
1054 }
1055
1056 /* satr */
1057 static bool trans_SATR(DisasContext *ctx, arg_SATR *a)
1058 {
1059 prt("satr");
1060 return true;
1061 }
1062
1063 /* fadd #imm, rd */
1064 static bool trans_FADD_ir(DisasContext *ctx, arg_FADD_ir *a)
1065 {
1066 prt("fadd\t#%d,r%d", li(ctx, 0), a->rd);
1067 return true;
1068 }
1069
1070 /* fadd dsp[rs], rd */
1071 /* fadd rs, rd */
1072 static bool trans_FADD_mr(DisasContext *ctx, arg_FADD_mr *a)
1073 {
1074 prt_ldmi(ctx, "fadd", a->ld, RX_IM_LONG, a->rs, a->rd);
1075 return true;
1076 }
1077
1078 /* fcmp #imm, rd */
1079 static bool trans_FCMP_ir(DisasContext *ctx, arg_FCMP_ir *a)
1080 {
1081 prt("fadd\t#%d,r%d", li(ctx, 0), a->rd);
1082 return true;
1083 }
1084
1085 /* fcmp dsp[rs], rd */
1086 /* fcmp rs, rd */
1087 static bool trans_FCMP_mr(DisasContext *ctx, arg_FCMP_mr *a)
1088 {
1089 prt_ldmi(ctx, "fcmp", a->ld, RX_IM_LONG, a->rs, a->rd);
1090 return true;
1091 }
1092
1093 /* fsub #imm, rd */
1094 static bool trans_FSUB_ir(DisasContext *ctx, arg_FSUB_ir *a)
1095 {
1096 prt("fsub\t#%d,r%d", li(ctx, 0), a->rd);
1097 return true;
1098 }
1099
1100 /* fsub dsp[rs], rd */
1101 /* fsub rs, rd */
1102 static bool trans_FSUB_mr(DisasContext *ctx, arg_FSUB_mr *a)
1103 {
1104 prt_ldmi(ctx, "fsub", a->ld, RX_IM_LONG, a->rs, a->rd);
1105 return true;
1106 }
1107
1108 /* ftoi dsp[rs], rd */
1109 /* ftoi rs, rd */
1110 static bool trans_FTOI(DisasContext *ctx, arg_FTOI *a)
1111 {
1112 prt_ldmi(ctx, "ftoi", a->ld, RX_IM_LONG, a->rs, a->rd);
1113 return true;
1114 }
1115
1116 /* fmul #imm, rd */
1117 static bool trans_FMUL_ir(DisasContext *ctx, arg_FMUL_ir *a)
1118 {
1119 prt("fmul\t#%d,r%d", li(ctx, 0), a->rd);
1120 return true;
1121 }
1122
1123 /* fmul dsp[rs], rd */
1124 /* fmul rs, rd */
1125 static bool trans_FMUL_mr(DisasContext *ctx, arg_FMUL_mr *a)
1126 {
1127 prt_ldmi(ctx, "fmul", a->ld, RX_IM_LONG, a->rs, a->rd);
1128 return true;
1129 }
1130
1131 /* fdiv #imm, rd */
1132 static bool trans_FDIV_ir(DisasContext *ctx, arg_FDIV_ir *a)
1133 {
1134 prt("fdiv\t#%d,r%d", li(ctx, 0), a->rd);
1135 return true;
1136 }
1137
1138 /* fdiv dsp[rs], rd */
1139 /* fdiv rs, rd */
1140 static bool trans_FDIV_mr(DisasContext *ctx, arg_FDIV_mr *a)
1141 {
1142 prt_ldmi(ctx, "fdiv", a->ld, RX_IM_LONG, a->rs, a->rd);
1143 return true;
1144 }
1145
1146 /* round dsp[rs], rd */
1147 /* round rs, rd */
1148 static bool trans_ROUND(DisasContext *ctx, arg_ROUND *a)
1149 {
1150 prt_ldmi(ctx, "round", a->ld, RX_IM_LONG, a->rs, a->rd);
1151 return true;
1152 }
1153
1154 /* itof rs, rd */
1155 /* itof dsp[rs], rd */
1156 static bool trans_ITOF(DisasContext *ctx, arg_ITOF *a)
1157 {
1158 prt_ldmi(ctx, "itof", a->ld, RX_IM_LONG, a->rs, a->rd);
1159 return true;
1160 }
1161
1162 #define BOP_IM(name, reg) \
1163 do { \
1164 char dsp[8]; \
1165 rx_index_addr(ctx, dsp, a->ld, RX_MEMORY_BYTE); \
1166 prt("b%s\t#%d, %s[r%d]", #name, a->imm, dsp, reg); \
1167 return true; \
1168 } while (0)
1169
1170 #define BOP_RM(name) \
1171 do { \
1172 char dsp[8]; \
1173 rx_index_addr(ctx, dsp, a->ld, RX_MEMORY_BYTE); \
1174 prt("b%s\tr%d, %s[r%d]", #name, a->rd, dsp, a->rs); \
1175 return true; \
1176 } while (0)
1177
1178 /* bset #imm, dsp[rd] */
1179 static bool trans_BSET_im(DisasContext *ctx, arg_BSET_im *a)
1180 {
1181 BOP_IM(bset, a->rs);
1182 }
1183
1184 /* bset rs, dsp[rd] */
1185 static bool trans_BSET_rm(DisasContext *ctx, arg_BSET_rm *a)
1186 {
1187 BOP_RM(set);
1188 }
1189
1190 /* bset rs, rd */
1191 static bool trans_BSET_rr(DisasContext *ctx, arg_BSET_rr *a)
1192 {
1193 prt("bset\tr%d,r%d", a->rs, a->rd);
1194 return true;
1195 }
1196
1197 /* bset #imm, rd */
1198 static bool trans_BSET_ir(DisasContext *ctx, arg_BSET_ir *a)
1199 {
1200 prt("bset\t#%d, r%d", a->imm, a->rd);
1201 return true;
1202 }
1203
1204 /* bclr #imm, dsp[rd] */
1205 static bool trans_BCLR_im(DisasContext *ctx, arg_BCLR_im *a)
1206 {
1207 BOP_IM(clr, a->rs);
1208 }
1209
1210 /* bclr rs, dsp[rd] */
1211 static bool trans_BCLR_rm(DisasContext *ctx, arg_BCLR_rm *a)
1212 {
1213 BOP_RM(clr);
1214 }
1215
1216 /* bclr rs, rd */
1217 static bool trans_BCLR_rr(DisasContext *ctx, arg_BCLR_rr *a)
1218 {
1219 prt("bclr\tr%d, r%d", a->rs, a->rd);
1220 return true;
1221 }
1222
1223 /* bclr #imm, rd */
1224 static bool trans_BCLR_ir(DisasContext *ctx, arg_BCLR_ir *a)
1225 {
1226 prt("bclr\t#%d,r%d", a->imm, a->rd);
1227 return true;
1228 }
1229
1230 /* btst #imm, dsp[rd] */
1231 static bool trans_BTST_im(DisasContext *ctx, arg_BTST_im *a)
1232 {
1233 BOP_IM(tst, a->rs);
1234 }
1235
1236 /* btst rs, dsp[rd] */
1237 static bool trans_BTST_rm(DisasContext *ctx, arg_BTST_rm *a)
1238 {
1239 BOP_RM(tst);
1240 }
1241
1242 /* btst rs, rd */
1243 static bool trans_BTST_rr(DisasContext *ctx, arg_BTST_rr *a)
1244 {
1245 prt("btst\tr%d, r%d", a->rs, a->rd);
1246 return true;
1247 }
1248
1249 /* btst #imm, rd */
1250 static bool trans_BTST_ir(DisasContext *ctx, arg_BTST_ir *a)
1251 {
1252 prt("btst\t#%d, r%d", a->imm, a->rd);
1253 return true;
1254 }
1255
1256 /* bnot rs, dsp[rd] */
1257 static bool trans_BNOT_rm(DisasContext *ctx, arg_BNOT_rm *a)
1258 {
1259 BOP_RM(not);
1260 }
1261
1262 /* bnot rs, rd */
1263 static bool trans_BNOT_rr(DisasContext *ctx, arg_BNOT_rr *a)
1264 {
1265 prt("bnot\tr%d, r%d", a->rs, a->rd);
1266 return true;
1267 }
1268
1269 /* bnot #imm, dsp[rd] */
1270 static bool trans_BNOT_im(DisasContext *ctx, arg_BNOT_im *a)
1271 {
1272 BOP_IM(not, a->rs);
1273 }
1274
1275 /* bnot #imm, rd */
1276 static bool trans_BNOT_ir(DisasContext *ctx, arg_BNOT_ir *a)
1277 {
1278 prt("bnot\t#%d, r%d", a->imm, a->rd);
1279 return true;
1280 }
1281
1282 /* bmcond #imm, dsp[rd] */
1283 static bool trans_BMCnd_im(DisasContext *ctx, arg_BMCnd_im *a)
1284 {
1285 char dsp[8];
1286
1287 rx_index_addr(ctx, dsp, a->ld, RX_MEMORY_BYTE);
1288 prt("bm%s\t#%d, %s[r%d]", cond[a->cd], a->imm, dsp, a->rd);
1289 return true;
1290 }
1291
1292 /* bmcond #imm, rd */
1293 static bool trans_BMCnd_ir(DisasContext *ctx, arg_BMCnd_ir *a)
1294 {
1295 prt("bm%s\t#%d, r%d", cond[a->cd], a->imm, a->rd);
1296 return true;
1297 }
1298
1299 /* clrpsw psw */
1300 static bool trans_CLRPSW(DisasContext *ctx, arg_CLRPSW *a)
1301 {
1302 prt("clrpsw\t%c", psw[a->cb]);
1303 return true;
1304 }
1305
1306 /* setpsw psw */
1307 static bool trans_SETPSW(DisasContext *ctx, arg_SETPSW *a)
1308 {
1309 prt("setpsw\t%c", psw[a->cb]);
1310 return true;
1311 }
1312
1313 /* mvtipl #imm */
1314 static bool trans_MVTIPL(DisasContext *ctx, arg_MVTIPL *a)
1315 {
1316 prt("movtipl\t#%d", a->imm);
1317 return true;
1318 }
1319
1320 /* mvtc #imm, rd */
1321 static bool trans_MVTC_i(DisasContext *ctx, arg_MVTC_i *a)
1322 {
1323 prt("mvtc\t#0x%08x, %s", a->imm, rx_crname(a->cr));
1324 return true;
1325 }
1326
1327 /* mvtc rs, rd */
1328 static bool trans_MVTC_r(DisasContext *ctx, arg_MVTC_r *a)
1329 {
1330 prt("mvtc\tr%d, %s", a->rs, rx_crname(a->cr));
1331 return true;
1332 }
1333
1334 /* mvfc rs, rd */
1335 static bool trans_MVFC(DisasContext *ctx, arg_MVFC *a)
1336 {
1337 prt("mvfc\t%s, r%d", rx_crname(a->cr), a->rd);
1338 return true;
1339 }
1340
1341 /* rtfi */
1342 static bool trans_RTFI(DisasContext *ctx, arg_RTFI *a)
1343 {
1344 prt("rtfi");
1345 return true;
1346 }
1347
1348 /* rte */
1349 static bool trans_RTE(DisasContext *ctx, arg_RTE *a)
1350 {
1351 prt("rte");
1352 return true;
1353 }
1354
1355 /* brk */
1356 static bool trans_BRK(DisasContext *ctx, arg_BRK *a)
1357 {
1358 prt("brk");
1359 return true;
1360 }
1361
1362 /* int #imm */
1363 static bool trans_INT(DisasContext *ctx, arg_INT *a)
1364 {
1365 prt("int\t#%d", a->imm);
1366 return true;
1367 }
1368
1369 /* wait */
1370 static bool trans_WAIT(DisasContext *ctx, arg_WAIT *a)
1371 {
1372 prt("wait");
1373 return true;
1374 }
1375
1376 /* sccnd.[bwl] rd */
1377 /* sccnd.[bwl] dsp:[rd] */
1378 static bool trans_SCCnd(DisasContext *ctx, arg_SCCnd *a)
1379 {
1380 if (a->ld < 3) {
1381 char dsp[8];
1382 rx_index_addr(ctx, dsp, a->sz, a->ld);
1383 prt("sc%s.%c\t%s[r%d]", cond[a->cd], size[a->sz], dsp, a->rd);
1384 } else {
1385 prt("sc%s.%c\tr%d", cond[a->cd], size[a->sz], a->rd);
1386 }
1387 return true;
1388 }
1389
1390 int print_insn_rx(bfd_vma addr, disassemble_info *dis)
1391 {
1392 DisasContext ctx;
1393 uint32_t insn;
1394 int i;
1395 ctx.dis = dis;
1396 ctx.pc = ctx.addr = addr;
1397
1398 insn = decode_load(&ctx);
1399 if (!decode(&ctx, insn)) {
1400 ctx.dis->fprintf_func(ctx.dis->stream, ".byte\t");
1401 for (i = 0; i < ctx.addr - addr; i++) {
1402 if (i > 0) {
1403 ctx.dis->fprintf_func(ctx.dis->stream, ",");
1404 }
1405 ctx.dis->fprintf_func(ctx.dis->stream, "0x%02x", insn >> 24);
1406 insn <<= 8;
1407 }
1408 }
1409 return ctx.addr - addr;
1410 }