• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisiondcc029debb961523ed38e2e2ee21de204a7ff354 (tree)
Time2019-06-16 22:31:40
AuthorYoshinori Sato <ysato@user...>
CommiterYoshinori Sato

Log Message

target/rx: RX disassembler

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20190607091116.49044-5-ysato@users.sourceforge.jp>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Change Summary

Incremental Difference

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