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 } 1433