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-insns.c.inc" 104 105 static 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) 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 130 static const char size[] = {'b', 'w', 'l'}; 131 static const char cond[][4] = { 132 "eq", "ne", "c", "nc", "gtu", "leu", "pz", "n", 133 "ge", "lt", "gt", "le", "o", "no", "ra", "f" 134 }; 135 static const char psw[] = { 136 'c', 'z', 's', 'o', 0, 0, 0, 0, 137 'i', 'u', 0, 0, 0, 0, 0, 0, 138 }; 139 140 static void rx_index_addr(DisasContext *ctx, char out[8], int ld, int mi) 141 { 142 uint32_t addr = ctx->addr; 143 uintptr_t len = ctx->len; 144 uint16_t dsp; 145 146 switch (ld) { 147 case 0: 148 /* No index; return empty string. */ 149 out[0] = '\0'; 150 return; 151 case 1: 152 g_assert(len + 1 <= ARRAY_SIZE(ctx->bytes)); 153 ctx->addr += 1; 154 ctx->len += 1; 155 ctx->dis->read_memory_func(addr, ctx->bytes + len, 1, ctx->dis); 156 dsp = ctx->bytes[len]; 157 break; 158 case 2: 159 g_assert(len + 2 <= ARRAY_SIZE(ctx->bytes)); 160 ctx->addr += 2; 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); 164 break; 165 default: 166 g_assert_not_reached(); 167 } 168 169 sprintf(out, "%u", dsp << (mi < 3 ? mi : 4 - mi)); 170 } 171 172 static void prt_ldmi(DisasContext *ctx, const char *insn, 173 int ld, int mi, int rs, int rd) 174 { 175 static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"}; 176 char dsp[8]; 177 178 if (ld < 3) { 179 rx_index_addr(ctx, dsp, ld, mi); 180 prt("%s\t%s[r%d]%s, r%d", insn, dsp, rs, sizes[mi], rd); 181 } else { 182 prt("%s\tr%d, r%d", insn, rs, rd); 183 } 184 } 185 186 static 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] */ 196 static 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 */ 209 static 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 */ 224 static 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] */ 232 static 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 */ 245 static 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] */ 252 static 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 */ 263 static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a) 264 { 265 char dspd[8], dsps[8], szc = size[a->sz]; 266 267 if (a->lds == 3 && a->ldd == 3) { 268 /* mov.[bwl] rs,rd */ 269 prt("mov.%c\tr%d, r%d", szc, a->rs, a->rd); 270 } else if (a->lds == 3) { 271 rx_index_addr(ctx, dspd, a->ldd, a->sz); 272 prt("mov.%c\tr%d, %s[r%d]", szc, a->rs, dspd, a->rd); 273 } else if (a->ldd == 3) { 274 rx_index_addr(ctx, dsps, a->lds, a->sz); 275 prt("mov.%c\t%s[r%d], r%d", szc, dsps, a->rs, a->rd); 276 } else { 277 rx_index_addr(ctx, dsps, a->lds, a->sz); 278 rx_index_addr(ctx, dspd, a->ldd, a->sz); 279 prt("mov.%c\t%s[r%d], %s[r%d]", szc, dsps, a->rs, dspd, a->rd); 280 } 281 return true; 282 } 283 284 /* mov.[bwl] rs,[rd+] */ 285 /* mov.[bwl] rs,[-rd] */ 286 static bool trans_MOV_rp(DisasContext *ctx, arg_MOV_rp *a) 287 { 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 } 293 return true; 294 } 295 296 /* mov.[bwl] [rd+],rs */ 297 /* mov.[bwl] [-rd],rs */ 298 static bool trans_MOV_pr(DisasContext *ctx, arg_MOV_pr *a) 299 { 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 } 305 return true; 306 } 307 308 /* movu.[bw] dsp5:[rs],rd */ 309 static 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 */ 321 static 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 */ 328 static 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 */ 336 static bool trans_MOVU_pr(DisasContext *ctx, arg_MOVU_pr *a) 337 { 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 } 343 return true; 344 } 345 346 /* pop rd */ 347 static bool trans_POP(DisasContext *ctx, arg_POP *a) 348 { 349 prt("pop\tr%d", a->rd); 350 return true; 351 } 352 353 /* popc rx */ 354 static 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 */ 361 static 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 */ 368 static 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] */ 375 static bool trans_PUSH_m(DisasContext *ctx, arg_PUSH_m *a) 376 { 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); 381 return true; 382 } 383 384 /* pushc rx */ 385 static 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*/ 392 static 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 */ 399 static 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 */ 405 static bool trans_XCHG_mr(DisasContext *ctx, arg_XCHG_mr *a) 406 { 407 prt_ldmi(ctx, "xchg", a->ld, a->mi, a->rs, a->rd); 408 return true; 409 } 410 411 /* stz #imm,rd */ 412 static 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 */ 419 static 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 */ 426 static 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 */ 433 static 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 */ 441 static 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 */ 449 static bool trans_AND_mr(DisasContext *ctx, arg_AND_mr *a) 450 { 451 prt_ldmi(ctx, "and", a->ld, a->mi, a->rs, a->rd); 452 return true; 453 } 454 455 /* and rs,rs2,rd */ 456 static 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 */ 464 static 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 */ 472 static bool trans_OR_mr(DisasContext *ctx, arg_OR_mr *a) 473 { 474 prt_ldmi(ctx, "or", a->ld, a->mi, a->rs, a->rd); 475 return true; 476 } 477 478 /* or rs,rs2,rd */ 479 static 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 */ 486 static 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 */ 494 static bool trans_XOR_mr(DisasContext *ctx, arg_XOR_mr *a) 495 { 496 prt_ldmi(ctx, "xor", a->ld, a->mi, a->rs, a->rd); 497 return true; 498 } 499 500 /* tst #imm, rd */ 501 static 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 */ 509 static bool trans_TST_mr(DisasContext *ctx, arg_TST_mr *a) 510 { 511 prt_ldmi(ctx, "tst", a->ld, a->mi, a->rs, a->rd); 512 return true; 513 } 514 515 /* not rd */ 516 /* not rs, rd */ 517 static bool trans_NOT_rr(DisasContext *ctx, arg_NOT_rr *a) 518 { 519 if (a->rs != a->rd) { 520 prt("not\tr%d, r%d", a->rs, a->rd); 521 } else { 522 prt("not\tr%d", a->rs); 523 } 524 return true; 525 } 526 527 /* neg rd */ 528 /* neg rs, rd */ 529 static bool trans_NEG_rr(DisasContext *ctx, arg_NEG_rr *a) 530 { 531 if (a->rs != a->rd) { 532 prt("neg\tr%d, r%d", a->rs, a->rd); 533 } else { 534 prt("neg\tr%d", a->rs); 535 } 536 return true; 537 } 538 539 /* adc #imm, rd */ 540 static 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 */ 547 static 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 */ 554 static bool trans_ADC_mr(DisasContext *ctx, arg_ADC_mr *a) 555 { 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); 560 return true; 561 } 562 563 /* add #uimm4, rd */ 564 /* add #imm, rs, rd */ 565 static 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 */ 577 static bool trans_ADD_mr(DisasContext *ctx, arg_ADD_mr *a) 578 { 579 prt_ldmi(ctx, "add", a->ld, a->mi, a->rs, a->rd); 580 return true; 581 } 582 583 /* add rs, rs2, rd */ 584 static 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 */ 593 static 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 */ 601 static bool trans_CMP_mr(DisasContext *ctx, arg_CMP_mr *a) 602 { 603 prt_ldmi(ctx, "cmp", a->ld, a->mi, a->rs, a->rd); 604 return true; 605 } 606 607 /* sub #imm4, rd */ 608 static 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 */ 616 static bool trans_SUB_mr(DisasContext *ctx, arg_SUB_mr *a) 617 { 618 prt_ldmi(ctx, "sub", a->ld, a->mi, a->rs, a->rd); 619 return true; 620 } 621 622 /* sub rs, rs2, rd */ 623 static 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 */ 630 static 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 */ 637 static bool trans_SBB_mr(DisasContext *ctx, arg_SBB_mr *a) 638 { 639 prt_ldmi(ctx, "sbb", a->ld, RX_IM_LONG, a->rs, a->rd); 640 return true; 641 } 642 643 /* abs rd */ 644 /* abs rs, rd */ 645 static bool trans_ABS_rr(DisasContext *ctx, arg_ABS_rr *a) 646 { 647 if (a->rs != a->rd) { 648 prt("abs\tr%d, r%d", a->rs, a->rd); 649 } else { 650 prt("abs\tr%d", a->rs); 651 } 652 return true; 653 } 654 655 /* max #imm, rd */ 656 static 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 */ 664 static bool trans_MAX_mr(DisasContext *ctx, arg_MAX_mr *a) 665 { 666 prt_ldmi(ctx, "max", a->ld, a->mi, a->rs, a->rd); 667 return true; 668 } 669 670 /* min #imm, rd */ 671 static 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 */ 679 static bool trans_MIN_mr(DisasContext *ctx, arg_MIN_mr *a) 680 { 681 prt_ldmi(ctx, "min", a->ld, a->mi, a->rs, a->rd); 682 return true; 683 } 684 685 /* mul #uimm4, rd */ 686 /* mul #imm, rd */ 687 static 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 */ 695 static bool trans_MUL_mr(DisasContext *ctx, arg_MUL_mr *a) 696 { 697 prt_ldmi(ctx, "mul", a->ld, a->mi, a->rs, a->rd); 698 return true; 699 } 700 701 /* mul rs, rs2, rd */ 702 static 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 */ 709 static 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 */ 717 static bool trans_EMUL_mr(DisasContext *ctx, arg_EMUL_mr *a) 718 { 719 prt_ldmi(ctx, "emul", a->ld, a->mi, a->rs, a->rd); 720 return true; 721 } 722 723 /* emulu #imm, rd */ 724 static 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 */ 732 static bool trans_EMULU_mr(DisasContext *ctx, arg_EMULU_mr *a) 733 { 734 prt_ldmi(ctx, "emulu", a->ld, a->mi, a->rs, a->rd); 735 return true; 736 } 737 738 /* div #imm, rd */ 739 static 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 */ 747 static bool trans_DIV_mr(DisasContext *ctx, arg_DIV_mr *a) 748 { 749 prt_ldmi(ctx, "div", a->ld, a->mi, a->rs, a->rd); 750 return true; 751 } 752 753 /* divu #imm, rd */ 754 static 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 */ 762 static bool trans_DIVU_mr(DisasContext *ctx, arg_DIVU_mr *a) 763 { 764 prt_ldmi(ctx, "divu", a->ld, a->mi, a->rs, a->rd); 765 return true; 766 } 767 768 769 /* shll #imm:5, rd */ 770 /* shll #imm:5, rs, rd */ 771 static bool trans_SHLL_irr(DisasContext *ctx, arg_SHLL_irr *a) 772 { 773 if (a->rs2 != a->rd) { 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); 777 } 778 return true; 779 } 780 781 /* shll rs, rd */ 782 static 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 */ 790 static bool trans_SHAR_irr(DisasContext *ctx, arg_SHAR_irr *a) 791 { 792 if (a->rs2 != a->rd) { 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); 796 } 797 return true; 798 } 799 800 /* shar rs, rd */ 801 static 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 */ 809 static bool trans_SHLR_irr(DisasContext *ctx, arg_SHLR_irr *a) 810 { 811 if (a->rs2 != a->rd) { 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); 815 } 816 return true; 817 } 818 819 /* shlr rs, rd */ 820 static 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 */ 827 static bool trans_ROLC(DisasContext *ctx, arg_ROLC *a) 828 { 829 prt("rorc\tr%d", a->rd); 830 return true; 831 } 832 833 /* rorc rd */ 834 static 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 */ 841 static 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 */ 848 static 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 */ 855 static 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 */ 862 static 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 */ 869 static 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 */ 876 static 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 */ 883 static 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 */ 898 static 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 */ 908 static 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 */ 915 static 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 */ 922 static bool trans_JMP(DisasContext *ctx, arg_JMP *a) 923 { 924 prt("jmp\tr%d", a->rs); 925 return true; 926 } 927 928 /* jsr rs */ 929 static 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 */ 937 static 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 */ 945 static 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 */ 952 static bool trans_RTS(DisasContext *ctx, arg_RTS *a) 953 { 954 prt("rts"); 955 return true; 956 } 957 958 /* nop */ 959 static bool trans_NOP(DisasContext *ctx, arg_NOP *a) 960 { 961 prt("nop"); 962 return true; 963 } 964 965 /* scmpu */ 966 static bool trans_SCMPU(DisasContext *ctx, arg_SCMPU *a) 967 { 968 prt("scmpu"); 969 return true; 970 } 971 972 /* smovu */ 973 static bool trans_SMOVU(DisasContext *ctx, arg_SMOVU *a) 974 { 975 prt("smovu"); 976 return true; 977 } 978 979 /* smovf */ 980 static bool trans_SMOVF(DisasContext *ctx, arg_SMOVF *a) 981 { 982 prt("smovf"); 983 return true; 984 } 985 986 /* smovb */ 987 static bool trans_SMOVB(DisasContext *ctx, arg_SMOVB *a) 988 { 989 prt("smovb"); 990 return true; 991 } 992 993 /* suntile */ 994 static bool trans_SUNTIL(DisasContext *ctx, arg_SUNTIL *a) 995 { 996 prt("suntil.%c", size[a->sz]); 997 return true; 998 } 999 1000 /* swhile */ 1001 static bool trans_SWHILE(DisasContext *ctx, arg_SWHILE *a) 1002 { 1003 prt("swhile.%c", size[a->sz]); 1004 return true; 1005 } 1006 /* sstr */ 1007 static bool trans_SSTR(DisasContext *ctx, arg_SSTR *a) 1008 { 1009 prt("sstr.%c", size[a->sz]); 1010 return true; 1011 } 1012 1013 /* rmpa */ 1014 static 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 */ 1021 static 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 */ 1028 static 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 */ 1035 static 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 */ 1042 static 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 */ 1049 static bool trans_MVFACHI(DisasContext *ctx, arg_MVFACHI *a) 1050 { 1051 prt("mvfachi\tr%d", a->rd); 1052 return true; 1053 } 1054 1055 /* mvfacmi rd */ 1056 static bool trans_MVFACMI(DisasContext *ctx, arg_MVFACMI *a) 1057 { 1058 prt("mvfacmi\tr%d", a->rd); 1059 return true; 1060 } 1061 1062 /* mvtachi rs */ 1063 static bool trans_MVTACHI(DisasContext *ctx, arg_MVTACHI *a) 1064 { 1065 prt("mvtachi\tr%d", a->rs); 1066 return true; 1067 } 1068 1069 /* mvtaclo rs */ 1070 static bool trans_MVTACLO(DisasContext *ctx, arg_MVTACLO *a) 1071 { 1072 prt("mvtaclo\tr%d", a->rs); 1073 return true; 1074 } 1075 1076 /* racw #imm */ 1077 static 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 */ 1084 static bool trans_SAT(DisasContext *ctx, arg_SAT *a) 1085 { 1086 prt("sat\tr%d", a->rd); 1087 return true; 1088 } 1089 1090 /* satr */ 1091 static bool trans_SATR(DisasContext *ctx, arg_SATR *a) 1092 { 1093 prt("satr"); 1094 return true; 1095 } 1096 1097 /* fadd #imm, rd */ 1098 static 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 */ 1106 static bool trans_FADD_mr(DisasContext *ctx, arg_FADD_mr *a) 1107 { 1108 prt_ldmi(ctx, "fadd", a->ld, RX_IM_LONG, a->rs, a->rd); 1109 return true; 1110 } 1111 1112 /* fcmp #imm, rd */ 1113 static 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 */ 1121 static bool trans_FCMP_mr(DisasContext *ctx, arg_FCMP_mr *a) 1122 { 1123 prt_ldmi(ctx, "fcmp", a->ld, RX_IM_LONG, a->rs, a->rd); 1124 return true; 1125 } 1126 1127 /* fsub #imm, rd */ 1128 static 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 */ 1136 static bool trans_FSUB_mr(DisasContext *ctx, arg_FSUB_mr *a) 1137 { 1138 prt_ldmi(ctx, "fsub", a->ld, RX_IM_LONG, a->rs, a->rd); 1139 return true; 1140 } 1141 1142 /* ftoi dsp[rs], rd */ 1143 /* ftoi rs, rd */ 1144 static bool trans_FTOI(DisasContext *ctx, arg_FTOI *a) 1145 { 1146 prt_ldmi(ctx, "ftoi", a->ld, RX_IM_LONG, a->rs, a->rd); 1147 return true; 1148 } 1149 1150 /* fmul #imm, rd */ 1151 static 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 */ 1159 static bool trans_FMUL_mr(DisasContext *ctx, arg_FMUL_mr *a) 1160 { 1161 prt_ldmi(ctx, "fmul", a->ld, RX_IM_LONG, a->rs, a->rd); 1162 return true; 1163 } 1164 1165 /* fdiv #imm, rd */ 1166 static 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 */ 1174 static bool trans_FDIV_mr(DisasContext *ctx, arg_FDIV_mr *a) 1175 { 1176 prt_ldmi(ctx, "fdiv", a->ld, RX_IM_LONG, a->rs, a->rd); 1177 return true; 1178 } 1179 1180 /* round dsp[rs], rd */ 1181 /* round rs, rd */ 1182 static bool trans_ROUND(DisasContext *ctx, arg_ROUND *a) 1183 { 1184 prt_ldmi(ctx, "round", a->ld, RX_IM_LONG, a->rs, a->rd); 1185 return true; 1186 } 1187 1188 /* itof rs, rd */ 1189 /* itof dsp[rs], rd */ 1190 static bool trans_ITOF(DisasContext *ctx, arg_ITOF *a) 1191 { 1192 prt_ldmi(ctx, "itof", a->ld, RX_IM_LONG, a->rs, a->rd); 1193 return true; 1194 } 1195 1196 #define BOP_IM(name, reg) \ 1197 do { \ 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); \ 1201 return true; \ 1202 } while (0) 1203 1204 #define BOP_RM(name) \ 1205 do { \ 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); \ 1209 return true; \ 1210 } while (0) 1211 1212 /* bset #imm, dsp[rd] */ 1213 static bool trans_BSET_im(DisasContext *ctx, arg_BSET_im *a) 1214 { 1215 BOP_IM(bset, a->rs); 1216 } 1217 1218 /* bset rs, dsp[rd] */ 1219 static bool trans_BSET_rm(DisasContext *ctx, arg_BSET_rm *a) 1220 { 1221 BOP_RM(set); 1222 } 1223 1224 /* bset rs, rd */ 1225 static 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 */ 1232 static 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] */ 1239 static bool trans_BCLR_im(DisasContext *ctx, arg_BCLR_im *a) 1240 { 1241 BOP_IM(clr, a->rs); 1242 } 1243 1244 /* bclr rs, dsp[rd] */ 1245 static bool trans_BCLR_rm(DisasContext *ctx, arg_BCLR_rm *a) 1246 { 1247 BOP_RM(clr); 1248 } 1249 1250 /* bclr rs, rd */ 1251 static 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 */ 1258 static 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] */ 1265 static bool trans_BTST_im(DisasContext *ctx, arg_BTST_im *a) 1266 { 1267 BOP_IM(tst, a->rs); 1268 } 1269 1270 /* btst rs, dsp[rd] */ 1271 static bool trans_BTST_rm(DisasContext *ctx, arg_BTST_rm *a) 1272 { 1273 BOP_RM(tst); 1274 } 1275 1276 /* btst rs, rd */ 1277 static 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 */ 1284 static 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] */ 1291 static bool trans_BNOT_rm(DisasContext *ctx, arg_BNOT_rm *a) 1292 { 1293 BOP_RM(not); 1294 } 1295 1296 /* bnot rs, rd */ 1297 static 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] */ 1304 static bool trans_BNOT_im(DisasContext *ctx, arg_BNOT_im *a) 1305 { 1306 BOP_IM(not, a->rs); 1307 } 1308 1309 /* bnot #imm, rd */ 1310 static 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] */ 1317 static bool trans_BMCnd_im(DisasContext *ctx, arg_BMCnd_im *a) 1318 { 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); 1323 return true; 1324 } 1325 1326 /* bmcond #imm, rd */ 1327 static 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 */ 1334 static 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 */ 1341 static 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 */ 1348 static 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 */ 1355 static 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 */ 1362 static 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 */ 1369 static 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 */ 1376 static bool trans_RTFI(DisasContext *ctx, arg_RTFI *a) 1377 { 1378 prt("rtfi"); 1379 return true; 1380 } 1381 1382 /* rte */ 1383 static bool trans_RTE(DisasContext *ctx, arg_RTE *a) 1384 { 1385 prt("rte"); 1386 return true; 1387 } 1388 1389 /* brk */ 1390 static bool trans_BRK(DisasContext *ctx, arg_BRK *a) 1391 { 1392 prt("brk"); 1393 return true; 1394 } 1395 1396 /* int #imm */ 1397 static bool trans_INT(DisasContext *ctx, arg_INT *a) 1398 { 1399 prt("int\t#%d", a->imm); 1400 return true; 1401 } 1402 1403 /* wait */ 1404 static 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] */ 1412 static bool trans_SCCnd(DisasContext *ctx, arg_SCCnd *a) 1413 { 1414 if (a->ld < 3) { 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); 1418 } else { 1419 prt("sc%s.%c\tr%d", cond[a->cd], size[a->sz], a->rd); 1420 } 1421 return true; 1422 } 1423 1424 int print_insn_rx(bfd_vma addr, disassemble_info *dis) 1425 { 1426 DisasContext ctx; 1427 uint32_t insn; 1428 int i; 1429 1430 ctx.dis = dis; 1431 ctx.pc = ctx.addr = addr; 1432 ctx.len = 0; 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 } 1447