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