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