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