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