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