25 |
|
|
26 |
|
|
27 |
|
// Instruction fields |
28 |
< |
static int primop, exop, ra, rb, rc, rd; |
28 |
> |
static int primop, exop, vxop, ra, rb, rc, rd; |
29 |
|
static unsigned short imm; |
30 |
|
|
31 |
|
|
96 |
|
|
97 |
|
#define dsform(s) fprintf(f, "%s\tr%d,$%04x(r%d)\n", s, rd, short(imm & 0xfffc), ra) |
98 |
|
|
99 |
+ |
#define xform_vls(s) \ |
100 |
+ |
if (ra == 0) \ |
101 |
+ |
fprintf(f, "%s\tv%d,r%d\n", s, rd, rb); \ |
102 |
+ |
else \ |
103 |
+ |
fprintf(f, "%s\tv%d,r%d,r%d\n", s, rd, ra, rb) |
104 |
|
#define xform_ls(s) \ |
105 |
|
if (ra == 0) \ |
106 |
|
fprintf(f, "%s\tr%d,r%d\n", s, rd, rb); \ |
165 |
|
|
166 |
|
#define mdsform(s) fprintf(f, "%s%s\tr%d,r%d,r%d,%d\n", s, w & 1 ? "." : "", ra, rd, rb, rc | (w & 32 ? 32 : 0)) |
167 |
|
|
168 |
+ |
#define vx_form(s) fprintf(f, "%s\tv%d,v%d,v%d\n", s, rd, ra, rb) |
169 |
+ |
#define vxi_form(s) fprintf(f, "%s\tv%d,v%d,v%d,%d\n", s, rd, ra, rb, (rc & 15)) |
170 |
+ |
#define va_form(s) fprintf(f, "%s\tv%d,v%d,v%d,v%d\n", s, rd, ra, rb, rc) |
171 |
|
|
172 |
|
// Prototypes |
173 |
+ |
static void disass4(FILE *f, unsigned int adr, unsigned int w); |
174 |
|
static void disass19(FILE *f, unsigned int adr, unsigned int w); |
175 |
|
static void disass31(FILE *f, unsigned int adr, unsigned int w); |
176 |
|
static void disass59(FILE *f, unsigned int adr, unsigned int w); |
192 |
|
rb = w >> 11 & 0x1f; |
193 |
|
rc = w >> 6 & 0x1f; |
194 |
|
exop = w >> 1 & 0x3ff; |
195 |
+ |
vxop = w & 0x7ff; |
196 |
|
imm = w & 0xffff; |
197 |
|
|
198 |
|
// Decode primary opcode |
211 |
|
dform_to("twi"); |
212 |
|
break; |
213 |
|
|
214 |
< |
// case 4: // AltiVec |
214 |
> |
case 4: // AltiVec |
215 |
> |
disass4(f, adr, w); |
216 |
> |
break; |
217 |
|
|
218 |
|
case 7: dform_simm("mulli"); break; |
219 |
|
case 8: dform_simm("subfic"); break; |
405 |
|
|
406 |
|
|
407 |
|
/* |
408 |
+ |
* Disassemble instruction with primary opcode = 4 (VX-Form) |
409 |
+ |
*/ |
410 |
+ |
|
411 |
+ |
static void disass4(FILE *f, unsigned int adr, unsigned int w) |
412 |
+ |
{ |
413 |
+ |
switch (vxop) { |
414 |
+ |
case 384: vx_form("vaddcuw"); break; |
415 |
+ |
case 10: vx_form("vaddfp"); break; |
416 |
+ |
case 768: vx_form("vaddsbs"); break; |
417 |
+ |
case 832: vx_form("vaddshs"); break; |
418 |
+ |
case 896: vx_form("vaddsws"); break; |
419 |
+ |
case 0: vx_form("vaddubm"); break; |
420 |
+ |
case 512: vx_form("vaddubs"); break; |
421 |
+ |
case 64: vx_form("vadduhm"); break; |
422 |
+ |
case 576: vx_form("vadduhs"); break; |
423 |
+ |
case 128: vx_form("vadduwm"); break; |
424 |
+ |
case 640: vx_form("vadduws"); break; |
425 |
+ |
case 1028: vx_form("vand"); break; |
426 |
+ |
case 1092: vx_form("vandc"); break; |
427 |
+ |
case 1282: vx_form("vavgsb"); break; |
428 |
+ |
case 1346: vx_form("vavgsh"); break; |
429 |
+ |
case 1410: vx_form("vavgsw"); break; |
430 |
+ |
case 1026: vx_form("vavgub"); break; |
431 |
+ |
case 1090: vx_form("vavguh"); break; |
432 |
+ |
case 1154: vx_form("vavguw"); break; |
433 |
+ |
case 1034: vx_form("vmaxfp"); break; |
434 |
+ |
case 258: vx_form("vmaxsb"); break; |
435 |
+ |
case 322: vx_form("vmaxsh"); break; |
436 |
+ |
case 386: vx_form("vmaxsw"); break; |
437 |
+ |
case 2: vx_form("vmaxub"); break; |
438 |
+ |
case 66: vx_form("vmaxus"); break; |
439 |
+ |
case 130: vx_form("vmaxuw"); break; |
440 |
+ |
case 1098: vx_form("vminfp"); break; |
441 |
+ |
case 770: vx_form("vminsb"); break; |
442 |
+ |
case 834: vx_form("vminsh"); break; |
443 |
+ |
case 898: vx_form("vminsw"); break; |
444 |
+ |
case 514: vx_form("vminub"); break; |
445 |
+ |
case 578: vx_form("vminuh"); break; |
446 |
+ |
case 642: vx_form("vminuw"); break; |
447 |
+ |
case 12: vx_form("vmrghb"); break; |
448 |
+ |
case 76: vx_form("vmrghh"); break; |
449 |
+ |
case 140: vx_form("vmrghw"); break; |
450 |
+ |
case 268: vx_form("vmrglb"); break; |
451 |
+ |
case 332: vx_form("vmrglh"); break; |
452 |
+ |
case 396: vx_form("vmrglw"); break; |
453 |
+ |
case 776: vx_form("vmulesb"); break; |
454 |
+ |
case 840: vx_form("vmulesh"); break; |
455 |
+ |
case 520: vx_form("vmuleub"); break; |
456 |
+ |
case 584: vx_form("vmuleuh"); break; |
457 |
+ |
case 264: vx_form("vmulosb"); break; |
458 |
+ |
case 328: vx_form("vmulosh"); break; |
459 |
+ |
case 8: vx_form("vmuloub"); break; |
460 |
+ |
case 72: vx_form("vmulouh"); break; |
461 |
+ |
case 1284: vx_form("vnor"); break; |
462 |
+ |
case 1156: vx_form("vor"); break; |
463 |
+ |
case 1220: vx_form("vxor"); break; |
464 |
+ |
case 782: vx_form("vpkpx"); break; |
465 |
+ |
case 398: vx_form("vpkshss"); break; |
466 |
+ |
case 270: vx_form("vpkshus"); break; |
467 |
+ |
case 462: vx_form("vpkswss"); break; |
468 |
+ |
case 334: vx_form("vpkswus"); break; |
469 |
+ |
case 14: vx_form("vpkuhum"); break; |
470 |
+ |
case 142: vx_form("vpkuhus"); break; |
471 |
+ |
case 78: vx_form("vpkuwum"); break; |
472 |
+ |
case 206: vx_form("vpkuwus"); break; |
473 |
+ |
case 4: vx_form("vrlb"); break; |
474 |
+ |
case 68: vx_form("vrlh"); break; |
475 |
+ |
case 132: vx_form("vrlw"); break; |
476 |
+ |
case 452: vx_form("vsl"); break; |
477 |
+ |
case 260: vx_form("vslb"); break; |
478 |
+ |
case 324: vx_form("vslh"); break; |
479 |
+ |
case 1036: vx_form("vslo"); break; |
480 |
+ |
case 388: vx_form("vslw"); break; |
481 |
+ |
case 708: vx_form("vsr"); break; |
482 |
+ |
case 772: vx_form("vsrab"); break; |
483 |
+ |
case 836: vx_form("vsrah"); break; |
484 |
+ |
case 900: vx_form("vsraw"); break; |
485 |
+ |
case 516: vx_form("vsrb"); break; |
486 |
+ |
case 580: vx_form("vsrh"); break; |
487 |
+ |
case 1100: vx_form("vsro"); break; |
488 |
+ |
case 644: vx_form("vsrw"); break; |
489 |
+ |
case 1408: vx_form("vsubcuw"); break; |
490 |
+ |
case 74: vx_form("vsubfp"); break; |
491 |
+ |
case 1792: vx_form("vsubsbs"); break; |
492 |
+ |
case 1856: vx_form("vsubshs"); break; |
493 |
+ |
case 1920: vx_form("vsubsws"); break; |
494 |
+ |
case 1024: vx_form("vsububm"); break; |
495 |
+ |
case 1536: vx_form("vsububs"); break; |
496 |
+ |
case 1088: vx_form("vsubuhm"); break; |
497 |
+ |
case 1600: vx_form("vsubuhs"); break; |
498 |
+ |
case 1152: vx_form("vsubuwm"); break; |
499 |
+ |
case 1664: vx_form("vsubuws"); break; |
500 |
+ |
case 1928: vx_form("vsumsws"); break; |
501 |
+ |
case 1672: vx_form("vsum2sws"); break; |
502 |
+ |
case 1800: vx_form("vsum4sbs"); break; |
503 |
+ |
case 1608: vx_form("vsum4shs"); break; |
504 |
+ |
case 1544: vx_form("vsum4ubs"); break; |
505 |
+ |
default: |
506 |
+ |
if ((vxop & 0x43f) == 44) { |
507 |
+ |
vxi_form("vsldoi"); |
508 |
+ |
break; |
509 |
+ |
} |
510 |
+ |
fprintf(f, "?\n"); |
511 |
+ |
break; |
512 |
+ |
} |
513 |
+ |
} |
514 |
+ |
|
515 |
+ |
|
516 |
+ |
/* |
517 |
|
* Disassemble instruction with primary opcode = 19 (XL-Form) |
518 |
|
*/ |
519 |
|
|
615 |
|
xform_to("tw"); |
616 |
|
break; |
617 |
|
|
618 |
+ |
case 6: xform_vls("lvsl"); break; |
619 |
+ |
case 7: xform_vls("lvebx"); break; |
620 |
|
case 8: xoform_dab("subfc"); break; |
621 |
|
case 8+512: xoform_dab("subfco"); break; |
622 |
|
case 9: case 9+512: xoform_dab("mulhdu"); break; // 64 bit |
639 |
|
xform_crlab("cmplw"); |
640 |
|
break; |
641 |
|
|
642 |
+ |
case 38: xform_vls("lvsr"); break; |
643 |
+ |
case 39: xform_vls("lvehx"); break; |
644 |
|
case 40: xoform_dab("subf"); break; |
645 |
|
case 40+512: xoform_dab("subfo"); break; |
646 |
|
case 53: xform_ls("ldux"); break; // 64 bit |
656 |
|
xform_to("td"); |
657 |
|
break; |
658 |
|
|
659 |
+ |
case 71: xform_vls("lvewx"); break; |
660 |
|
case 73: case 73+512: xoform_dab("mulhd"); break; // 64 bit |
661 |
|
case 75: case 75+512: xoform_dab("mulhw"); break; |
662 |
|
case 83: xform_d("mfmsr"); break; |
663 |
|
case 84: xform_ls("ldarx"); break; // 64 bit |
664 |
|
case 86: xform_ab("dcbf"); break; |
665 |
|
case 87: xform_ls("lbzx"); break; |
666 |
+ |
case 103: xform_vls("lvx"); break; |
667 |
|
case 104: xoform_da("neg"); break; |
668 |
|
case 104+512: xoform_da("nego"); break; |
669 |
|
case 119: xform_ls("lbzux"); break; |
675 |
|
xform_sabc("nor"); |
676 |
|
break; |
677 |
|
|
678 |
+ |
case 135: xform_vls("stvebx"); break; |
679 |
|
case 136: xoform_dab("subfe"); break; |
680 |
|
case 136+512: xoform_dab("subfeo"); break; |
681 |
|
case 138: xoform_dab("adde"); break; |
692 |
|
break; |
693 |
|
|
694 |
|
case 151: xform_ls("stwx"); break; |
695 |
+ |
case 167: xform_vls("stvehx"); break; |
696 |
|
case 181: xform_ls("stdux"); break; // 64 bit |
697 |
|
case 183: xform_ls("stwux"); break; |
698 |
+ |
case 199: xform_vls("stvewx"); break; |
699 |
|
case 200: xoform_da("subfze"); break; |
700 |
|
case 200+512: xoform_da("subfzeo"); break; |
701 |
|
case 202: xoform_da("addze"); break; |
710 |
|
break; |
711 |
|
|
712 |
|
case 215: xform_ls("stbx"); break; |
713 |
+ |
case 231: xform_vls("stvx"); break; |
714 |
|
case 232: xoform_da("subfme"); break; |
715 |
|
case 232+512: xoform_da("subfmeo"); break; |
716 |
|
case 233: xoform_dab("mulld"); break; // 64 bit |
739 |
|
fprintf(f, "mflr\tr%d\n", rd); |
740 |
|
else if ((ra | (rb << 5)) == 9) |
741 |
|
fprintf(f, "mfctr\tr%d\n", rd); |
742 |
+ |
else if ((ra | (rb << 5)) == 256) |
743 |
+ |
fprintf(f, "mfvrsave\tr%d\n", rd); |
744 |
|
else { |
745 |
|
char *spr = get_spr(ra | (rb << 5)); |
746 |
|
if (spr) |
752 |
|
|
753 |
|
case 341: xform_ls("lwax"); break; // 64 bit |
754 |
|
case 343: xform_ls("lhax"); break; |
755 |
+ |
case 359: xform_vls("lvxl"); break; |
756 |
|
case 370: xform("tlbia"); break; |
757 |
|
|
758 |
|
case 371: |
791 |
|
fprintf(f, "mtlr\tr%d\n", rd); |
792 |
|
else if ((ra | (rb << 5)) == 9) |
793 |
|
fprintf(f, "mtctr\tr%d\n", rd); |
794 |
+ |
else if ((ra | (rb << 5)) == 256) |
795 |
+ |
fprintf(f, "mtvrsave\tr%d\n", rd); |
796 |
|
else { |
797 |
|
char *spr = get_spr(ra | (rb << 5)); |
798 |
|
if (spr) |
804 |
|
|
805 |
|
case 470: xform_ab("dcbi"); break; |
806 |
|
case 476: xform_sabc("nand"); break; |
807 |
+ |
case 487: xform_vls("stvxl"); break; |
808 |
|
case 489: xoform_dab("divd"); break; // 64 bit |
809 |
|
case 489+512: xoform_dab("divdo"); break; // 64 bit |
810 |
|
case 491: xoform_dab("divw"); break; |