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