]>
git.ipfire.org Git - thirdparty/qemu.git/blob - target/rx/disas.c
dcfb7baf9961e7ed9c9afdff573fc53b2ff54171
2 * Renesas RX Disassembler
4 * Copyright (c) 2019 Yoshinori Sato <ysato@users.sourceforge.jp>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2 or later, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "qemu/osdep.h"
20 #include "disas/dis-asm.h"
21 #include "qemu/bitops.h"
24 typedef struct DisasContext
{
25 disassemble_info
*dis
;
33 static uint32_t decode_load_bytes(DisasContext
*ctx
, uint32_t insn
,
36 uint32_t addr
= ctx
->addr
;
38 g_assert(ctx
->len
== i
);
39 g_assert(n
<= ARRAY_SIZE(ctx
->bytes
));
42 ctx
->dis
->read_memory_func(addr
++, &ctx
->bytes
[i
- 1], 1, ctx
->dis
);
43 insn
|= ctx
->bytes
[i
- 1] << (32 - i
* 8);
51 static int32_t li(DisasContext
*ctx
, int sz
)
53 uint32_t addr
= ctx
->addr
;
54 uintptr_t len
= ctx
->len
;
58 g_assert(len
+ 1 <= ARRAY_SIZE(ctx
->bytes
));
61 ctx
->dis
->read_memory_func(addr
, ctx
->bytes
+ len
, 1, ctx
->dis
);
62 return (int8_t)ctx
->bytes
[len
];
64 g_assert(len
+ 2 <= ARRAY_SIZE(ctx
->bytes
));
67 ctx
->dis
->read_memory_func(addr
, ctx
->bytes
+ len
, 2, ctx
->dis
);
68 return ldsw_le_p(ctx
->bytes
+ len
);
70 g_assert(len
+ 3 <= ARRAY_SIZE(ctx
->bytes
));
73 ctx
->dis
->read_memory_func(addr
, ctx
->bytes
+ len
, 3, ctx
->dis
);
74 return (int8_t)ctx
->bytes
[len
+ 2] << 16 | lduw_le_p(ctx
->bytes
+ len
);
76 g_assert(len
+ 4 <= ARRAY_SIZE(ctx
->bytes
));
79 ctx
->dis
->read_memory_func(addr
, ctx
->bytes
+ len
, 4, ctx
->dis
);
80 return ldl_le_p(ctx
->bytes
+ len
);
82 g_assert_not_reached();
86 static int bdsp_s(DisasContext
*ctx
, int d
)
102 /* Include the auto-generated decoder. */
103 #include "decode.inc.c"
105 #define prt(...) (ctx->dis->fprintf_func)((ctx->dis->stream), __VA_ARGS__)
107 #define RX_MEMORY_BYTE 0
108 #define RX_MEMORY_WORD 1
109 #define RX_MEMORY_LONG 2
114 #define RX_IM_UWORD 3
116 static const char size
[] = {'b', 'w', 'l'};
117 static const char cond
[][4] = {
118 "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
119 "ge", "lt", "gt", "le", "o", "no", "ra", "f"
121 static const char psw
[] = {
122 'c', 'z', 's', 'o', 0, 0, 0, 0,
123 'i', 'u', 0, 0, 0, 0, 0, 0,
126 static void rx_index_addr(DisasContext
*ctx
, char out
[8], int ld
, int mi
)
128 uint32_t addr
= ctx
->addr
;
129 uintptr_t len
= ctx
->len
;
134 /* No index; return empty string. */
138 g_assert(len
+ 1 <= ARRAY_SIZE(ctx
->bytes
));
141 ctx
->dis
->read_memory_func(addr
, ctx
->bytes
+ len
, 1, ctx
->dis
);
142 dsp
= ctx
->bytes
[len
];
145 g_assert(len
+ 2 <= ARRAY_SIZE(ctx
->bytes
));
148 ctx
->dis
->read_memory_func(addr
, ctx
->bytes
+ len
, 2, ctx
->dis
);
149 dsp
= lduw_le_p(ctx
->bytes
+ len
);
152 g_assert_not_reached();
155 sprintf(out
, "%u", dsp
<< (mi
< 3 ? mi
: 4 - mi
));
158 static void prt_ldmi(DisasContext
*ctx
, const char *insn
,
159 int ld
, int mi
, int rs
, int rd
)
161 static const char sizes
[][4] = {".b", ".w", ".l", ".uw", ".ub"};
165 rx_index_addr(ctx
, dsp
, ld
, mi
);
166 prt("%s\t%s[r%d]%s, r%d", insn
, dsp
, rs
, sizes
[mi
], rd
);
168 prt("%s\tr%d, r%d", insn
, rs
, rd
);
172 static void prt_ir(DisasContext
*ctx
, const char *insn
, int imm
, int rd
)
175 prt("%s\t#%d, r%d", insn
, imm
, rd
);
177 prt("%s\t#0x%08x, r%d", insn
, imm
, rd
);
181 /* mov.[bwl] rs,dsp:[rd] */
182 static bool trans_MOV_rm(DisasContext
*ctx
, arg_MOV_rm
*a
)
185 prt("mov.%c\tr%d,%d[r%d]",
186 size
[a
->sz
], a
->rs
, a
->dsp
<< a
->sz
, a
->rd
);
188 prt("mov.%c\tr%d,[r%d]",
189 size
[a
->sz
], a
->rs
, a
->rd
);
194 /* mov.[bwl] dsp:[rs],rd */
195 static bool trans_MOV_mr(DisasContext
*ctx
, arg_MOV_mr
*a
)
198 prt("mov.%c\t%d[r%d], r%d",
199 size
[a
->sz
], a
->dsp
<< a
->sz
, a
->rs
, a
->rd
);
201 prt("mov.%c\t[r%d], r%d",
202 size
[a
->sz
], a
->rs
, a
->rd
);
207 /* mov.l #uimm4,rd */
208 /* mov.l #uimm8,rd */
210 static bool trans_MOV_ir(DisasContext
*ctx
, arg_MOV_ir
*a
)
212 prt_ir(ctx
, "mov.l", a
->imm
, a
->rd
);
216 /* mov.[bwl] #uimm8,dsp:[rd] */
217 /* mov #imm, dsp:[rd] */
218 static bool trans_MOV_im(DisasContext
*ctx
, arg_MOV_im
*a
)
221 prt("mov.%c\t#%d,%d[r%d]",
222 size
[a
->sz
], a
->imm
, a
->dsp
<< a
->sz
, a
->rd
);
224 prt("mov.%c\t#%d,[r%d]",
225 size
[a
->sz
], a
->imm
, a
->rd
);
230 /* mov.[bwl] [ri,rb],rd */
231 static bool trans_MOV_ar(DisasContext
*ctx
, arg_MOV_ar
*a
)
233 prt("mov.%c\t[r%d,r%d], r%d", size
[a
->sz
], a
->ri
, a
->rb
, a
->rd
);
237 /* mov.[bwl] rd,[ri,rb] */
238 static bool trans_MOV_ra(DisasContext
*ctx
, arg_MOV_ra
*a
)
240 prt("mov.%c\tr%d, [r%d, r%d]", size
[a
->sz
], a
->rs
, a
->ri
, a
->rb
);
245 /* mov.[bwl] dsp:[rs],dsp:[rd] */
246 /* mov.[bwl] rs,dsp:[rd] */
247 /* mov.[bwl] dsp:[rs],rd */
248 /* mov.[bwl] rs,rd */
249 static bool trans_MOV_mm(DisasContext
*ctx
, arg_MOV_mm
*a
)
251 char dspd
[8], dsps
[8], szc
= size
[a
->sz
];
253 if (a
->lds
== 3 && a
->ldd
== 3) {
254 /* mov.[bwl] rs,rd */
255 prt("mov.%c\tr%d, r%d", szc
, a
->rs
, a
->rd
);
256 } else if (a
->lds
== 3) {
257 rx_index_addr(ctx
, dspd
, a
->ldd
, a
->sz
);
258 prt("mov.%c\tr%d, %s[r%d]", szc
, a
->rs
, dspd
, a
->rd
);
259 } else if (a
->ldd
== 3) {
260 rx_index_addr(ctx
, dsps
, a
->lds
, a
->sz
);
261 prt("mov.%c\t%s[r%d], r%d", szc
, dsps
, a
->rs
, a
->rd
);
263 rx_index_addr(ctx
, dsps
, a
->lds
, a
->sz
);
264 rx_index_addr(ctx
, dspd
, a
->ldd
, a
->sz
);
265 prt("mov.%c\t%s[r%d], %s[r%d]", szc
, dsps
, a
->rs
, dspd
, a
->rd
);
270 /* mov.[bwl] rs,[rd+] */
271 /* mov.[bwl] rs,[-rd] */
272 static bool trans_MOV_rp(DisasContext
*ctx
, arg_MOV_rp
*a
)
275 prt("mov.%c\tr%d, [-r%d]", size
[a
->sz
], a
->rs
, a
->rd
);
277 prt("mov.%c\tr%d, [r%d+]", size
[a
->sz
], a
->rs
, a
->rd
);
282 /* mov.[bwl] [rd+],rs */
283 /* mov.[bwl] [-rd],rs */
284 static bool trans_MOV_pr(DisasContext
*ctx
, arg_MOV_pr
*a
)
287 prt("mov.%c\t[-r%d], r%d", size
[a
->sz
], a
->rd
, a
->rs
);
289 prt("mov.%c\t[r%d+], r%d", size
[a
->sz
], a
->rd
, a
->rs
);
294 /* movu.[bw] dsp5:[rs],rd */
295 static bool trans_MOVU_mr(DisasContext
*ctx
, arg_MOVU_mr
*a
)
298 prt("movu.%c\t%d[r%d], r%d", size
[a
->sz
],
299 a
->dsp
<< a
->sz
, a
->rs
, a
->rd
);
301 prt("movu.%c\t[r%d], r%d", size
[a
->sz
], a
->rs
, a
->rd
);
306 /* movu.[bw] rs,rd */
307 static bool trans_MOVU_rr(DisasContext
*ctx
, arg_MOVU_rr
*a
)
309 prt("movu.%c\tr%d, r%d", size
[a
->sz
], a
->rs
, a
->rd
);
313 /* movu.[bw] [ri,rb],rd */
314 static bool trans_MOVU_ar(DisasContext
*ctx
, arg_MOVU_ar
*a
)
316 prt("mov.%c\t[r%d,r%d], r%d", size
[a
->sz
], a
->ri
, a
->rb
, a
->rd
);
320 /* movu.[bw] [rs+],rd */
321 /* movu.[bw] [-rs],rd */
322 static bool trans_MOVU_pr(DisasContext
*ctx
, arg_MOVU_pr
*a
)
325 prt("movu.%c\t[-r%d], r%d", size
[a
->sz
], a
->rd
, a
->rs
);
327 prt("movu.%c\t[r%d+], r%d", size
[a
->sz
], a
->rd
, a
->rs
);
333 static bool trans_POP(DisasContext
*ctx
, arg_POP
*a
)
335 prt("pop\tr%d", a
->rd
);
340 static bool trans_POPC(DisasContext
*ctx
, arg_POPC
*a
)
342 prt("pop\tr%s", rx_crname(a
->cr
));
347 static bool trans_POPM(DisasContext
*ctx
, arg_POPM
*a
)
349 prt("popm\tr%d-r%d", a
->rd
, a
->rd2
);
354 static bool trans_PUSH_r(DisasContext
*ctx
, arg_PUSH_r
*a
)
356 prt("push\tr%d", a
->rs
);
361 static bool trans_PUSH_m(DisasContext
*ctx
, arg_PUSH_m
*a
)
365 rx_index_addr(ctx
, dsp
, a
->ld
, a
->sz
);
366 prt("push\t%s[r%d]", dsp
, a
->rs
);
371 static bool trans_PUSHC(DisasContext
*ctx
, arg_PUSHC
*a
)
373 prt("push\t%s", rx_crname(a
->cr
));
378 static bool trans_PUSHM(DisasContext
*ctx
, arg_PUSHM
*a
)
380 prt("pushm\tr%d-r%d", a
->rs
, a
->rs2
);
385 static bool trans_XCHG_rr(DisasContext
*ctx
, arg_XCHG_rr
*a
)
387 prt("xchg\tr%d, r%d", a
->rs
, a
->rd
);
390 /* xchg dsp[rs].<mi>,rd */
391 static bool trans_XCHG_mr(DisasContext
*ctx
, arg_XCHG_mr
*a
)
393 prt_ldmi(ctx
, "xchg", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
398 static bool trans_STZ(DisasContext
*ctx
, arg_STZ
*a
)
400 prt_ir(ctx
, "stz", a
->imm
, a
->rd
);
405 static bool trans_STNZ(DisasContext
*ctx
, arg_STNZ
*a
)
407 prt_ir(ctx
, "stnz", a
->imm
, a
->rd
);
412 static bool trans_RTSD_i(DisasContext
*ctx
, arg_RTSD_i
*a
)
414 prt("rtsd\t#%d", a
->imm
<< 2);
418 /* rtsd #imm, rd-rd2 */
419 static bool trans_RTSD_irr(DisasContext
*ctx
, arg_RTSD_irr
*a
)
421 prt("rtsd\t#%d, r%d - r%d", a
->imm
<< 2, a
->rd
, a
->rd2
);
425 /* and #uimm:4, rd */
427 static bool trans_AND_ir(DisasContext
*ctx
, arg_AND_ir
*a
)
429 prt_ir(ctx
, "and", a
->imm
, a
->rd
);
433 /* and dsp[rs], rd */
435 static bool trans_AND_mr(DisasContext
*ctx
, arg_AND_mr
*a
)
437 prt_ldmi(ctx
, "and", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
442 static bool trans_AND_rrr(DisasContext
*ctx
, arg_AND_rrr
*a
)
444 prt("and\tr%d,r%d, r%d", a
->rs
, a
->rs2
, a
->rd
);
450 static bool trans_OR_ir(DisasContext
*ctx
, arg_OR_ir
*a
)
452 prt_ir(ctx
, "or", a
->imm
, a
->rd
);
458 static bool trans_OR_mr(DisasContext
*ctx
, arg_OR_mr
*a
)
460 prt_ldmi(ctx
, "or", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
465 static bool trans_OR_rrr(DisasContext
*ctx
, arg_OR_rrr
*a
)
467 prt("or\tr%d, r%d, r%d", a
->rs
, a
->rs2
, a
->rd
);
472 static bool trans_XOR_ir(DisasContext
*ctx
, arg_XOR_ir
*a
)
474 prt_ir(ctx
, "xor", a
->imm
, a
->rd
);
478 /* xor dsp[rs], rd */
480 static bool trans_XOR_mr(DisasContext
*ctx
, arg_XOR_mr
*a
)
482 prt_ldmi(ctx
, "xor", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
487 static bool trans_TST_ir(DisasContext
*ctx
, arg_TST_ir
*a
)
489 prt_ir(ctx
, "tst", a
->imm
, a
->rd
);
493 /* tst dsp[rs], rd */
495 static bool trans_TST_mr(DisasContext
*ctx
, arg_TST_mr
*a
)
497 prt_ldmi(ctx
, "tst", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
503 static bool trans_NOT_rr(DisasContext
*ctx
, arg_NOT_rr
*a
)
505 if (a
->rs
!= a
->rd
) {
506 prt("not\tr%d, r%d", a
->rs
, a
->rd
);
508 prt("not\tr%d", a
->rs
);
515 static bool trans_NEG_rr(DisasContext
*ctx
, arg_NEG_rr
*a
)
517 if (a
->rs
!= a
->rd
) {
518 prt("neg\tr%d, r%d", a
->rs
, a
->rd
);
520 prt("neg\tr%d", a
->rs
);
526 static bool trans_ADC_ir(DisasContext
*ctx
, arg_ADC_ir
*a
)
528 prt_ir(ctx
, "adc", a
->imm
, a
->rd
);
533 static bool trans_ADC_rr(DisasContext
*ctx
, arg_ADC_rr
*a
)
535 prt("adc\tr%d, r%d", a
->rs
, a
->rd
);
539 /* adc dsp[rs], rd */
540 static bool trans_ADC_mr(DisasContext
*ctx
, arg_ADC_mr
*a
)
544 rx_index_addr(ctx
, dsp
, a
->ld
, 2);
545 prt("adc\t%s[r%d], r%d", dsp
, a
->rs
, a
->rd
);
550 /* add #imm, rs, rd */
551 static bool trans_ADD_irr(DisasContext
*ctx
, arg_ADD_irr
*a
)
553 if (a
->imm
< 0x10 && a
->rs2
== a
->rd
) {
554 prt("add\t#%d, r%d", a
->imm
, a
->rd
);
556 prt("add\t#0x%08x, r%d, r%d", a
->imm
, a
->rs2
, a
->rd
);
562 /* add dsp[rs], rd */
563 static bool trans_ADD_mr(DisasContext
*ctx
, arg_ADD_mr
*a
)
565 prt_ldmi(ctx
, "add", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
569 /* add rs, rs2, rd */
570 static bool trans_ADD_rrr(DisasContext
*ctx
, arg_ADD_rrr
*a
)
572 prt("add\tr%d, r%d, r%d", a
->rs
, a
->rs2
, a
->rd
);
579 static bool trans_CMP_ir(DisasContext
*ctx
, arg_CMP_ir
*a
)
581 prt_ir(ctx
, "cmp", a
->imm
, a
->rs2
);
586 /* cmp dsp[rs], rs2 */
587 static bool trans_CMP_mr(DisasContext
*ctx
, arg_CMP_mr
*a
)
589 prt_ldmi(ctx
, "cmp", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
594 static bool trans_SUB_ir(DisasContext
*ctx
, arg_SUB_ir
*a
)
596 prt("sub\t#%d, r%d", a
->imm
, a
->rd
);
601 /* sub dsp[rs], rd */
602 static bool trans_SUB_mr(DisasContext
*ctx
, arg_SUB_mr
*a
)
604 prt_ldmi(ctx
, "sub", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
608 /* sub rs, rs2, rd */
609 static bool trans_SUB_rrr(DisasContext
*ctx
, arg_SUB_rrr
*a
)
611 prt("sub\tr%d, r%d, r%d", a
->rs
, a
->rs2
, a
->rd
);
616 static bool trans_SBB_rr(DisasContext
*ctx
, arg_SBB_rr
*a
)
618 prt("sbb\tr%d, r%d", a
->rs
, a
->rd
);
622 /* sbb dsp[rs], rd */
623 static bool trans_SBB_mr(DisasContext
*ctx
, arg_SBB_mr
*a
)
625 prt_ldmi(ctx
, "sbb", a
->ld
, RX_IM_LONG
, a
->rs
, a
->rd
);
631 static bool trans_ABS_rr(DisasContext
*ctx
, arg_ABS_rr
*a
)
633 if (a
->rs
!= a
->rd
) {
634 prt("abs\tr%d, r%d", a
->rs
, a
->rd
);
636 prt("abs\tr%d", a
->rs
);
642 static bool trans_MAX_ir(DisasContext
*ctx
, arg_MAX_ir
*a
)
644 prt_ir(ctx
, "max", a
->imm
, a
->rd
);
649 /* max dsp[rs], rd */
650 static bool trans_MAX_mr(DisasContext
*ctx
, arg_MAX_mr
*a
)
652 prt_ldmi(ctx
, "max", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
657 static bool trans_MIN_ir(DisasContext
*ctx
, arg_MIN_ir
*a
)
659 prt_ir(ctx
, "min", a
->imm
, a
->rd
);
664 /* min dsp[rs], rd */
665 static bool trans_MIN_mr(DisasContext
*ctx
, arg_MIN_mr
*a
)
667 prt_ldmi(ctx
, "min", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
673 static bool trans_MUL_ir(DisasContext
*ctx
, arg_MUL_ir
*a
)
675 prt_ir(ctx
, "mul", a
->imm
, a
->rd
);
680 /* mul dsp[rs], rd */
681 static bool trans_MUL_mr(DisasContext
*ctx
, arg_MUL_mr
*a
)
683 prt_ldmi(ctx
, "mul", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
687 /* mul rs, rs2, rd */
688 static bool trans_MUL_rrr(DisasContext
*ctx
, arg_MUL_rrr
*a
)
690 prt("mul\tr%d,r%d,r%d", a
->rs
, a
->rs2
, a
->rd
);
695 static bool trans_EMUL_ir(DisasContext
*ctx
, arg_EMUL_ir
*a
)
697 prt_ir(ctx
, "emul", a
->imm
, a
->rd
);
702 /* emul dsp[rs], rd */
703 static bool trans_EMUL_mr(DisasContext
*ctx
, arg_EMUL_mr
*a
)
705 prt_ldmi(ctx
, "emul", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
710 static bool trans_EMULU_ir(DisasContext
*ctx
, arg_EMULU_ir
*a
)
712 prt_ir(ctx
, "emulu", a
->imm
, a
->rd
);
717 /* emulu dsp[rs], rd */
718 static bool trans_EMULU_mr(DisasContext
*ctx
, arg_EMULU_mr
*a
)
720 prt_ldmi(ctx
, "emulu", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
725 static bool trans_DIV_ir(DisasContext
*ctx
, arg_DIV_ir
*a
)
727 prt_ir(ctx
, "div", a
->imm
, a
->rd
);
732 /* div dsp[rs], rd */
733 static bool trans_DIV_mr(DisasContext
*ctx
, arg_DIV_mr
*a
)
735 prt_ldmi(ctx
, "div", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
740 static bool trans_DIVU_ir(DisasContext
*ctx
, arg_DIVU_ir
*a
)
742 prt_ir(ctx
, "divu", a
->imm
, a
->rd
);
747 /* divu dsp[rs], rd */
748 static bool trans_DIVU_mr(DisasContext
*ctx
, arg_DIVU_mr
*a
)
750 prt_ldmi(ctx
, "divu", a
->ld
, a
->mi
, a
->rs
, a
->rd
);
755 /* shll #imm:5, rd */
756 /* shll #imm:5, rs, rd */
757 static bool trans_SHLL_irr(DisasContext
*ctx
, arg_SHLL_irr
*a
)
759 if (a
->rs2
!= a
->rd
) {
760 prt("shll\t#%d, r%d, r%d", a
->imm
, a
->rs2
, a
->rd
);
762 prt("shll\t#%d, r%d", a
->imm
, a
->rd
);
768 static bool trans_SHLL_rr(DisasContext
*ctx
, arg_SHLL_rr
*a
)
770 prt("shll\tr%d, r%d", a
->rs
, a
->rd
);
774 /* shar #imm:5, rd */
775 /* shar #imm:5, rs, rd */
776 static bool trans_SHAR_irr(DisasContext
*ctx
, arg_SHAR_irr
*a
)
778 if (a
->rs2
!= a
->rd
) {
779 prt("shar\t#%d, r%d, r%d", a
->imm
, a
->rs2
, a
->rd
);
781 prt("shar\t#%d, r%d", a
->imm
, a
->rd
);
787 static bool trans_SHAR_rr(DisasContext
*ctx
, arg_SHAR_rr
*a
)
789 prt("shar\tr%d, r%d", a
->rs
, a
->rd
);
793 /* shlr #imm:5, rd */
794 /* shlr #imm:5, rs, rd */
795 static bool trans_SHLR_irr(DisasContext
*ctx
, arg_SHLR_irr
*a
)
797 if (a
->rs2
!= a
->rd
) {
798 prt("shlr\t#%d, r%d, r%d", a
->imm
, a
->rs2
, a
->rd
);
800 prt("shlr\t#%d, r%d", a
->imm
, a
->rd
);
806 static bool trans_SHLR_rr(DisasContext
*ctx
, arg_SHLR_rr
*a
)
808 prt("shlr\tr%d, r%d", a
->rs
, a
->rd
);
813 static bool trans_ROLC(DisasContext
*ctx
, arg_ROLC
*a
)
815 prt("rorc\tr%d", a
->rd
);
820 static bool trans_RORC(DisasContext
*ctx
, arg_RORC
*a
)
822 prt("rorc\tr%d", a
->rd
);
827 static bool trans_ROTL_ir(DisasContext
*ctx
, arg_ROTL_ir
*a
)
829 prt("rotl\t#%d, r%d", a
->imm
, a
->rd
);
834 static bool trans_ROTL_rr(DisasContext
*ctx
, arg_ROTL_rr
*a
)
836 prt("rotl\tr%d, r%d", a
->rs
, a
->rd
);
841 static bool trans_ROTR_ir(DisasContext
*ctx
, arg_ROTR_ir
*a
)
843 prt("rotr\t#%d, r%d", a
->imm
, a
->rd
);
848 static bool trans_ROTR_rr(DisasContext
*ctx
, arg_ROTR_rr
*a
)
850 prt("rotr\tr%d, r%d", a
->rs
, a
->rd
);
855 static bool trans_REVL(DisasContext
*ctx
, arg_REVL
*a
)
857 prt("revl\tr%d, r%d", a
->rs
, a
->rd
);
862 static bool trans_REVW(DisasContext
*ctx
, arg_REVW
*a
)
864 prt("revw\tr%d, r%d", a
->rs
, a
->rd
);
868 /* conditional branch helper */
869 static void rx_bcnd_main(DisasContext
*ctx
, int cd
, int len
, int dst
)
871 static const char sz
[] = {'s', 'b', 'w', 'a'};
872 prt("b%s.%c\t%08x", cond
[cd
], sz
[len
- 1], ctx
->pc
+ dst
);
875 /* beq dsp:3 / bne dsp:3 */
876 /* beq dsp:8 / bne dsp:8 */
877 /* bc dsp:8 / bnc dsp:8 */
878 /* bgtu dsp:8 / bleu dsp:8 */
879 /* bpz dsp:8 / bn dsp:8 */
880 /* bge dsp:8 / blt dsp:8 */
881 /* bgt dsp:8 / ble dsp:8 */
882 /* bo dsp:8 / bno dsp:8 */
883 /* beq dsp:16 / bne dsp:16 */
884 static bool trans_BCnd(DisasContext
*ctx
, arg_BCnd
*a
)
886 rx_bcnd_main(ctx
, a
->cd
, a
->sz
, a
->dsp
);
894 static bool trans_BRA(DisasContext
*ctx
, arg_BRA
*a
)
896 rx_bcnd_main(ctx
, 14, a
->sz
, a
->dsp
);
901 static bool trans_BRA_l(DisasContext
*ctx
, arg_BRA_l
*a
)
903 prt("bra.l\tr%d", a
->rd
);
908 static bool trans_JMP(DisasContext
*ctx
, arg_JMP
*a
)
910 prt("jmp\tr%d", a
->rs
);
915 static bool trans_JSR(DisasContext
*ctx
, arg_JSR
*a
)
917 prt("jsr\tr%d", a
->rs
);
923 static bool trans_BSR(DisasContext
*ctx
, arg_BSR
*a
)
925 static const char sz
[] = {'w', 'a'};
926 prt("bsr.%c\t%08x", sz
[a
->sz
- 3], ctx
->pc
+ a
->dsp
);
931 static bool trans_BSR_l(DisasContext
*ctx
, arg_BSR_l
*a
)
933 prt("bsr.l\tr%d", a
->rd
);
938 static bool trans_RTS(DisasContext
*ctx
, arg_RTS
*a
)
945 static bool trans_NOP(DisasContext
*ctx
, arg_NOP
*a
)
952 static bool trans_SCMPU(DisasContext
*ctx
, arg_SCMPU
*a
)
959 static bool trans_SMOVU(DisasContext
*ctx
, arg_SMOVU
*a
)
966 static bool trans_SMOVF(DisasContext
*ctx
, arg_SMOVF
*a
)
973 static bool trans_SMOVB(DisasContext
*ctx
, arg_SMOVB
*a
)
980 static bool trans_SUNTIL(DisasContext
*ctx
, arg_SUNTIL
*a
)
982 prt("suntil.%c", size
[a
->sz
]);
987 static bool trans_SWHILE(DisasContext
*ctx
, arg_SWHILE
*a
)
989 prt("swhile.%c", size
[a
->sz
]);
993 static bool trans_SSTR(DisasContext
*ctx
, arg_SSTR
*a
)
995 prt("sstr.%c", size
[a
->sz
]);
1000 static bool trans_RMPA(DisasContext
*ctx
, arg_RMPA
*a
)
1002 prt("rmpa.%c", size
[a
->sz
]);
1007 static bool trans_MULHI(DisasContext
*ctx
, arg_MULHI
*a
)
1009 prt("mulhi\tr%d,r%d", a
->rs
, a
->rs2
);
1014 static bool trans_MULLO(DisasContext
*ctx
, arg_MULLO
*a
)
1016 prt("mullo\tr%d, r%d", a
->rs
, a
->rs2
);
1021 static bool trans_MACHI(DisasContext
*ctx
, arg_MACHI
*a
)
1023 prt("machi\tr%d, r%d", a
->rs
, a
->rs2
);
1028 static bool trans_MACLO(DisasContext
*ctx
, arg_MACLO
*a
)
1030 prt("maclo\tr%d, r%d", a
->rs
, a
->rs2
);
1035 static bool trans_MVFACHI(DisasContext
*ctx
, arg_MVFACHI
*a
)
1037 prt("mvfachi\tr%d", a
->rd
);
1042 static bool trans_MVFACMI(DisasContext
*ctx
, arg_MVFACMI
*a
)
1044 prt("mvfacmi\tr%d", a
->rd
);
1049 static bool trans_MVTACHI(DisasContext
*ctx
, arg_MVTACHI
*a
)
1051 prt("mvtachi\tr%d", a
->rs
);
1056 static bool trans_MVTACLO(DisasContext
*ctx
, arg_MVTACLO
*a
)
1058 prt("mvtaclo\tr%d", a
->rs
);
1063 static bool trans_RACW(DisasContext
*ctx
, arg_RACW
*a
)
1065 prt("racw\t#%d", a
->imm
+ 1);
1070 static bool trans_SAT(DisasContext
*ctx
, arg_SAT
*a
)
1072 prt("sat\tr%d", a
->rd
);
1077 static bool trans_SATR(DisasContext
*ctx
, arg_SATR
*a
)
1084 static bool trans_FADD_ir(DisasContext
*ctx
, arg_FADD_ir
*a
)
1086 prt("fadd\t#%d,r%d", li(ctx
, 0), a
->rd
);
1090 /* fadd dsp[rs], rd */
1092 static bool trans_FADD_mr(DisasContext
*ctx
, arg_FADD_mr
*a
)
1094 prt_ldmi(ctx
, "fadd", a
->ld
, RX_IM_LONG
, a
->rs
, a
->rd
);
1099 static bool trans_FCMP_ir(DisasContext
*ctx
, arg_FCMP_ir
*a
)
1101 prt("fadd\t#%d,r%d", li(ctx
, 0), a
->rd
);
1105 /* fcmp dsp[rs], rd */
1107 static bool trans_FCMP_mr(DisasContext
*ctx
, arg_FCMP_mr
*a
)
1109 prt_ldmi(ctx
, "fcmp", a
->ld
, RX_IM_LONG
, a
->rs
, a
->rd
);
1114 static bool trans_FSUB_ir(DisasContext
*ctx
, arg_FSUB_ir
*a
)
1116 prt("fsub\t#%d,r%d", li(ctx
, 0), a
->rd
);
1120 /* fsub dsp[rs], rd */
1122 static bool trans_FSUB_mr(DisasContext
*ctx
, arg_FSUB_mr
*a
)
1124 prt_ldmi(ctx
, "fsub", a
->ld
, RX_IM_LONG
, a
->rs
, a
->rd
);
1128 /* ftoi dsp[rs], rd */
1130 static bool trans_FTOI(DisasContext
*ctx
, arg_FTOI
*a
)
1132 prt_ldmi(ctx
, "ftoi", a
->ld
, RX_IM_LONG
, a
->rs
, a
->rd
);
1137 static bool trans_FMUL_ir(DisasContext
*ctx
, arg_FMUL_ir
*a
)
1139 prt("fmul\t#%d,r%d", li(ctx
, 0), a
->rd
);
1143 /* fmul dsp[rs], rd */
1145 static bool trans_FMUL_mr(DisasContext
*ctx
, arg_FMUL_mr
*a
)
1147 prt_ldmi(ctx
, "fmul", a
->ld
, RX_IM_LONG
, a
->rs
, a
->rd
);
1152 static bool trans_FDIV_ir(DisasContext
*ctx
, arg_FDIV_ir
*a
)
1154 prt("fdiv\t#%d,r%d", li(ctx
, 0), a
->rd
);
1158 /* fdiv dsp[rs], rd */
1160 static bool trans_FDIV_mr(DisasContext
*ctx
, arg_FDIV_mr
*a
)
1162 prt_ldmi(ctx
, "fdiv", a
->ld
, RX_IM_LONG
, a
->rs
, a
->rd
);
1166 /* round dsp[rs], rd */
1168 static bool trans_ROUND(DisasContext
*ctx
, arg_ROUND
*a
)
1170 prt_ldmi(ctx
, "round", a
->ld
, RX_IM_LONG
, a
->rs
, a
->rd
);
1175 /* itof dsp[rs], rd */
1176 static bool trans_ITOF(DisasContext
*ctx
, arg_ITOF
*a
)
1178 prt_ldmi(ctx
, "itof", a
->ld
, RX_IM_LONG
, a
->rs
, a
->rd
);
1182 #define BOP_IM(name, reg) \
1185 rx_index_addr(ctx, dsp, a->ld, RX_MEMORY_BYTE); \
1186 prt("b%s\t#%d, %s[r%d]", #name, a->imm, dsp, reg); \
1190 #define BOP_RM(name) \
1193 rx_index_addr(ctx, dsp, a->ld, RX_MEMORY_BYTE); \
1194 prt("b%s\tr%d, %s[r%d]", #name, a->rd, dsp, a->rs); \
1198 /* bset #imm, dsp[rd] */
1199 static bool trans_BSET_im(DisasContext
*ctx
, arg_BSET_im
*a
)
1201 BOP_IM(bset
, a
->rs
);
1204 /* bset rs, dsp[rd] */
1205 static bool trans_BSET_rm(DisasContext
*ctx
, arg_BSET_rm
*a
)
1211 static bool trans_BSET_rr(DisasContext
*ctx
, arg_BSET_rr
*a
)
1213 prt("bset\tr%d,r%d", a
->rs
, a
->rd
);
1218 static bool trans_BSET_ir(DisasContext
*ctx
, arg_BSET_ir
*a
)
1220 prt("bset\t#%d, r%d", a
->imm
, a
->rd
);
1224 /* bclr #imm, dsp[rd] */
1225 static bool trans_BCLR_im(DisasContext
*ctx
, arg_BCLR_im
*a
)
1230 /* bclr rs, dsp[rd] */
1231 static bool trans_BCLR_rm(DisasContext
*ctx
, arg_BCLR_rm
*a
)
1237 static bool trans_BCLR_rr(DisasContext
*ctx
, arg_BCLR_rr
*a
)
1239 prt("bclr\tr%d, r%d", a
->rs
, a
->rd
);
1244 static bool trans_BCLR_ir(DisasContext
*ctx
, arg_BCLR_ir
*a
)
1246 prt("bclr\t#%d,r%d", a
->imm
, a
->rd
);
1250 /* btst #imm, dsp[rd] */
1251 static bool trans_BTST_im(DisasContext
*ctx
, arg_BTST_im
*a
)
1256 /* btst rs, dsp[rd] */
1257 static bool trans_BTST_rm(DisasContext
*ctx
, arg_BTST_rm
*a
)
1263 static bool trans_BTST_rr(DisasContext
*ctx
, arg_BTST_rr
*a
)
1265 prt("btst\tr%d, r%d", a
->rs
, a
->rd
);
1270 static bool trans_BTST_ir(DisasContext
*ctx
, arg_BTST_ir
*a
)
1272 prt("btst\t#%d, r%d", a
->imm
, a
->rd
);
1276 /* bnot rs, dsp[rd] */
1277 static bool trans_BNOT_rm(DisasContext
*ctx
, arg_BNOT_rm
*a
)
1283 static bool trans_BNOT_rr(DisasContext
*ctx
, arg_BNOT_rr
*a
)
1285 prt("bnot\tr%d, r%d", a
->rs
, a
->rd
);
1289 /* bnot #imm, dsp[rd] */
1290 static bool trans_BNOT_im(DisasContext
*ctx
, arg_BNOT_im
*a
)
1296 static bool trans_BNOT_ir(DisasContext
*ctx
, arg_BNOT_ir
*a
)
1298 prt("bnot\t#%d, r%d", a
->imm
, a
->rd
);
1302 /* bmcond #imm, dsp[rd] */
1303 static bool trans_BMCnd_im(DisasContext
*ctx
, arg_BMCnd_im
*a
)
1307 rx_index_addr(ctx
, dsp
, a
->ld
, RX_MEMORY_BYTE
);
1308 prt("bm%s\t#%d, %s[r%d]", cond
[a
->cd
], a
->imm
, dsp
, a
->rd
);
1312 /* bmcond #imm, rd */
1313 static bool trans_BMCnd_ir(DisasContext
*ctx
, arg_BMCnd_ir
*a
)
1315 prt("bm%s\t#%d, r%d", cond
[a
->cd
], a
->imm
, a
->rd
);
1320 static bool trans_CLRPSW(DisasContext
*ctx
, arg_CLRPSW
*a
)
1322 prt("clrpsw\t%c", psw
[a
->cb
]);
1327 static bool trans_SETPSW(DisasContext
*ctx
, arg_SETPSW
*a
)
1329 prt("setpsw\t%c", psw
[a
->cb
]);
1334 static bool trans_MVTIPL(DisasContext
*ctx
, arg_MVTIPL
*a
)
1336 prt("movtipl\t#%d", a
->imm
);
1341 static bool trans_MVTC_i(DisasContext
*ctx
, arg_MVTC_i
*a
)
1343 prt("mvtc\t#0x%08x, %s", a
->imm
, rx_crname(a
->cr
));
1348 static bool trans_MVTC_r(DisasContext
*ctx
, arg_MVTC_r
*a
)
1350 prt("mvtc\tr%d, %s", a
->rs
, rx_crname(a
->cr
));
1355 static bool trans_MVFC(DisasContext
*ctx
, arg_MVFC
*a
)
1357 prt("mvfc\t%s, r%d", rx_crname(a
->cr
), a
->rd
);
1362 static bool trans_RTFI(DisasContext
*ctx
, arg_RTFI
*a
)
1369 static bool trans_RTE(DisasContext
*ctx
, arg_RTE
*a
)
1376 static bool trans_BRK(DisasContext
*ctx
, arg_BRK
*a
)
1383 static bool trans_INT(DisasContext
*ctx
, arg_INT
*a
)
1385 prt("int\t#%d", a
->imm
);
1390 static bool trans_WAIT(DisasContext
*ctx
, arg_WAIT
*a
)
1396 /* sccnd.[bwl] rd */
1397 /* sccnd.[bwl] dsp:[rd] */
1398 static bool trans_SCCnd(DisasContext
*ctx
, arg_SCCnd
*a
)
1402 rx_index_addr(ctx
, dsp
, a
->sz
, a
->ld
);
1403 prt("sc%s.%c\t%s[r%d]", cond
[a
->cd
], size
[a
->sz
], dsp
, a
->rd
);
1405 prt("sc%s.%c\tr%d", cond
[a
->cd
], size
[a
->sz
], a
->rd
);
1410 int print_insn_rx(bfd_vma addr
, disassemble_info
*dis
)
1417 ctx
.pc
= ctx
.addr
= addr
;
1420 insn
= decode_load(&ctx
);
1421 if (!decode(&ctx
, insn
)) {
1422 ctx
.dis
->fprintf_func(ctx
.dis
->stream
, ".byte\t");
1423 for (i
= 0; i
< ctx
.addr
- addr
; i
++) {
1425 ctx
.dis
->fprintf_func(ctx
.dis
->stream
, ",");
1427 ctx
.dis
->fprintf_func(ctx
.dis
->stream
, "0x%02x", insn
>> 24);
1431 return ctx
.addr
- addr
;