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