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