2 * Renesas RX Disassembler
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.
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
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/>.
19 #include "qemu/osdep.h"
20 #include "disas/dis-asm.h"
21 #include "qemu/bitops.h"
24 typedef struct DisasContext {
25 disassemble_info *dis;
33 static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
36 uint32_t addr = ctx->addr;
38 g_assert(ctx->len == i);
39 g_assert(n <= ARRAY_SIZE(ctx->bytes));
42 ctx->dis->read_memory_func(addr++, &ctx->bytes[i - 1], 1, ctx->dis);
43 insn |= ctx->bytes[i - 1] << (32 - i * 8);
51 static int32_t li(DisasContext *ctx, int sz)
53 uint32_t addr = ctx->addr;
54 uintptr_t len = ctx->len;
58 g_assert(len + 1 <= ARRAY_SIZE(ctx->bytes));
61 ctx->dis->read_memory_func(addr, ctx->bytes + len, 1, ctx->dis);
62 return (int8_t)ctx->bytes[len];
64 g_assert(len + 2 <= ARRAY_SIZE(ctx->bytes));
67 ctx->dis->read_memory_func(addr, ctx->bytes + len, 2, ctx->dis);
68 return ldsw_le_p(ctx->bytes + len);
70 g_assert(len + 3 <= ARRAY_SIZE(ctx->bytes));
73 ctx->dis->read_memory_func(addr, ctx->bytes + len, 3, ctx->dis);
74 return (int8_t)ctx->bytes[len + 2] << 16 | lduw_le_p(ctx->bytes + len);
76 g_assert(len + 4 <= ARRAY_SIZE(ctx->bytes));
79 ctx->dis->read_memory_func(addr, ctx->bytes + len, 4, ctx->dis);
80 return ldl_le_p(ctx->bytes + len);
82 g_assert_not_reached();
86 static int bdsp_s(DisasContext *ctx, int d)
102 /* Include the auto-generated decoder. */
103 #include "decode-insns.c.inc"
105 static void dump_bytes(DisasContext *ctx)
107 int i, len = ctx->len;
109 for (i = 0; i < len; ++i) {
110 ctx->dis->fprintf_func(ctx->dis->stream, "%02x ", ctx->bytes[i]);
112 ctx->dis->fprintf_func(ctx->dis->stream, "%*c", (8 - i) * 3, '\t');
118 ctx->dis->fprintf_func(ctx->dis->stream, __VA_ARGS__); \
121 #define RX_MEMORY_BYTE 0
122 #define RX_MEMORY_WORD 1
123 #define RX_MEMORY_LONG 2
128 #define RX_IM_UWORD 3
130 static const char size[] = {'b', 'w', 'l'};
131 static const char cond[][4] = {
132 "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
133 "ge", "lt", "gt", "le", "o", "no", "ra", "f"
135 static const char psw[] = {
136 'c', 'z', 's', 'o', 0, 0, 0, 0,
137 'i', 'u', 0, 0, 0, 0, 0, 0,
140 static void rx_index_addr(DisasContext *ctx, char out[8], int ld, int mi)
142 uint32_t addr = ctx->addr;
143 uintptr_t len = ctx->len;
148 /* No index; return empty string. */
152 g_assert(len + 1 <= ARRAY_SIZE(ctx->bytes));
155 ctx->dis->read_memory_func(addr, ctx->bytes + len, 1, ctx->dis);
156 dsp = ctx->bytes[len];
159 g_assert(len + 2 <= ARRAY_SIZE(ctx->bytes));
162 ctx->dis->read_memory_func(addr, ctx->bytes + len, 2, ctx->dis);
163 dsp = lduw_le_p(ctx->bytes + len);
166 g_assert_not_reached();
169 sprintf(out, "%u", dsp << (mi < 3 ? mi : 4 - mi));
172 static void prt_ldmi(DisasContext *ctx, const char *insn,
173 int ld, int mi, int rs, int rd)
175 static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"};
179 rx_index_addr(ctx, dsp, ld, mi);
180 prt("%s\t%s[r%d]%s, r%d", insn, dsp, rs, sizes[mi], rd);
182 prt("%s\tr%d, r%d", insn, rs, rd);
186 static void prt_ir(DisasContext *ctx, const char *insn, int imm, int rd)
189 prt("%s\t#%d, r%d", insn, imm, rd);
191 prt("%s\t#0x%08x, r%d", insn, imm, rd);
195 /* mov.[bwl] rs,dsp:[rd] */
196 static bool trans_MOV_rm(DisasContext *ctx, arg_MOV_rm *a)
199 prt("mov.%c\tr%d,%d[r%d]",
200 size[a->sz], a->rs, a->dsp << a->sz, a->rd);
202 prt("mov.%c\tr%d,[r%d]",
203 size[a->sz], a->rs, a->rd);
208 /* mov.[bwl] dsp:[rs],rd */
209 static bool trans_MOV_mr(DisasContext *ctx, arg_MOV_mr *a)
212 prt("mov.%c\t%d[r%d], r%d",
213 size[a->sz], a->dsp << a->sz, a->rs, a->rd);
215 prt("mov.%c\t[r%d], r%d",
216 size[a->sz], a->rs, a->rd);
221 /* mov.l #uimm4,rd */
222 /* mov.l #uimm8,rd */
224 static bool trans_MOV_ir(DisasContext *ctx, arg_MOV_ir *a)
226 prt_ir(ctx, "mov.l", a->imm, a->rd);
230 /* mov.[bwl] #uimm8,dsp:[rd] */
231 /* mov #imm, dsp:[rd] */
232 static bool trans_MOV_im(DisasContext *ctx, arg_MOV_im *a)
235 prt("mov.%c\t#%d,%d[r%d]",
236 size[a->sz], a->imm, a->dsp << a->sz, a->rd);
238 prt("mov.%c\t#%d,[r%d]",
239 size[a->sz], a->imm, a->rd);
244 /* mov.[bwl] [ri,rb],rd */
245 static bool trans_MOV_ar(DisasContext *ctx, arg_MOV_ar *a)
247 prt("mov.%c\t[r%d,r%d], r%d", size[a->sz], a->ri, a->rb, a->rd);
251 /* mov.[bwl] rd,[ri,rb] */
252 static bool trans_MOV_ra(DisasContext *ctx, arg_MOV_ra *a)
254 prt("mov.%c\tr%d, [r%d, r%d]", size[a->sz], a->rs, a->ri, a->rb);
259 /* mov.[bwl] dsp:[rs],dsp:[rd] */
260 /* mov.[bwl] rs,dsp:[rd] */
261 /* mov.[bwl] dsp:[rs],rd */
262 /* mov.[bwl] rs,rd */
263 static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
265 char dspd[8], dsps[8], szc = size[a->sz];
267 if (a->lds == 3 && a->ldd == 3) {
268 /* mov.[bwl] rs,rd */
269 prt("mov.%c\tr%d, r%d", szc, a->rs, a->rd);
270 } else if (a->lds == 3) {
271 rx_index_addr(ctx, dspd, a->ldd, a->sz);
272 prt("mov.%c\tr%d, %s[r%d]", szc, a->rs, dspd, a->rd);
273 } else if (a->ldd == 3) {
274 rx_index_addr(ctx, dsps, a->lds, a->sz);
275 prt("mov.%c\t%s[r%d], r%d", szc, dsps, a->rs, a->rd);
277 rx_index_addr(ctx, dsps, a->lds, a->sz);
278 rx_index_addr(ctx, dspd, a->ldd, a->sz);
279 prt("mov.%c\t%s[r%d], %s[r%d]", szc, dsps, a->rs, dspd, a->rd);
284 /* mov.[bwl] rs,[rd+] */
285 /* mov.[bwl] rs,[-rd] */
286 static bool trans_MOV_rp(DisasContext *ctx, arg_MOV_rp *a)
289 prt("mov.%c\tr%d, [-r%d]", size[a->sz], a->rs, a->rd);
291 prt("mov.%c\tr%d, [r%d+]", size[a->sz], a->rs, a->rd);
296 /* mov.[bwl] [rd+],rs */
297 /* mov.[bwl] [-rd],rs */
298 static bool trans_MOV_pr(DisasContext *ctx, arg_MOV_pr *a)
301 prt("mov.%c\t[-r%d], r%d", size[a->sz], a->rd, a->rs);
303 prt("mov.%c\t[r%d+], r%d", size[a->sz], a->rd, a->rs);
308 /* movu.[bw] dsp5:[rs],rd */
309 static bool trans_MOVU_mr(DisasContext *ctx, arg_MOVU_mr *a)
312 prt("movu.%c\t%d[r%d], r%d", size[a->sz],
313 a->dsp << a->sz, a->rs, a->rd);
315 prt("movu.%c\t[r%d], r%d", size[a->sz], a->rs, a->rd);
320 /* movu.[bw] rs,rd */
321 static bool trans_MOVU_rr(DisasContext *ctx, arg_MOVU_rr *a)
323 prt("movu.%c\tr%d, r%d", size[a->sz], a->rs, a->rd);
327 /* movu.[bw] [ri,rb],rd */
328 static bool trans_MOVU_ar(DisasContext *ctx, arg_MOVU_ar *a)
330 prt("mov.%c\t[r%d,r%d], r%d", size[a->sz], a->ri, a->rb, a->rd);
334 /* movu.[bw] [rs+],rd */
335 /* movu.[bw] [-rs],rd */
336 static bool trans_MOVU_pr(DisasContext *ctx, arg_MOVU_pr *a)
339 prt("movu.%c\t[-r%d], r%d", size[a->sz], a->rd, a->rs);
341 prt("movu.%c\t[r%d+], r%d", size[a->sz], a->rd, a->rs);
347 static bool trans_POP(DisasContext *ctx, arg_POP *a)
349 prt("pop\tr%d", a->rd);
354 static bool trans_POPC(DisasContext *ctx, arg_POPC *a)
356 prt("pop\tr%s", rx_crname(a->cr));
361 static bool trans_POPM(DisasContext *ctx, arg_POPM *a)
363 prt("popm\tr%d-r%d", a->rd, a->rd2);
368 static bool trans_PUSH_r(DisasContext *ctx, arg_PUSH_r *a)
370 prt("push\tr%d", a->rs);
375 static bool trans_PUSH_m(DisasContext *ctx, arg_PUSH_m *a)
379 rx_index_addr(ctx, dsp, a->ld, a->sz);
380 prt("push\t%s[r%d]", dsp, a->rs);
385 static bool trans_PUSHC(DisasContext *ctx, arg_PUSHC *a)
387 prt("push\t%s", rx_crname(a->cr));
392 static bool trans_PUSHM(DisasContext *ctx, arg_PUSHM *a)
394 prt("pushm\tr%d-r%d", a->rs, a->rs2);
399 static bool trans_XCHG_rr(DisasContext *ctx, arg_XCHG_rr *a)
401 prt("xchg\tr%d, r%d", a->rs, a->rd);
404 /* xchg dsp[rs].<mi>,rd */
405 static bool trans_XCHG_mr(DisasContext *ctx, arg_XCHG_mr *a)
407 prt_ldmi(ctx, "xchg", a->ld, a->mi, a->rs, a->rd);
412 static bool trans_STZ(DisasContext *ctx, arg_STZ *a)
414 prt_ir(ctx, "stz", a->imm, a->rd);
419 static bool trans_STNZ(DisasContext *ctx, arg_STNZ *a)
421 prt_ir(ctx, "stnz", a->imm, a->rd);
426 static bool trans_RTSD_i(DisasContext *ctx, arg_RTSD_i *a)
428 prt("rtsd\t#%d", a->imm << 2);
432 /* rtsd #imm, rd-rd2 */
433 static bool trans_RTSD_irr(DisasContext *ctx, arg_RTSD_irr *a)
435 prt("rtsd\t#%d, r%d - r%d", a->imm << 2, a->rd, a->rd2);
439 /* and #uimm:4, rd */
441 static bool trans_AND_ir(DisasContext *ctx, arg_AND_ir *a)
443 prt_ir(ctx, "and", a->imm, a->rd);
447 /* and dsp[rs], rd */
449 static bool trans_AND_mr(DisasContext *ctx, arg_AND_mr *a)
451 prt_ldmi(ctx, "and", a->ld, a->mi, a->rs, a->rd);
456 static bool trans_AND_rrr(DisasContext *ctx, arg_AND_rrr *a)
458 prt("and\tr%d,r%d, r%d", a->rs, a->rs2, a->rd);
464 static bool trans_OR_ir(DisasContext *ctx, arg_OR_ir *a)
466 prt_ir(ctx, "or", a->imm, a->rd);
472 static bool trans_OR_mr(DisasContext *ctx, arg_OR_mr *a)
474 prt_ldmi(ctx, "or", a->ld, a->mi, a->rs, a->rd);
479 static bool trans_OR_rrr(DisasContext *ctx, arg_OR_rrr *a)
481 prt("or\tr%d, r%d, r%d", a->rs, a->rs2, a->rd);
486 static bool trans_XOR_ir(DisasContext *ctx, arg_XOR_ir *a)
488 prt_ir(ctx, "xor", a->imm, a->rd);
492 /* xor dsp[rs], rd */
494 static bool trans_XOR_mr(DisasContext *ctx, arg_XOR_mr *a)
496 prt_ldmi(ctx, "xor", a->ld, a->mi, a->rs, a->rd);
501 static bool trans_TST_ir(DisasContext *ctx, arg_TST_ir *a)
503 prt_ir(ctx, "tst", a->imm, a->rd);
507 /* tst dsp[rs], rd */
509 static bool trans_TST_mr(DisasContext *ctx, arg_TST_mr *a)
511 prt_ldmi(ctx, "tst", a->ld, a->mi, a->rs, a->rd);
517 static bool trans_NOT_rr(DisasContext *ctx, arg_NOT_rr *a)
519 if (a->rs != a->rd) {
520 prt("not\tr%d, r%d", a->rs, a->rd);
522 prt("not\tr%d", a->rs);
529 static bool trans_NEG_rr(DisasContext *ctx, arg_NEG_rr *a)
531 if (a->rs != a->rd) {
532 prt("neg\tr%d, r%d", a->rs, a->rd);
534 prt("neg\tr%d", a->rs);
540 static bool trans_ADC_ir(DisasContext *ctx, arg_ADC_ir *a)
542 prt_ir(ctx, "adc", a->imm, a->rd);
547 static bool trans_ADC_rr(DisasContext *ctx, arg_ADC_rr *a)
549 prt("adc\tr%d, r%d", a->rs, a->rd);
553 /* adc dsp[rs], rd */
554 static bool trans_ADC_mr(DisasContext *ctx, arg_ADC_mr *a)
558 rx_index_addr(ctx, dsp, a->ld, 2);
559 prt("adc\t%s[r%d], r%d", dsp, a->rs, a->rd);
564 /* add #imm, rs, rd */
565 static bool trans_ADD_irr(DisasContext *ctx, arg_ADD_irr *a)
567 if (a->imm < 0x10 && a->rs2 == a->rd) {
568 prt("add\t#%d, r%d", a->imm, a->rd);
570 prt("add\t#0x%08x, r%d, r%d", a->imm, a->rs2, a->rd);
576 /* add dsp[rs], rd */
577 static bool trans_ADD_mr(DisasContext *ctx, arg_ADD_mr *a)
579 prt_ldmi(ctx, "add", a->ld, a->mi, a->rs, a->rd);
583 /* add rs, rs2, rd */
584 static bool trans_ADD_rrr(DisasContext *ctx, arg_ADD_rrr *a)
586 prt("add\tr%d, r%d, r%d", a->rs, a->rs2, a->rd);
593 static bool trans_CMP_ir(DisasContext *ctx, arg_CMP_ir *a)
595 prt_ir(ctx, "cmp", a->imm, a->rs2);
600 /* cmp dsp[rs], rs2 */
601 static bool trans_CMP_mr(DisasContext *ctx, arg_CMP_mr *a)
603 prt_ldmi(ctx, "cmp", a->ld, a->mi, a->rs, a->rd);
608 static bool trans_SUB_ir(DisasContext *ctx, arg_SUB_ir *a)
610 prt("sub\t#%d, r%d", a->imm, a->rd);
615 /* sub dsp[rs], rd */
616 static bool trans_SUB_mr(DisasContext *ctx, arg_SUB_mr *a)
618 prt_ldmi(ctx, "sub", a->ld, a->mi, a->rs, a->rd);
622 /* sub rs, rs2, rd */
623 static bool trans_SUB_rrr(DisasContext *ctx, arg_SUB_rrr *a)
625 prt("sub\tr%d, r%d, r%d", a->rs, a->rs2, a->rd);
630 static bool trans_SBB_rr(DisasContext *ctx, arg_SBB_rr *a)
632 prt("sbb\tr%d, r%d", a->rs, a->rd);
636 /* sbb dsp[rs], rd */
637 static bool trans_SBB_mr(DisasContext *ctx, arg_SBB_mr *a)
639 prt_ldmi(ctx, "sbb", a->ld, RX_IM_LONG, a->rs, a->rd);
645 static bool trans_ABS_rr(DisasContext *ctx, arg_ABS_rr *a)
647 if (a->rs != a->rd) {
648 prt("abs\tr%d, r%d", a->rs, a->rd);
650 prt("abs\tr%d", a->rs);
656 static bool trans_MAX_ir(DisasContext *ctx, arg_MAX_ir *a)
658 prt_ir(ctx, "max", a->imm, a->rd);
663 /* max dsp[rs], rd */
664 static bool trans_MAX_mr(DisasContext *ctx, arg_MAX_mr *a)
666 prt_ldmi(ctx, "max", a->ld, a->mi, a->rs, a->rd);
671 static bool trans_MIN_ir(DisasContext *ctx, arg_MIN_ir *a)
673 prt_ir(ctx, "min", a->imm, a->rd);
678 /* min dsp[rs], rd */
679 static bool trans_MIN_mr(DisasContext *ctx, arg_MIN_mr *a)
681 prt_ldmi(ctx, "min", a->ld, a->mi, a->rs, a->rd);
687 static bool trans_MUL_ir(DisasContext *ctx, arg_MUL_ir *a)
689 prt_ir(ctx, "mul", a->imm, a->rd);
694 /* mul dsp[rs], rd */
695 static bool trans_MUL_mr(DisasContext *ctx, arg_MUL_mr *a)
697 prt_ldmi(ctx, "mul", a->ld, a->mi, a->rs, a->rd);
701 /* mul rs, rs2, rd */
702 static bool trans_MUL_rrr(DisasContext *ctx, arg_MUL_rrr *a)
704 prt("mul\tr%d,r%d,r%d", a->rs, a->rs2, a->rd);
709 static bool trans_EMUL_ir(DisasContext *ctx, arg_EMUL_ir *a)
711 prt_ir(ctx, "emul", a->imm, a->rd);
716 /* emul dsp[rs], rd */
717 static bool trans_EMUL_mr(DisasContext *ctx, arg_EMUL_mr *a)
719 prt_ldmi(ctx, "emul", a->ld, a->mi, a->rs, a->rd);
724 static bool trans_EMULU_ir(DisasContext *ctx, arg_EMULU_ir *a)
726 prt_ir(ctx, "emulu", a->imm, a->rd);
731 /* emulu dsp[rs], rd */
732 static bool trans_EMULU_mr(DisasContext *ctx, arg_EMULU_mr *a)
734 prt_ldmi(ctx, "emulu", a->ld, a->mi, a->rs, a->rd);
739 static bool trans_DIV_ir(DisasContext *ctx, arg_DIV_ir *a)
741 prt_ir(ctx, "div", a->imm, a->rd);
746 /* div dsp[rs], rd */
747 static bool trans_DIV_mr(DisasContext *ctx, arg_DIV_mr *a)
749 prt_ldmi(ctx, "div", a->ld, a->mi, a->rs, a->rd);
754 static bool trans_DIVU_ir(DisasContext *ctx, arg_DIVU_ir *a)
756 prt_ir(ctx, "divu", a->imm, a->rd);
761 /* divu dsp[rs], rd */
762 static bool trans_DIVU_mr(DisasContext *ctx, arg_DIVU_mr *a)
764 prt_ldmi(ctx, "divu", a->ld, a->mi, a->rs, a->rd);
769 /* shll #imm:5, rd */
770 /* shll #imm:5, rs, rd */
771 static bool trans_SHLL_irr(DisasContext *ctx, arg_SHLL_irr *a)
773 if (a->rs2 != a->rd) {
774 prt("shll\t#%d, r%d, r%d", a->imm, a->rs2, a->rd);
776 prt("shll\t#%d, r%d", a->imm, a->rd);
782 static bool trans_SHLL_rr(DisasContext *ctx, arg_SHLL_rr *a)
784 prt("shll\tr%d, r%d", a->rs, a->rd);
788 /* shar #imm:5, rd */
789 /* shar #imm:5, rs, rd */
790 static bool trans_SHAR_irr(DisasContext *ctx, arg_SHAR_irr *a)
792 if (a->rs2 != a->rd) {
793 prt("shar\t#%d, r%d, r%d", a->imm, a->rs2, a->rd);
795 prt("shar\t#%d, r%d", a->imm, a->rd);
801 static bool trans_SHAR_rr(DisasContext *ctx, arg_SHAR_rr *a)
803 prt("shar\tr%d, r%d", a->rs, a->rd);
807 /* shlr #imm:5, rd */
808 /* shlr #imm:5, rs, rd */
809 static bool trans_SHLR_irr(DisasContext *ctx, arg_SHLR_irr *a)
811 if (a->rs2 != a->rd) {
812 prt("shlr\t#%d, r%d, r%d", a->imm, a->rs2, a->rd);
814 prt("shlr\t#%d, r%d", a->imm, a->rd);
820 static bool trans_SHLR_rr(DisasContext *ctx, arg_SHLR_rr *a)
822 prt("shlr\tr%d, r%d", a->rs, a->rd);
827 static bool trans_ROLC(DisasContext *ctx, arg_ROLC *a)
829 prt("rorc\tr%d", a->rd);
834 static bool trans_RORC(DisasContext *ctx, arg_RORC *a)
836 prt("rorc\tr%d", a->rd);
841 static bool trans_ROTL_ir(DisasContext *ctx, arg_ROTL_ir *a)
843 prt("rotl\t#%d, r%d", a->imm, a->rd);
848 static bool trans_ROTL_rr(DisasContext *ctx, arg_ROTL_rr *a)
850 prt("rotl\tr%d, r%d", a->rs, a->rd);
855 static bool trans_ROTR_ir(DisasContext *ctx, arg_ROTR_ir *a)
857 prt("rotr\t#%d, r%d", a->imm, a->rd);
862 static bool trans_ROTR_rr(DisasContext *ctx, arg_ROTR_rr *a)
864 prt("rotr\tr%d, r%d", a->rs, a->rd);
869 static bool trans_REVL(DisasContext *ctx, arg_REVL *a)
871 prt("revl\tr%d, r%d", a->rs, a->rd);
876 static bool trans_REVW(DisasContext *ctx, arg_REVW *a)
878 prt("revw\tr%d, r%d", a->rs, a->rd);
882 /* conditional branch helper */
883 static void rx_bcnd_main(DisasContext *ctx, int cd, int len, int dst)
885 static const char sz[] = {'s', 'b', 'w', 'a'};
886 prt("b%s.%c\t%08x", cond[cd], sz[len - 1], ctx->pc + dst);
889 /* beq dsp:3 / bne dsp:3 */
890 /* beq dsp:8 / bne dsp:8 */
891 /* bc dsp:8 / bnc dsp:8 */
892 /* bgtu dsp:8 / bleu dsp:8 */
893 /* bpz dsp:8 / bn dsp:8 */
894 /* bge dsp:8 / blt dsp:8 */
895 /* bgt dsp:8 / ble dsp:8 */
896 /* bo dsp:8 / bno dsp:8 */
897 /* beq dsp:16 / bne dsp:16 */
898 static bool trans_BCnd(DisasContext *ctx, arg_BCnd *a)
900 rx_bcnd_main(ctx, a->cd, a->sz, a->dsp);
908 static bool trans_BRA(DisasContext *ctx, arg_BRA *a)
910 rx_bcnd_main(ctx, 14, a->sz, a->dsp);
915 static bool trans_BRA_l(DisasContext *ctx, arg_BRA_l *a)
917 prt("bra.l\tr%d", a->rd);
922 static bool trans_JMP(DisasContext *ctx, arg_JMP *a)
924 prt("jmp\tr%d", a->rs);
929 static bool trans_JSR(DisasContext *ctx, arg_JSR *a)
931 prt("jsr\tr%d", a->rs);
937 static bool trans_BSR(DisasContext *ctx, arg_BSR *a)
939 static const char sz[] = {'w', 'a'};
940 prt("bsr.%c\t%08x", sz[a->sz - 3], ctx->pc + a->dsp);
945 static bool trans_BSR_l(DisasContext *ctx, arg_BSR_l *a)
947 prt("bsr.l\tr%d", a->rd);
952 static bool trans_RTS(DisasContext *ctx, arg_RTS *a)
959 static bool trans_NOP(DisasContext *ctx, arg_NOP *a)
966 static bool trans_SCMPU(DisasContext *ctx, arg_SCMPU *a)
973 static bool trans_SMOVU(DisasContext *ctx, arg_SMOVU *a)
980 static bool trans_SMOVF(DisasContext *ctx, arg_SMOVF *a)
987 static bool trans_SMOVB(DisasContext *ctx, arg_SMOVB *a)
994 static bool trans_SUNTIL(DisasContext *ctx, arg_SUNTIL *a)
996 prt("suntil.%c", size[a->sz]);
1001 static bool trans_SWHILE(DisasContext *ctx, arg_SWHILE *a)
1003 prt("swhile.%c", size[a->sz]);
1007 static bool trans_SSTR(DisasContext *ctx, arg_SSTR *a)
1009 prt("sstr.%c", size[a->sz]);
1014 static bool trans_RMPA(DisasContext *ctx, arg_RMPA *a)
1016 prt("rmpa.%c", size[a->sz]);
1021 static bool trans_MULHI(DisasContext *ctx, arg_MULHI *a)
1023 prt("mulhi\tr%d,r%d", a->rs, a->rs2);
1028 static bool trans_MULLO(DisasContext *ctx, arg_MULLO *a)
1030 prt("mullo\tr%d, r%d", a->rs, a->rs2);
1035 static bool trans_MACHI(DisasContext *ctx, arg_MACHI *a)
1037 prt("machi\tr%d, r%d", a->rs, a->rs2);
1042 static bool trans_MACLO(DisasContext *ctx, arg_MACLO *a)
1044 prt("maclo\tr%d, r%d", a->rs, a->rs2);
1049 static bool trans_MVFACHI(DisasContext *ctx, arg_MVFACHI *a)
1051 prt("mvfachi\tr%d", a->rd);
1056 static bool trans_MVFACMI(DisasContext *ctx, arg_MVFACMI *a)
1058 prt("mvfacmi\tr%d", a->rd);
1063 static bool trans_MVTACHI(DisasContext *ctx, arg_MVTACHI *a)
1065 prt("mvtachi\tr%d", a->rs);
1070 static bool trans_MVTACLO(DisasContext *ctx, arg_MVTACLO *a)
1072 prt("mvtaclo\tr%d", a->rs);
1077 static bool trans_RACW(DisasContext *ctx, arg_RACW *a)
1079 prt("racw\t#%d", a->imm + 1);
1084 static bool trans_SAT(DisasContext *ctx, arg_SAT *a)
1086 prt("sat\tr%d", a->rd);
1091 static bool trans_SATR(DisasContext *ctx, arg_SATR *a)
1098 static bool trans_FADD_ir(DisasContext *ctx, arg_FADD_ir *a)
1100 prt("fadd\t#%d,r%d", li(ctx, 0), a->rd);
1104 /* fadd dsp[rs], rd */
1106 static bool trans_FADD_mr(DisasContext *ctx, arg_FADD_mr *a)
1108 prt_ldmi(ctx, "fadd", a->ld, RX_IM_LONG, a->rs, a->rd);
1113 static bool trans_FCMP_ir(DisasContext *ctx, arg_FCMP_ir *a)
1115 prt("fadd\t#%d,r%d", li(ctx, 0), a->rd);
1119 /* fcmp dsp[rs], rd */
1121 static bool trans_FCMP_mr(DisasContext *ctx, arg_FCMP_mr *a)
1123 prt_ldmi(ctx, "fcmp", a->ld, RX_IM_LONG, a->rs, a->rd);
1128 static bool trans_FSUB_ir(DisasContext *ctx, arg_FSUB_ir *a)
1130 prt("fsub\t#%d,r%d", li(ctx, 0), a->rd);
1134 /* fsub dsp[rs], rd */
1136 static bool trans_FSUB_mr(DisasContext *ctx, arg_FSUB_mr *a)
1138 prt_ldmi(ctx, "fsub", a->ld, RX_IM_LONG, a->rs, a->rd);
1142 /* ftoi dsp[rs], rd */
1144 static bool trans_FTOI(DisasContext *ctx, arg_FTOI *a)
1146 prt_ldmi(ctx, "ftoi", a->ld, RX_IM_LONG, a->rs, a->rd);
1151 static bool trans_FMUL_ir(DisasContext *ctx, arg_FMUL_ir *a)
1153 prt("fmul\t#%d,r%d", li(ctx, 0), a->rd);
1157 /* fmul dsp[rs], rd */
1159 static bool trans_FMUL_mr(DisasContext *ctx, arg_FMUL_mr *a)
1161 prt_ldmi(ctx, "fmul", a->ld, RX_IM_LONG, a->rs, a->rd);
1166 static bool trans_FDIV_ir(DisasContext *ctx, arg_FDIV_ir *a)
1168 prt("fdiv\t#%d,r%d", li(ctx, 0), a->rd);
1172 /* fdiv dsp[rs], rd */
1174 static bool trans_FDIV_mr(DisasContext *ctx, arg_FDIV_mr *a)
1176 prt_ldmi(ctx, "fdiv", a->ld, RX_IM_LONG, a->rs, a->rd);
1180 /* round dsp[rs], rd */
1182 static bool trans_ROUND(DisasContext *ctx, arg_ROUND *a)
1184 prt_ldmi(ctx, "round", a->ld, RX_IM_LONG, a->rs, a->rd);
1189 /* itof dsp[rs], rd */
1190 static bool trans_ITOF(DisasContext *ctx, arg_ITOF *a)
1192 prt_ldmi(ctx, "itof", a->ld, RX_IM_LONG, a->rs, a->rd);
1196 #define BOP_IM(name, reg) \
1199 rx_index_addr(ctx, dsp, a->ld, RX_MEMORY_BYTE); \
1200 prt("b%s\t#%d, %s[r%d]", #name, a->imm, dsp, reg); \
1204 #define BOP_RM(name) \
1207 rx_index_addr(ctx, dsp, a->ld, RX_MEMORY_BYTE); \
1208 prt("b%s\tr%d, %s[r%d]", #name, a->rd, dsp, a->rs); \
1212 /* bset #imm, dsp[rd] */
1213 static bool trans_BSET_im(DisasContext *ctx, arg_BSET_im *a)
1215 BOP_IM(bset, a->rs);
1218 /* bset rs, dsp[rd] */
1219 static bool trans_BSET_rm(DisasContext *ctx, arg_BSET_rm *a)
1225 static bool trans_BSET_rr(DisasContext *ctx, arg_BSET_rr *a)
1227 prt("bset\tr%d,r%d", a->rs, a->rd);
1232 static bool trans_BSET_ir(DisasContext *ctx, arg_BSET_ir *a)
1234 prt("bset\t#%d, r%d", a->imm, a->rd);
1238 /* bclr #imm, dsp[rd] */
1239 static bool trans_BCLR_im(DisasContext *ctx, arg_BCLR_im *a)
1244 /* bclr rs, dsp[rd] */
1245 static bool trans_BCLR_rm(DisasContext *ctx, arg_BCLR_rm *a)
1251 static bool trans_BCLR_rr(DisasContext *ctx, arg_BCLR_rr *a)
1253 prt("bclr\tr%d, r%d", a->rs, a->rd);
1258 static bool trans_BCLR_ir(DisasContext *ctx, arg_BCLR_ir *a)
1260 prt("bclr\t#%d,r%d", a->imm, a->rd);
1264 /* btst #imm, dsp[rd] */
1265 static bool trans_BTST_im(DisasContext *ctx, arg_BTST_im *a)
1270 /* btst rs, dsp[rd] */
1271 static bool trans_BTST_rm(DisasContext *ctx, arg_BTST_rm *a)
1277 static bool trans_BTST_rr(DisasContext *ctx, arg_BTST_rr *a)
1279 prt("btst\tr%d, r%d", a->rs, a->rd);
1284 static bool trans_BTST_ir(DisasContext *ctx, arg_BTST_ir *a)
1286 prt("btst\t#%d, r%d", a->imm, a->rd);
1290 /* bnot rs, dsp[rd] */
1291 static bool trans_BNOT_rm(DisasContext *ctx, arg_BNOT_rm *a)
1297 static bool trans_BNOT_rr(DisasContext *ctx, arg_BNOT_rr *a)
1299 prt("bnot\tr%d, r%d", a->rs, a->rd);
1303 /* bnot #imm, dsp[rd] */
1304 static bool trans_BNOT_im(DisasContext *ctx, arg_BNOT_im *a)
1310 static bool trans_BNOT_ir(DisasContext *ctx, arg_BNOT_ir *a)
1312 prt("bnot\t#%d, r%d", a->imm, a->rd);
1316 /* bmcond #imm, dsp[rd] */
1317 static bool trans_BMCnd_im(DisasContext *ctx, arg_BMCnd_im *a)
1321 rx_index_addr(ctx, dsp, a->ld, RX_MEMORY_BYTE);
1322 prt("bm%s\t#%d, %s[r%d]", cond[a->cd], a->imm, dsp, a->rd);
1326 /* bmcond #imm, rd */
1327 static bool trans_BMCnd_ir(DisasContext *ctx, arg_BMCnd_ir *a)
1329 prt("bm%s\t#%d, r%d", cond[a->cd], a->imm, a->rd);
1334 static bool trans_CLRPSW(DisasContext *ctx, arg_CLRPSW *a)
1336 prt("clrpsw\t%c", psw[a->cb]);
1341 static bool trans_SETPSW(DisasContext *ctx, arg_SETPSW *a)
1343 prt("setpsw\t%c", psw[a->cb]);
1348 static bool trans_MVTIPL(DisasContext *ctx, arg_MVTIPL *a)
1350 prt("movtipl\t#%d", a->imm);
1355 static bool trans_MVTC_i(DisasContext *ctx, arg_MVTC_i *a)
1357 prt("mvtc\t#0x%08x, %s", a->imm, rx_crname(a->cr));
1362 static bool trans_MVTC_r(DisasContext *ctx, arg_MVTC_r *a)
1364 prt("mvtc\tr%d, %s", a->rs, rx_crname(a->cr));
1369 static bool trans_MVFC(DisasContext *ctx, arg_MVFC *a)
1371 prt("mvfc\t%s, r%d", rx_crname(a->cr), a->rd);
1376 static bool trans_RTFI(DisasContext *ctx, arg_RTFI *a)
1383 static bool trans_RTE(DisasContext *ctx, arg_RTE *a)
1390 static bool trans_BRK(DisasContext *ctx, arg_BRK *a)
1397 static bool trans_INT(DisasContext *ctx, arg_INT *a)
1399 prt("int\t#%d", a->imm);
1404 static bool trans_WAIT(DisasContext *ctx, arg_WAIT *a)
1410 /* sccnd.[bwl] rd */
1411 /* sccnd.[bwl] dsp:[rd] */
1412 static bool trans_SCCnd(DisasContext *ctx, arg_SCCnd *a)
1416 rx_index_addr(ctx, dsp, a->sz, a->ld);
1417 prt("sc%s.%c\t%s[r%d]", cond[a->cd], size[a->sz], dsp, a->rd);
1419 prt("sc%s.%c\tr%d", cond[a->cd], size[a->sz], a->rd);
1424 int print_insn_rx(bfd_vma addr, disassemble_info *dis)
1431 ctx.pc = ctx.addr = addr;
1434 insn = decode_load(&ctx);
1435 if (!decode(&ctx, insn)) {
1436 ctx.dis->fprintf_func(ctx.dis->stream, ".byte\t");
1437 for (i = 0; i < ctx.addr - addr; i++) {
1439 ctx.dis->fprintf_func(ctx.dis->stream, ",");
1441 ctx.dis->fprintf_func(ctx.dis->stream, "0x%02x", insn >> 24);
1445 return ctx.addr - addr;