From: Yoshinori Sato <ysato@users.sourceforge.jp>
To: qemu-devel@nongnu.org
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>,
peter.maydell@linaro.org, richard.henderson@linaro.org
Subject: [Qemu-devel] [PATCH RFC v3 04/11] target/rx: RX disassembler
Date: Sat, 2 Mar 2019 15:21:31 +0900 [thread overview]
Message-ID: <20190302062138.10713-5-ysato@users.sourceforge.jp> (raw)
In-Reply-To: <20190302062138.10713-1-ysato@users.sourceforge.jp>
Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
include/disas/bfd.h | 5 +
target/rx/disas.c | 1570 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 1575 insertions(+)
create mode 100644 target/rx/disas.c
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 41b61c85f9..b2c34274dd 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -228,6 +228,10 @@ enum bfd_architecture
#define bfd_mach_nios2r2 2
bfd_arch_lm32, /* Lattice Mico32 */
#define bfd_mach_lm32 1
+ bfd_arch_rx, /* Renesas RX */
+#define bfd_mach_rx 0x75
+#define bfd_mach_rx_v2 0x76
+#define bfd_mach_rx_v3 0x77
bfd_arch_last
};
#define bfd_mach_s390_31 31
@@ -432,6 +436,7 @@ int print_insn_little_nios2 (bfd_vma, disassemble_info*);
int print_insn_xtensa (bfd_vma, disassemble_info*);
int print_insn_riscv32 (bfd_vma, disassemble_info*);
int print_insn_riscv64 (bfd_vma, disassemble_info*);
+int print_insn_rx(bfd_vma, disassemble_info *);
#if 0
/* Fetch the disassembler for a given BFD, if that support is available. */
diff --git a/target/rx/disas.c b/target/rx/disas.c
new file mode 100644
index 0000000000..737fd425b6
--- /dev/null
+++ b/target/rx/disas.c
@@ -0,0 +1,1570 @@
+/*
+ * Renesas RX Disassembler
+ *
+ * Copyright (c) 2019 Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "disas/bfd.h"
+#include "qemu/bitops.h"
+#include "cpu.h"
+
+typedef struct DisasContext {
+ disassemble_info *dis;
+ uint32_t addr;
+} DisasContext;
+
+
+static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
+ int i, int n)
+{
+ bfd_byte buf;
+ while (++i <= n) {
+ ctx->dis->read_memory_func(ctx->addr++, &buf, 1, ctx->dis);
+ insn |= buf << (32 - i * 8);
+ }
+ return insn;
+}
+
+static int32_t li(DisasContext *ctx, int sz)
+{
+ int32_t addr;
+ bfd_byte buf[4];
+ addr = ctx->addr;
+
+ switch (sz) {
+ case 1:
+ ctx->addr += 1;
+ ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
+ return buf[0];
+ case 2:
+ ctx->addr += 2;
+ ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
+ return buf[1] << 8 | buf[0];
+ case 3:
+ ctx->addr += 3;
+ ctx->dis->read_memory_func(addr, buf, 3, ctx->dis);
+ return buf[2] << 16 | buf[1] << 8 | buf[0];
+ case 0:
+ ctx->addr += 4;
+ ctx->dis->read_memory_func(addr, buf, 4, ctx->dis);
+ return buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
+ default:
+ g_assert_not_reached();
+ }
+}
+
+/* Include the auto-generated decoder. */
+#include "decode.inc.c"
+
+#define prt(...) (ctx->dis->fprintf_func)((ctx->dis->stream), __VA_ARGS__)
+
+#define RX_MEMORY_BYTE 0
+#define RX_MEMORY_WORD 1
+#define RX_MEMORY_LONG 2
+
+#define RX_MI_BYTE 0
+#define RX_MI_WORD 1
+#define RX_MI_LONG 2
+#define RX_MI_UWORD 3
+
+static const char size[] = {'b', 'w', 'l'};
+static const char *cond[] = {
+ "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
+ "ge", "lt", "gt", "le", "o", "no", "ra", "f"
+};
+static const char *cr[] = {
+ "psw", "", "usp", "fpsw", "", "", "", "",
+ "bpsw", "bpc", "isp", "fintv", "intb", "", "", "",
+};
+static const char *msize[] = {
+ "b", "w", "l", "ub", "uw",
+};
+
+static const char psw[] = {
+ 'c', 'z', 's', 'o', 0, 0, 0, 0,
+ 'i', 'u', 0, 0, 0, 0, 0, 0,
+};
+
+static uint32_t rx_index_addr(int ld, int size, DisasContext *ctx)
+{
+ bfd_byte buf[2];
+ switch (ld) {
+ case 0:
+ return 0;
+ case 1:
+ ctx->dis->read_memory_func(ctx->addr, buf, 1, ctx->dis);
+ ctx->addr += 1;
+ return buf[0];
+ case 2:
+ ctx->dis->read_memory_func(ctx->addr, buf, 2, ctx->dis);
+ ctx->addr += 2;
+ return buf[1] << 8 | buf[0];
+ }
+ g_assert_not_reached();
+}
+
+static void operand(DisasContext *ctx, int ld, int mi, int rs, int rd)
+{
+ int dsp;
+ const char *mis;
+ static const char *sizes[] = {".b", ".w", ".l"};
+ if (ld < 3) {
+ switch (mi) {
+ case 4:
+ /* dsp[rs].ub */
+ dsp = rx_index_addr(ld, RX_MEMORY_BYTE, ctx);
+ mis = ".ub";
+ break;
+ case 3:
+ /* dsp[rs].uw */
+ dsp = rx_index_addr(ld, RX_MEMORY_BYTE, ctx);
+ mis = ".uw";
+ break;
+ default:
+ dsp = rx_index_addr(ld, mi, ctx);
+ mis = sizes[mi];
+ break;
+ }
+ if (dsp > 0) {
+ dsp <<= ld;
+ prt("%d", dsp);
+ }
+ prt("[r%d]%s", rs, mis);
+ } else {
+ prt("r%d", rs);
+ }
+ prt(",r%d", rd);
+}
+
+/* mov.[bwl] rs,dsp:[rd] */
+static bool trans_MOV_mr(DisasContext *ctx, arg_MOV_mr *a)
+{
+ if (a->dsp > 0) {
+ prt("mov.%c\tr%d,%d[r%d]",
+ size[a->sz], a->rs, a->dsp << a->sz, a->rd);
+ } else {
+ prt("mov.%c\tr%d,[r%d]",
+ size[a->sz], a->rs, a->rd);
+ }
+ return true;
+}
+
+/* mov.[bwl] dsp:[rd],rs */
+static bool trans_MOV_rm(DisasContext *ctx, arg_MOV_rm *a)
+{
+ if (a->dsp > 0) {
+ prt("mov.%c\t%d[r%d],r%d",
+ size[a->sz], a->dsp << a->sz, a->rd, a->rs);
+ } else {
+ prt("mov.%c\t[r%d],r%d",
+ size[a->sz], a->rd, a->rs);
+ }
+ return true;
+}
+
+/* mov.l #uimm4,rd */
+/* mov.l #uimm8,rd */
+static bool trans_MOV_ri(DisasContext *ctx, arg_MOV_ri *a)
+{
+ prt("mov.l\t#%d,r%d", a->imm & 0xff, a->rd);
+ return true;
+}
+
+/* mov.[bwl] #uimm8,dsp:[rd] */
+static bool trans_MOV_mi(DisasContext *ctx, arg_MOV_mi *a)
+{
+ if (a->dsp > 0) {
+ prt("mov.%c\t#%d,%d[r%d]",
+ size[a->sz], a->imm & 0xff, a->dsp << a->sz, a->rd);
+ } else {
+ prt("mov.%c\t#%d,[r%d]",
+ size[a->sz], a->imm & 0xff, a->rd);
+ }
+ return true;
+}
+
+/* mov.l #imm,rd */
+static bool trans_MOV_rli(DisasContext *ctx, arg_MOV_rli *a)
+{
+ prt("mov.l\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+
+/* mov #imm, dsp:[rd] */
+static bool trans_MOV_mli(DisasContext *ctx, arg_MOV_mli *a)
+{
+ if (a->ld == 2) {
+ a->dsp = bswap_16(a->dsp);
+ }
+ if (a->dsp > 0) {
+ prt("mov.%c\t#0x%08x,%d[r%d]",
+ size[a->sz], a->imm, a->dsp << a->sz, a->rd);
+ } else {
+ prt("mov.%c\t#0x%08x,[r%d]",
+ size[a->sz], a->imm, a->rd);
+ }
+ return true;
+}
+
+
+/* mov.[bwl] [ri,rb],rd */
+static bool trans_MOV_ra(DisasContext *ctx, arg_MOV_ra *a)
+{
+ prt("mov.%c\t[r%d,r%d],r%d", size[a->sz], a->ri, a->rb, a->rd);
+ return true;
+}
+
+/* mov.[bwl] rd,[ri,rb] */
+static bool trans_MOV_ar(DisasContext *ctx, arg_MOV_ar *a)
+{
+ prt("mov.%c\tr%d,[r%d,r%d]", size[a->sz], a->rs, a->ri, a->rb);
+ return true;
+}
+
+
+/* mov.[bwl] dsp:[rs],dsp:[rd] */
+/* mov.[bwl] rs,dsp:[rd] */
+/* mov.[bwl] dsp:[rs],rd */
+/* mov.[bwl] rs,rd */
+static bool trans_MOV_ll(DisasContext *ctx, arg_MOV_ll *a)
+{
+ int rs, rd, dsp;
+
+ if (a->lds == 3 && a->ldd < 3) {
+ rs = a->rd;
+ rd = a->rs;
+ } else {
+ rs = a->rs;
+ rd = a->rd;
+ }
+ prt("mov.%c\t", size[a->sz]);
+ if (a->lds < 3) {
+ dsp = rx_index_addr(a->lds, a->sz, ctx);
+ if (dsp > 0) {
+ prt("%d", dsp);
+ }
+ prt("[r%d],", rs);
+ } else {
+ prt("r%d,", rs);
+ }
+ if (a->ldd < 3) {
+ dsp = rx_index_addr(a->ldd, a->sz, ctx);
+ if (dsp > 0) {
+ prt("%d", dsp);
+ }
+ prt("[r%d]", rd);
+ } else {
+ prt("r%d", rd);
+ }
+ return true;
+}
+
+/* mov.[bwl] rs,[rd+] */
+/* mov.[bwl] rs,[-rd] */
+static bool trans_MOV_pr(DisasContext *ctx, arg_MOV_pr *a)
+{
+ prt("mov.%c\tr%d,", size[a->sz], a->rs);
+ if (a->ad == 0) {
+ prt("[r%d+]", a->rd);
+ } else {
+ prt("[-r%d]", a->rd);
+ }
+ return true;
+}
+
+/* mov.[bwl] [rd+],rs */
+/* mov.[bwl] [-rd],rs */
+static bool trans_MOV_rp(DisasContext *ctx, arg_MOV_rp *a)
+{
+ prt("mov.%c\t", size[a->sz]);
+ if (a->ad == 1) {
+ prt("[-r%d]", a->rd);
+ } else {
+ prt("[r%d+]", a->rd);
+ }
+ prt(",r%d", a->rs);
+ return true;
+}
+
+/* movu.[bw] dsp5:[rs],rd */
+static bool trans_MOVU_rm(DisasContext *ctx, arg_MOVU_rm *a)
+{
+ if (a->dsp > 0) {
+ prt("movu.%c%d[r%d],r%d", size[a->sz], a->dsp << a->sz, a->rs, a->rd);
+ } else {
+ prt("movu.%c[r%d],r%d", size[a->sz], a->rs, a->rd);
+ }
+ return true;
+}
+
+/* movu.[bw] rs,rd */
+/* movu.[bw] dsp:[rs],rd */
+static bool trans_MOVU_rl(DisasContext *ctx, arg_MOVU_rl *a)
+{
+ int dsp;
+ prt("movu.%c\t", size[a->sz]);
+ if (a->ld < 3) {
+ /* from memory */
+ dsp = rx_index_addr(a->ld, a->sz, ctx);
+ if (dsp > 0) {
+ prt("%d", dsp);
+ }
+ prt("[r%d]", a->rs);
+ } else {
+ prt("r%d", a->rs);
+ }
+ prt(",r%d", a->rd);
+ return true;
+}
+
+/* movu.[bw] [ri,rb],rd */
+static bool trans_MOVU_ra(DisasContext *ctx, arg_MOVU_ra *a)
+{
+ prt("mov.%c\t[r%d,r%d],r%d", size[a->sz], a->ri, a->rb, a->rd);
+ return true;
+}
+
+/* movu.[bw] [rs+],rd */
+/* movu.[bw] [-rs],rd */
+static bool trans_MOVU_rp(DisasContext *ctx, arg_MOVU_rp *a)
+{
+ prt("movu.%c\t", size[a->sz]);
+ if (a->ad == 1) {
+ prt("[-r%d]", a->rd);
+ } else {
+ prt("[r%d+]", a->rd);
+ }
+ prt(",r%d", a->rs);
+ return true;
+}
+
+/* pop rd */
+static bool trans_POP(DisasContext *ctx, arg_POP *a)
+{
+ prt("pop\tr%d", a->rd);
+ return true;
+}
+
+/* popc rx */
+static bool trans_POPC(DisasContext *ctx, arg_POPC *a)
+{
+ prt("pop\tr%s", cr[a->cr]);
+ return true;
+}
+
+/* popm rd-rd2 */
+static bool trans_POPM(DisasContext *ctx, arg_POPM *a)
+{
+ prt("popm\tr%d-r%d", a->rd, a->rd2);
+ return true;
+}
+
+/* push rs */
+static bool trans_PUSH_r(DisasContext *ctx, arg_PUSH_r *a)
+{
+ prt("push\tr%d", a->rs);
+ return true;
+}
+
+/* push dsp[rs] */
+static bool trans_PUSH_m(DisasContext *ctx, arg_PUSH_m *a)
+{
+ prt("push\t");
+ int dsp = rx_index_addr(a->ld, a->sz, ctx);
+ if (dsp > 0) {
+ prt("%d", dsp);
+ }
+ prt("[r%d]", a->rs);
+ return true;
+}
+
+/* pushc rx */
+static bool trans_PUSHC(DisasContext *ctx, arg_PUSHC *a)
+{
+ prt("push\t%s", cr[a->cr]);
+ return true;
+}
+
+/* pushm rs-rs2*/
+static bool trans_PUSHM(DisasContext *ctx, arg_PUSHM *a)
+{
+ prt("pushm\tr%d-r%d", a->rs, a->rs2);
+ return true;
+}
+
+/* xchg rs,rd */
+/* xchg dsp[rs].<mi>,rd */
+static bool trans_XCHG_rl(DisasContext *ctx, arg_XCHG_rl *a)
+{
+ int dsp;
+
+ prt("xchg\t");
+ if (a->ld == 3) {
+ /* xchg rs,rd */
+ prt("r%d", a->rs);
+ } else {
+ dsp = rx_index_addr(a->ld, a->mi, ctx);
+ if (dsp > 0) {
+ prt("%d", dsp);
+ }
+ prt("[r%d].%s", a->rs, msize[a->mi]);
+ }
+ prt(",r%d", a->rd);
+ return true;
+}
+
+/* stz #imm,rd */
+static bool trans_STZ(DisasContext *ctx, arg_STZ *a)
+{
+ prt("stz\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* stnz #imm,rd */
+static bool trans_STNZ(DisasContext *ctx, arg_STNZ *a)
+{
+ prt("stnz\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* rtsd #imm */
+static bool trans_RTSD_i(DisasContext *ctx, arg_RTSD_i *a)
+{
+ prt("rtsd\t#%d", (a->imm & 0xff) << 2);
+ return true;
+}
+
+/* rtsd #imm, rd-rd2 */
+static bool trans_RTSD_irr(DisasContext *ctx, arg_RTSD_irr *a)
+{
+ prt("rtsd\t#%d,r%d-r%d", (a->imm & 0xff) << 2, a->rd, a->rd2);
+ return true;
+}
+
+/* and #uimm:4, rd */
+static bool trans_AND_ri(DisasContext *ctx, arg_AND_ri *a)
+{
+ prt("and\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* and #imm, rd */
+static bool trans_AND_rli(DisasContext *ctx, arg_AND_rli *a)
+{
+ prt("and\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* and dsp[rs], rd */
+/* and rs,rd */
+static bool trans_AND_rl(DisasContext *ctx, arg_AND_rl *a)
+{
+ prt("and\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* and rs,rs2,rd */
+static bool trans_AND_rrr(DisasContext *ctx, arg_AND_rrr *a)
+{
+ prt("and\tr%d,r%d,r%d", a->rs, a->rs2, a->rd);
+ return true;
+}
+
+/* or #uimm:4, rd */
+static bool trans_OR_ri(DisasContext *ctx, arg_OR_ri *a)
+{
+ prt("or\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* or #imm, rd */
+static bool trans_OR_rli(DisasContext *ctx, arg_OR_rli *a)
+{
+ prt("or\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* or dsp[rs], rd */
+/* or rs,rd */
+static bool trans_OR_rl(DisasContext *ctx, arg_OR_rl *a)
+{
+ prt("or\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* or rs,rs2,rd */
+static bool trans_OR_rrr(DisasContext *ctx, arg_OR_rrr *a)
+{
+ prt("or\tr%d,r%d,r%d", a->rs, a->rs2, a->rd);
+ return true;
+}
+
+/* xor #imm, rd */
+static bool trans_XOR_rli(DisasContext *ctx, arg_XOR_rli *a)
+{
+ prt("xor\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* xor dsp[rs], rd */
+/* xor rs,rd */
+static bool trans_XOR_rl(DisasContext *ctx, arg_XOR_rl *a)
+{
+ prt("xor\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* tst #imm, rd */
+static bool trans_TST_rli(DisasContext *ctx, arg_TST_rli *a)
+{
+ prt("tst\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* tst dsp[rs], rd */
+/* tst rs, rd */
+static bool trans_TST_rl(DisasContext *ctx, arg_TST_rl *a)
+{
+ prt("tst\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* not rd */
+/* not rs, rd */
+static bool trans_NOT_rr(DisasContext *ctx, arg_NOT_rr *a)
+{
+ prt("not\t");
+ if (a->rs < 16) {
+ prt("r%d", a->rs);
+ }
+ prt("r%d", a->rd);
+ return true;
+}
+
+/* neg rd */
+/* neg rs, rd */
+static bool trans_NEG_rr(DisasContext *ctx, arg_NEG_rr *a)
+{
+ prt("neg\t");
+ if (a->rs < 16) {
+ prt("r%d", a->rs);
+ }
+ prt("r%d", a->rd);
+ return true;
+}
+
+/* adc #imm, rd */
+static bool trans_ADC_rli(DisasContext *ctx, arg_ADC_rli *a)
+{
+ prt("adc\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* adc rs, rd */
+static bool trans_ADC_rr(DisasContext *ctx, arg_ADC_rr *a)
+{
+ prt("adc\tr%d,r%d", a->rs, a->rd);
+ return true;
+}
+
+/* adc dsp[rs], rd */
+static bool trans_ADC_rl(DisasContext *ctx, arg_ADC_rl *a)
+{
+ int dsp;
+ prt("adc\t");
+ dsp = rx_index_addr(a->ld, RX_LONG, ctx);
+ if (dsp > 0) {
+ prt("%d", dsp);
+ }
+ prt("[r%d],r%d", a->rs, a->rd);
+ return true;
+}
+
+/* add #uimm4, rd */
+static bool trans_ADD_rri(DisasContext *ctx, arg_ADD_rri *a)
+{
+ prt("add\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* add rs, rd */
+/* add dsp[rs], rd */
+static bool trans_ADD_rl(DisasContext *ctx, arg_ADD_rl *a)
+{
+ prt("add\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* add #imm, rs, rd */
+static bool trans_ADD_rrli(DisasContext *ctx, arg_ADD_rrli *a)
+{
+ prt("add\t#0x%08x,r%d,r%d", a->imm, a->rs2, a->rd);
+ return true;
+}
+
+/* add rs, rs2, rd */
+static bool trans_ADD_rrr(DisasContext *ctx, arg_ADD_rrr *a)
+{
+ prt("add\tr%d,r%d,r%d", a->rs, a->rs2, a->rd);
+ return true;
+}
+
+/* cmp #imm4, rd */
+/* cmp #imm8, rd */
+static bool trans_CMP_ri(DisasContext *ctx, arg_CMP_ri *a)
+{
+ int rs;
+ rs = (a->rs2 < 16) ? a->rs2 : a->rd;
+ prt("cmp\t#%d,r%d", a->imm & 0xff, rs);
+ return true;
+}
+
+/* cmp #imm, rs2 */
+static bool trans_CMP_rli(DisasContext *ctx, arg_CMP_rli *a)
+{
+ prt("cmp\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* cmp rs, rs2 */
+/* cmp dsp[rs], rs2 */
+static bool trans_CMP_rl(DisasContext *ctx, arg_CMP_rl *a)
+{
+ prt("cmp\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* sub #imm4, rd */
+static bool trans_SUB_ri(DisasContext *ctx, arg_SUB_ri *a)
+{
+ prt("sub\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* sub rs, rd */
+/* sub dsp[rs], rd */
+static bool trans_SUB_rl(DisasContext *ctx, arg_SUB_rl *a)
+{
+ prt("sub\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* sub rs, rs2, rd */
+static bool trans_SUB_rrr(DisasContext *ctx, arg_SUB_rrr *a)
+{
+ prt("sub\tr%d,r%d,r%d", a->rs, a->rs2, a->rd);
+ return true;
+}
+
+/* sbb rs, rd */
+static bool trans_SBB_rr(DisasContext *ctx, arg_SBB_rr *a)
+{
+ prt("sbb\tr%d,%d", a->rs, a->rd);
+ return true;
+}
+
+/* sbb dsp[rs], rd */
+static bool trans_SBB_rl(DisasContext *ctx, arg_SBB_rl *a)
+{
+ prt("sbb\t");
+ operand(ctx, a->ld, RX_MI_LONG, a->rs, a->rd);
+ return true;
+}
+
+/* abs rd */
+/* abs rs, rd */
+static bool trans_ABS_rr(DisasContext *ctx, arg_ABS_rr *a)
+{
+ prt("abs\t");
+ if (a->rs < 16) {
+ prt("r%d,r%d", a->rs, a->rd);
+ } else {
+ prt("r%d", a->rd);
+ }
+ return true;
+}
+
+/* max #imm, rd */
+static bool trans_MAX_ri(DisasContext *ctx, arg_MAX_ri *a)
+{
+ prt("max\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* max rs, rd */
+/* max dsp[rs], rd */
+static bool trans_MAX_rl(DisasContext *ctx, arg_MAX_rl *a)
+{
+ prt("max\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* min #imm, rd */
+static bool trans_MIN_ri(DisasContext *ctx, arg_MIN_ri *a)
+{
+ prt("min\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* min rs, rd */
+/* min dsp[rs], rd */
+static bool trans_MIN_rl(DisasContext *ctx, arg_MIN_rl *a)
+{
+ prt("max\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* mul #uimm4, rd */
+static bool trans_MUL_ri(DisasContext *ctx, arg_MUL_ri *a)
+{
+ prt("mul\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* mul #imm, rd */
+static bool trans_MUL_rli(DisasContext *ctx, arg_MUL_rli *a)
+{
+ prt("mul\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* mul rs, rd */
+/* mul dsp[rs], rd */
+static bool trans_MUL_rl(DisasContext *ctx, arg_MUL_rl *a)
+{
+ prt("mul\t");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* mul rs, rs2, rd */
+static bool trans_MUL_rrr(DisasContext *ctx, arg_MUL_rrr *a)
+{
+ prt("mul\tr%d,r%d,r%d", a->rs, a->rs2, a->rd);
+ return true;
+}
+
+/* emul #imm, rd */
+static bool trans_EMUL_ri(DisasContext *ctx, arg_EMUL_ri *a)
+{
+ prt("emul\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* emul rs, rd */
+/* emul dsp[rs], rd */
+static bool trans_EMUL_rl(DisasContext *ctx, arg_EMUL_rl *a)
+{
+ prt("emul\n");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* emulu #imm, rd */
+static bool trans_EMULU_ri(DisasContext *ctx, arg_EMULU_ri *a)
+{
+ prt("emulu\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* emulu rs, rd */
+/* emulu dsp[rs], rd */
+static bool trans_EMULU_rl(DisasContext *ctx, arg_EMULU_rl *a)
+{
+ prt("emulu\n");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* div #imm, rd */
+static bool trans_DIV_ri(DisasContext *ctx, arg_DIV_ri *a)
+{
+ prt("div\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* div rs, rd */
+/* div dsp[rs], rd */
+static bool trans_DIV_rl(DisasContext *ctx, arg_DIV_rl *a)
+{
+ prt("div\n");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+/* divu #imm, rd */
+static bool trans_DIVU_ri(DisasContext *ctx, arg_DIVU_ri *a)
+{
+ prt("divu\t#0x%08x,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* divu rs, rd */
+/* divu dsp[rs], rd */
+static bool trans_DIVU_rl(DisasContext *ctx, arg_DIVU_rl *a)
+{
+ prt("divu\n");
+ operand(ctx, a->ld, a->mi, a->rs, a->rd);
+ return true;
+}
+
+
+/* shll #imm:5, rd */
+/* shll #imm:5, rs, rd */
+static bool trans_SHLL_rri(DisasContext *ctx, arg_SHLL_rri *a)
+{
+ prt("shll\t#%d,", a->imm);
+ if (a->rs2 < 16) {
+ prt("r%d,", a->rs2);
+ }
+ prt("r%d", a->rd);
+ return true;
+}
+
+/* shll rs, rd */
+static bool trans_SHLL_rr(DisasContext *ctx, arg_SHLL_rr *a)
+{
+ prt("shll\tr%d,r%d", a->rs, a->rd);
+ return true;
+}
+
+/* shar #imm:5, rd */
+/* shar #imm:5, rs, rd */
+static bool trans_SHAR_rri(DisasContext *ctx, arg_SHAR_rri *a)
+{
+ prt("shar\t#%d,", a->imm);
+ if (a->rs2 < 16) {
+ prt("r%d,", a->rs2);
+ }
+ prt("r%d", a->rd);
+ return true;
+}
+
+/* shar rs, rd */
+static bool trans_SHAR_rr(DisasContext *ctx, arg_SHAR_rr *a)
+{
+ prt("shar\tr%d,r%d", a->rs, a->rd);
+ return true;
+}
+
+/* shlr #imm:5, rd */
+/* shlr #imm:5, rs, rd */
+static bool trans_SHLR_rri(DisasContext *ctx, arg_SHLR_rri *a)
+{
+ prt("shlr\t#%d,", a->imm);
+ if (a->rs2 < 16) {
+ prt("r%d,", a->rs2);
+ }
+ prt("r%d", a->rd);
+ return true;
+}
+
+/* shlr rs, rd */
+static bool trans_SHLR_rr(DisasContext *ctx, arg_SHLR_rr *a)
+{
+ prt("shlr\tr%d,r%d", a->rs, a->rd);
+ return true;
+}
+
+/* rolc rd */
+static bool trans_ROLC(DisasContext *ctx, arg_ROLC *a)
+{
+ prt("rorc\tr%d", a->rd);
+ return true;
+}
+
+/* rorc rd */
+static bool trans_RORC(DisasContext *ctx, arg_RORC *a)
+{
+ prt("rorc\tr%d", a->rd);
+ return true;
+}
+
+/* rotl #imm, rd */
+static bool trans_ROTL_ri(DisasContext *ctx, arg_ROTL_ri *a)
+{
+ prt("rotl\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* rotl rs, rd */
+static bool trans_ROTL_rr(DisasContext *ctx, arg_ROTL_rr *a)
+{
+ prt("rotl\tr%d,r%d", a->rs, a->rd);
+ return true;
+}
+
+/* rotr #imm, rd */
+static bool trans_ROTR_ri(DisasContext *ctx, arg_ROTR_ri *a)
+{
+ prt("rotr\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* rotr rs, rd */
+static bool trans_ROTR_rr(DisasContext *ctx, arg_ROTR_rr *a)
+{
+ prt("rotr\tr%d,r%d", a->rs, a->rd);
+ return true;
+}
+
+/* revl rs, rd */
+static bool trans_REVL(DisasContext *ctx, arg_REVL *a)
+{
+ prt("revl\tr%d,r%d", a->rs, a->rd);
+ return true;
+}
+
+/* revw rs, rd */
+static bool trans_REVW(DisasContext *ctx, arg_REVW *a)
+{
+ prt("revw\tr%d,r%d", a->rs, a->rd);
+ return true;
+}
+
+/* conditional branch helper */
+static void rx_bcnd_main(DisasContext *ctx, int cd, int dst, int len)
+{
+ static const char sz[] = {'s', 'b', 'w', 'a'};
+ prt("b%s.%c\t%08x", cond[cd], sz[len - 1], ctx->addr - len + dst);
+}
+
+static int16_t rev16(uint16_t dsp)
+{
+ return ((dsp << 8) & 0xff00) | ((dsp >> 8) & 0x00ff);
+}
+
+static int32_t rev24(uint32_t dsp)
+{
+ dsp = ((dsp << 16) & 0xff0000) |
+ (dsp & 0x00ff00) |
+ ((dsp >> 16) & 0x0000ff);
+ dsp |= (dsp & 0x00800000) ? 0xff000000 : 0x00000000;
+ return dsp;
+}
+
+/* beq dsp:3 */
+/* bne dsp:3 */
+static bool trans_BCnd_s(DisasContext *ctx, arg_BCnd_s *a)
+{
+ if (a->dsp < 3) {
+ a->dsp += 8;
+ }
+ rx_bcnd_main(ctx, a->cd, a->dsp, 1);
+ return true;
+}
+
+/* beq dsp:8 */
+/* bne dsp:8 */
+/* bc dsp:8 */
+/* bnc dsp:8 */
+/* bgtu dsp:8 */
+/* bleu dsp:8 */
+/* bpz dsp:8 */
+/* bn dsp:8 */
+/* bge dsp:8 */
+/* blt dsp:8 */
+/* bgt dsp:8 */
+/* ble dsp:8 */
+/* bo dsp:8 */
+/* bno dsp:8 */
+/* bra dsp:8 */
+static bool trans_BCnd_b(DisasContext *ctx, arg_BCnd_b *a)
+{
+ rx_bcnd_main(ctx, a->cd, (int8_t)a->dsp, 2);
+ return true;
+}
+
+/* beq dsp:16 */
+/* bne dsp:16 */
+static bool trans_BCnd_w(DisasContext *ctx, arg_BCnd_w *a)
+{
+ rx_bcnd_main(ctx, a->cd, rev16(a->dsp), 3);
+ return true;
+}
+
+/* bra dsp:3 */
+static bool trans_BRA_s(DisasContext *ctx, arg_BRA_s *a)
+{
+ if (a->dsp < 3) {
+ a->dsp += 8;
+ }
+ rx_bcnd_main(ctx, 14, a->dsp, 1);
+ return true;
+}
+
+/* bra dsp:16 */
+static bool trans_BRA_w(DisasContext *ctx, arg_BRA_w *a)
+{
+ rx_bcnd_main(ctx, 14, rev16(a->dsp), 3);
+ return true;
+}
+
+/* bra dsp:24 */
+static bool trans_BRA_a(DisasContext *ctx, arg_BRA_a *a)
+{
+ rx_bcnd_main(ctx, 14, rev24(a->dsp), 4);
+ return true;
+}
+
+/* bra rs */
+static bool trans_BRA_l(DisasContext *ctx, arg_BRA_l *a)
+{
+ prt("bra.l\tr%d", a->rd);
+ return true;
+}
+
+/* jmp rs */
+static bool trans_JMP(DisasContext *ctx, arg_JMP *a)
+{
+ prt("jmp\tr%d", a->rs);
+ return true;
+}
+
+/* jsr rs */
+static bool trans_JSR(DisasContext *ctx, arg_JSR *a)
+{
+ prt("jsr\tr%d", a->rs);
+ return true;
+}
+
+/* bsr dsp:16 */
+static bool trans_BSR_w(DisasContext *ctx, arg_BSR_w *a)
+{
+ prt("bsr.w\t%08x", ctx->addr - 3 + rev16(a->dsp));
+ return true;
+}
+
+/* bsr dsp:24 */
+static bool trans_BSR_a(DisasContext *ctx, arg_BSR_a *a)
+{
+ prt("bsr.a\t%08x", ctx->addr - 4 + rev24(a->dsp));
+ return true;
+}
+
+/* bsr rs */
+static bool trans_BSR_l(DisasContext *ctx, arg_BSR_l *a)
+{
+ prt("bsr.l\tr%d", a->rd);
+ return true;
+}
+
+/* rts */
+static bool trans_RTS(DisasContext *ctx, arg_RTS *a)
+{
+ prt("rts");
+ return true;
+}
+
+/* nop */
+static bool trans_NOP(DisasContext *ctx, arg_NOP *a)
+{
+ prt("nop");
+ return true;
+}
+
+/* scmpu */
+static bool trans_SCMPU(DisasContext *ctx, arg_SCMPU *a)
+{
+ prt("scmpu");
+ return true;
+}
+
+/* smovu */
+static bool trans_SMOVU(DisasContext *ctx, arg_SMOVU *a)
+{
+ prt("smovu");
+ return true;
+}
+
+/* smovf */
+static bool trans_SMOVF(DisasContext *ctx, arg_SMOVF *a)
+{
+ prt("smovf");
+ return true;
+}
+
+/* smovb */
+static bool trans_SMOVB(DisasContext *ctx, arg_SMOVB *a)
+{
+ prt("smovb");
+ return true;
+}
+
+/* suntile */
+static bool trans_SUNTIL(DisasContext *ctx, arg_SUNTIL *a)
+{
+ prt("suntil.%c", size[a->sz]);
+ return true;
+}
+
+/* swhile */
+static bool trans_SWHILE(DisasContext *ctx, arg_SWHILE *a)
+{
+ prt("swhile.%c", size[a->sz]);
+ return true;
+}
+/* sstr */
+static bool trans_SSTR(DisasContext *ctx, arg_SSTR *a)
+{
+ prt("sstr.%c", size[a->sz]);
+ return true;
+}
+
+/* rmpa */
+static bool trans_RMPA(DisasContext *ctx, arg_RMPA *a)
+{
+ prt("rmpa.%c", size[a->sz]);
+ return true;
+}
+
+/* mulhi rs,rs2 */
+static bool trans_MULHI(DisasContext *ctx, arg_MULHI *a)
+{
+ prt("mulhi\tr%d,r%d", a->rs, a->rs2);
+ return true;
+}
+
+/* mullo rs,rs2 */
+static bool trans_MULLO(DisasContext *ctx, arg_MULLO *a)
+{
+ prt("mullo\tr%d,r%d", a->rs, a->rs2);
+ return true;
+}
+
+/* machi rs,rs2 */
+static bool trans_MACHI(DisasContext *ctx, arg_MACHI *a)
+{
+ prt("machi\tr%d,r%d", a->rs, a->rs2);
+ return true;
+}
+
+/* maclo rs,rs2 */
+static bool trans_MACLO(DisasContext *ctx, arg_MACLO *a)
+{
+ prt("maclo\tr%d,r%d", a->rs, a->rs2);
+ return true;
+}
+
+/* mvfachi rd */
+static bool trans_MVFACHI(DisasContext *ctx, arg_MVFACHI *a)
+{
+ prt("mvfachi\tr%d", a->rd);
+ return true;
+}
+
+/* mvfacmi rd */
+static bool trans_MVFACMI(DisasContext *ctx, arg_MVFACMI *a)
+{
+ prt("mvfacmi\tr%d", a->rd);
+ return true;
+}
+
+/* mvtachi rs */
+static bool trans_MVTACHI(DisasContext *ctx, arg_MVTACHI *a)
+{
+ prt("mvtachi\tr%d", a->rs);
+ return true;
+}
+
+/* mvtaclo rs */
+static bool trans_MVTACLO(DisasContext *ctx, arg_MVTACLO *a)
+{
+ prt("mvtaclo\tr%d", a->rs);
+ return true;
+}
+
+/* racw #imm */
+static bool trans_RACW(DisasContext *ctx, arg_RACW *a)
+{
+ prt("racw\t#%d", a->imm + 1);
+ return true;
+}
+
+/* sat rd */
+static bool trans_SAT(DisasContext *ctx, arg_SAT *a)
+{
+ prt("sat\tr%d", a->rd);
+ return true;
+}
+
+/* satr */
+static bool trans_SATR(DisasContext *ctx, arg_SATR *a)
+{
+ prt("satr");
+ return true;
+}
+
+/* fadd #imm, rd */
+static bool trans_FADD_ri(DisasContext *ctx, arg_FADD_ri *a)
+{
+ prt("fadd\t#%d,r%d", li(ctx, 0), a->rd);
+ return true;
+}
+
+/* fadd dsp[rs], rd */
+/* fadd rs, rd */
+static bool trans_FADD_rl(DisasContext *ctx, arg_FADD_rl *a)
+{
+ prt("fadd\t");
+ operand(ctx, a->ld, RX_MI_LONG, a->rs, a->rd);
+ return true;
+}
+
+/* fcmp #imm, rd */
+static bool trans_FCMP_ri(DisasContext *ctx, arg_FCMP_ri *a)
+{
+ prt("fadd\t#%d,r%d", li(ctx, 0), a->rd);
+ return true;
+}
+
+/* fcmp dsp[rs], rd */
+/* fcmp rs, rd */
+static bool trans_FCMP_rl(DisasContext *ctx, arg_FCMP_rl *a)
+{
+ prt("fcmp\t");
+ operand(ctx, a->ld, RX_MI_LONG, a->rs, a->rd);
+ return true;
+}
+
+/* fsub #imm, rd */
+static bool trans_FSUB_ri(DisasContext *ctx, arg_FSUB_ri *a)
+{
+ prt("fsub\t#%d,r%d", li(ctx, 0), a->rd);
+ return true;
+}
+
+/* fsub dsp[rs], rd */
+/* fsub rs, rd */
+static bool trans_FSUB_rl(DisasContext *ctx, arg_FSUB_rl *a)
+{
+ prt("fsub\t");
+ operand(ctx, a->ld, RX_MI_LONG, a->rs, a->rd);
+ return true;
+}
+
+/* ftoi dsp[rs], rd */
+/* ftoi rs, rd */
+static bool trans_FTOI(DisasContext *ctx, arg_FTOI *a)
+{
+ prt("ftoi\t");
+ operand(ctx, a->ld, RX_MI_LONG, a->rs, a->rd);
+ return true;
+}
+
+/* fmul #imm, rd */
+static bool trans_FMUL_ri(DisasContext *ctx, arg_FMUL_ri *a)
+{
+ prt("fmul\t#%d,r%d", li(ctx, 0), a->rd);
+ return true;
+}
+
+/* fmul dsp[rs], rd */
+/* fmul rs, rd */
+static bool trans_FMUL_rl(DisasContext *ctx, arg_FMUL_rl *a)
+{
+ prt("fmul\t");
+ operand(ctx, a->ld, RX_MI_LONG, a->rs, a->rd);
+ return true;
+}
+
+/* fdiv #imm, rd */
+static bool trans_FDIV_ri(DisasContext *ctx, arg_FDIV_ri *a)
+{
+ prt("fdiv\t#%d,r%d", li(ctx, 0), a->rd);
+ return true;
+}
+
+/* fdiv dsp[rs], rd */
+/* fdiv rs, rd */
+static bool trans_FDIV_rl(DisasContext *ctx, arg_FDIV_rl *a)
+{
+ prt("fdiv\t");
+ operand(ctx, a->ld, RX_MI_LONG, a->rs, a->rd);
+ return true;
+}
+
+/* round dsp[rs], rd */
+/* round rs, rd */
+static bool trans_ROUND(DisasContext *ctx, arg_ROUND *a)
+{
+ prt("round\t");
+ operand(ctx, a->ld, RX_MI_LONG, a->rs, a->rd);
+ return true;
+}
+
+/* itof rs, rd */
+/* itof dsp[rs], rd */
+static bool trans_ITOF(DisasContext *ctx, arg_ITOF *a)
+{
+ prt("itof\t");
+ operand(ctx, a->ld, RX_MI_LONG, a->rs, a->rd);
+ return true;
+}
+
+#define BOP_IM(name, reg) \
+ do { \
+ int dsp; \
+ prt("b%s\t#%d,", #name, a->imm); \
+ dsp = rx_index_addr(a->ld, RX_MEMORY_BYTE, ctx); \
+ if (dsp > 0) { \
+ prt("%d", dsp); \
+ } \
+ prt("[r%d]", reg); \
+ return true; \
+ } while (0)
+
+/* bset #imm, dsp[rd] */
+static bool trans_BSET_li(DisasContext *ctx, arg_BSET_li *a)
+{
+ BOP_IM(bset, a->rs);
+}
+
+#define BOP_RM(name) \
+ do { \
+ int dsp; \
+ prt("b%s\tr%d,", #name, a->rs2); \
+ switch (a->ld) { \
+ case 0 ... 2: \
+ dsp = rx_index_addr(a->ld, RX_MEMORY_BYTE, ctx); \
+ if (dsp > 0) { \
+ prt("%d", dsp); \
+ } \
+ prt("[r%d]", a->rs); \
+ break; \
+ case 3: \
+ prt("r%d", a->rs); \
+ break; \
+ } \
+ return true; \
+ } while (0)
+
+/* bset rs, dsp[rd] */
+/* bset rs, rd */
+static bool trans_BSET_lr(DisasContext *ctx, arg_BSET_lr *a)
+{
+ BOP_RM(set);
+}
+
+/* bset #imm, rd */
+static bool trans_BSET_ri(DisasContext *ctx, arg_BSET_ri *a)
+{
+ prt("bset\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* bclr #imm, dsp[rd] */
+static bool trans_BCLR_li(DisasContext *ctx, arg_BCLR_li *a)
+{
+BOP_IM(clr, a->rs);
+}
+
+/* bclr rs, dsp[rd] */
+/* bclr rs, rd */
+static bool trans_BCLR_lr(DisasContext *ctx, arg_BCLR_lr *a)
+{
+ BOP_RM(clr);
+}
+
+/* bclr #imm, rd */
+static bool trans_BCLR_ri(DisasContext *ctx, arg_BCLR_ri *a)
+{
+ prt("bclr\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* btst #imm, dsp[rd] */
+static bool trans_BTST_li(DisasContext *ctx, arg_BTST_li *a)
+{
+ BOP_IM(tst, a->rs);
+}
+
+/* btst rs, dsp[rd] */
+/* btst rs, rd */
+static bool trans_BTST_lr(DisasContext *ctx, arg_BTST_lr *a)
+{
+ BOP_RM(tst);
+}
+
+/* btst #imm, rd */
+static bool trans_BTST_ri(DisasContext *ctx, arg_BTST_ri *a)
+{
+ prt("btst\t#%d,r%d", a->imm, a->rd);
+ return true;
+}
+
+/* bnot rs, dsp[rd] */
+/* bnot rs, rd */
+static bool trans_BNOT_lr(DisasContext *ctx, arg_BNOT_lr *a)
+{
+ BOP_RM(not);
+}
+
+/* bmcond #imm, dsp[rd] */
+/* bnot #imm, dsp[rd] */
+static bool trans_BMCnd_BNOT_mi(DisasContext *ctx, arg_BMCnd_BNOT_mi *a)
+{
+ if (a->cd == 15) {
+ BOP_IM(not, a->rd);
+ } else {
+ int dsp = rx_index_addr(a->ld, RX_MEMORY_BYTE, ctx);
+ prt("bm%s\t#%d,", cond[a->cd], a->imm);
+ if (dsp > 0) {
+ prt("%d", dsp);
+ }
+ prt("[%d]", a->rd);
+ }
+ return true;
+}
+
+/* bmcond #imm, rd */
+/* bnot #imm, rd */
+static bool trans_BMCnd_BNOT_ri(DisasContext *ctx, arg_BMCnd_BNOT_ri *a)
+{
+ if (a->cd == 15) {
+ prt("bnot\t#%d,r%d", a->imm, a->rd);
+ } else {
+ prt("bm%s\t#%d,r%d", cond[a->cd], a->imm, a->rd);
+ }
+ return true;
+}
+
+/* clrpsw psw */
+static bool trans_CLRPSW(DisasContext *ctx, arg_CLRPSW *a)
+{
+ prt("clrpsw\t%c", psw[a->cb]);
+ return true;
+}
+
+/* setpsw psw */
+static bool trans_SETPSW(DisasContext *ctx, arg_SETPSW *a)
+{
+ prt("setpsw\t%c", psw[a->cb]);
+ return true;
+}
+
+/* mvtipl #imm */
+static bool trans_MVTIPL(DisasContext *ctx, arg_MVTIPL *a)
+{
+ prt("movtipl\t#%d", a->imm);
+ return true;
+}
+
+/* mvtc #imm, rd */
+static bool trans_MVTC_i(DisasContext *ctx, arg_MVTC_i *a)
+{
+ prt("mvtc/t#0x%08x,%s", a->imm, cr[a->cr]);
+ return true;
+}
+
+/* mvtc rs, rd */
+static bool trans_MVTC_r(DisasContext *ctx, arg_MVTC_r *a)
+{
+ prt("mvtc/tr%d,%s", a->rs, cr[a->cr]);
+ return true;
+}
+
+/* mvfc rs, rd */
+static bool trans_MVFC(DisasContext *ctx, arg_MVFC *a)
+{
+ prt("mvfc/t%s,r%d", cr[a->cr], a->rd);
+ return true;
+}
+
+/* rtfi */
+static bool trans_RTFI(DisasContext *ctx, arg_RTFI *a)
+{
+ prt("rtfi");
+ return true;
+}
+
+/* rte */
+static bool trans_RTE(DisasContext *ctx, arg_RTE *a)
+{
+ prt("rte");
+ return true;
+}
+
+/* brk */
+static bool trans_BRK(DisasContext *ctx, arg_BRK *a)
+{
+ prt("brk");
+ return true;
+}
+
+/* int #imm */
+static bool trans_INT(DisasContext *ctx, arg_INT *a)
+{
+ prt("int\t#%d", a->imm);
+ return true;
+}
+
+/* wait */
+static bool trans_WAIT(DisasContext *ctx, arg_WAIT *a)
+{
+ prt("wait");
+ return true;
+}
+
+/* sccnd.[bwl] rd */
+/* sccnd.[bwl] dsp:[rd] */
+static bool trans_SCCnd(DisasContext *ctx, arg_SCCnd *a)
+{
+ int dsp;
+ prt("sc%s.%c\t", cond[a->cd], size[a->sz]);
+ if (a->ld < 3) {
+ dsp = rx_index_addr(a->sz, a->ld, ctx);
+ if (dsp > 0) {
+ prt("%d", dsp);
+ }
+ prt("[r%d]", a->rd);
+ } else {
+ prt("r%d", a->rd);
+ }
+ return true;
+}
+
+int print_insn_rx(bfd_vma addr, disassemble_info *dis)
+{
+ DisasContext ctx;
+ uint32_t insn;
+ int i;
+ ctx.dis = dis;
+ ctx.addr = addr;
+
+ insn = decode_load(&ctx);
+ if (!decode(&ctx, insn)) {
+ ctx.dis->fprintf_func(ctx.dis->stream, ".byte\t");
+ for (i = 0; i < ctx.addr - addr; i++) {
+ if (i > 0) {
+ ctx.dis->fprintf_func(ctx.dis->stream, ",");
+ }
+ ctx.dis->fprintf_func(ctx.dis->stream, "0x%02x", insn >> 24);
+ insn <<= 8;
+ }
+ }
+ return ctx.addr - addr;
+}
--
2.11.0
next prev parent reply other threads:[~2019-03-02 6:24 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20190122121413.31437-1-ysato@users.sourceforge.jp>
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 00/11] Add RX archtecture support Yoshinori Sato
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 01/11] target/rx: TCG Translation Yoshinori Sato
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 02/11] target/rx: TCG helper Yoshinori Sato
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 03/11] target/rx: CPU definition Yoshinori Sato
2019-03-02 6:21 ` Yoshinori Sato [this message]
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 05/11] target/rx: miscellaneous functions Yoshinori Sato
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 06/11] RX62N interrupt contorol uint Yoshinori Sato
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 07/11] RX62N internal timer modules Yoshinori Sato
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 08/11] RX62N internal serial communication interface Yoshinori Sato
2019-03-02 19:21 ` Philippe Mathieu-Daudé
2019-03-03 13:50 ` Yoshinori Sato
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 09/11] RX Target hardware definition Yoshinori Sato
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 10/11] Add rx-softmmu Yoshinori Sato
2019-03-02 6:21 ` [Qemu-devel] [PATCH RFC v3 11/11] MAINTAINERS: Add RX entry Yoshinori Sato
2019-03-02 19:03 ` Philippe Mathieu-Daudé
2019-03-03 13:40 ` Yoshinori Sato
2019-03-02 6:37 ` [Qemu-devel] [PATCH RFC v3 00/11] Add RX archtecture support no-reply
2019-03-02 18:51 ` Philippe Mathieu-Daudé
2019-03-03 8:39 ` Yoshinori Sato
2019-03-08 1:24 ` Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190302062138.10713-5-ysato@users.sourceforge.jp \
--to=ysato@users.sourceforge.jp \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.