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