20 #include "Disassembler.h" 21 #include "pedigree/kernel/Log.h" 23 const char *g_pRegisters[32] = {
24 "r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r8",
"r9",
"r10",
25 "r11",
"r12",
"r13",
"r14",
"r15",
"r16",
"r17",
"r18",
"r19",
"r20",
"r21",
26 "r22",
"r23",
"r24",
"r25",
"r26",
"r27",
"r28",
"r29",
"r30",
"r31"};
30 PPCDelegate ppcLookupTable[] = {
31 &PPCDisassembler::null,
32 &PPCDisassembler::null, &PPCDisassembler::null,
34 &PPCDisassembler::null, &PPCDisassembler::null,
35 &PPCDisassembler::mulli, &PPCDisassembler::subfic,
36 &PPCDisassembler::null, &PPCDisassembler::cmpli,
37 &PPCDisassembler::cmpi, &PPCDisassembler::addic,
38 &PPCDisassembler::addic_dot, &PPCDisassembler::addi,
39 &PPCDisassembler::addis,
42 &PPCDisassembler::sc, &PPCDisassembler::b,
43 &PPCDisassembler::op13, &PPCDisassembler::rlwimi,
44 &PPCDisassembler::rlwinm, &PPCDisassembler::null,
45 &PPCDisassembler::rlwnm, &PPCDisassembler::ori,
46 &PPCDisassembler::oris, &PPCDisassembler::xori,
47 &PPCDisassembler::xoris, &PPCDisassembler::andi_dot,
48 &PPCDisassembler::andis_dot, &PPCDisassembler::op1e,
49 &PPCDisassembler::op1f,
51 &PPCDisassembler::lwz,
52 &PPCDisassembler::lwzu, &PPCDisassembler::lbz,
53 &PPCDisassembler::lbzu, &PPCDisassembler::stw,
54 &PPCDisassembler::stwu, &PPCDisassembler::stb,
55 &PPCDisassembler::stbu, &PPCDisassembler::lhz,
56 &PPCDisassembler::lhzu, &PPCDisassembler::lha,
57 &PPCDisassembler::lhau, &PPCDisassembler::sth,
58 &PPCDisassembler::sthu, &PPCDisassembler::lmw,
59 &PPCDisassembler::stmw,
61 &PPCDisassembler::lfs,
62 &PPCDisassembler::lfsu, &PPCDisassembler::lfd,
63 &PPCDisassembler::lfdu, &PPCDisassembler::stfs,
64 &PPCDisassembler::stfsu, &PPCDisassembler::stfd,
65 &PPCDisassembler::stfdu, &PPCDisassembler::null,
66 &PPCDisassembler::null, &PPCDisassembler::op3a,
67 &PPCDisassembler::op3b, &PPCDisassembler::null,
68 &PPCDisassembler::null, &PPCDisassembler::op3e,
69 &PPCDisassembler::op3f,
72 PPCDisassembler::PPCDisassembler() : m_nLocation(0)
76 PPCDisassembler::~PPCDisassembler()
96 uint32_t nInstruction = *
reinterpret_cast<uint32_t *
>(
m_nLocation);
100 insn.integer = nInstruction;
102 PPCDelegate delegate = ppcLookupTable[insn.i.opcode];
103 (this->*delegate)(insn, text);
106 #define SIGNED_D_OP(mnemonic) \ 111 text += g_pRegisters[insn.d.d]; \ 113 text += g_pRegisters[insn.d.a]; \ 115 text.append(static_cast<int16_t>(insn.d.imm)); \ 118 #define UNSIGNED_D_OP(mnemonic) \ 123 text += g_pRegisters[insn.d.d]; \ 125 text += g_pRegisters[insn.d.a]; \ 127 text.append(static_cast<uint16_t>(insn.d.imm)); \ 130 #define UNSIGNED_SWAPPED_D_OP(mnemonic) \ 135 text += g_pRegisters[insn.d.a]; \ 137 text += g_pRegisters[insn.d.d]; \ 139 text.append(static_cast<uint16_t>(insn.d.imm)); \ 142 #define LOAD_STORE_D_OP(mnemonic) \ 147 text += g_pRegisters[insn.d.d]; \ 152 text.append(static_cast<uint16_t>(insn.d.imm), 16); \ 156 text.append(static_cast<int16_t>(insn.d.imm)); \ 158 text += g_pRegisters[insn.d.a]; \ 163 #define CR_XO_OP(mnemonic) \ 168 text += g_pRegisters[insn.xo.d]; \ 170 text += g_pRegisters[insn.xo.a]; \ 172 text += g_pRegisters[insn.xo.b]; \ 175 #define ARITH_XO_OP(mnemonic) \ 184 text += g_pRegisters[insn.xo.d]; \ 186 text += g_pRegisters[insn.xo.a]; \ 188 text += g_pRegisters[insn.xo.b]; \ 191 #define UNARY_ARITH_XO_OP(mnemonic) \ 200 text += g_pRegisters[insn.xo.d]; \ 202 text += g_pRegisters[insn.xo.a]; \ 205 #define LOAD_STORE_XO_OP(mnemonic) \ 210 text += g_pRegisters[insn.xo.d]; \ 212 if (insn.xo.a != 0) \ 214 text += g_pRegisters[insn.xo.a]; \ 217 text += g_pRegisters[insn.xo.b]; \ 220 #define LOGICAL_XO_OP(mnemonic) \ 227 text += g_pRegisters[insn.xo.a]; \ 229 if (insn.xo.a != 0) \ 231 text += g_pRegisters[insn.xo.d]; \ 234 text += g_pRegisters[insn.xo.b]; \ 240 const char *pMnemonic;
241 const char *pLikely =
"";
242 bool invertCondition =
false;
243 bool noCondition =
false;
250 invertCondition =
true;
255 invertCondition =
true;
260 invertCondition =
true;
265 invertCondition =
true;
270 invertCondition =
true;
275 invertCondition =
true;
328 const char *pCondition;
329 if (!invertCondition)
331 switch (insn.b.bi & 0x3)
349 switch (insn.b.bi & 0x3)
372 static const char *sprMnemonic(uint32_t spr)
443 void PPCDisassembler::null(
446 text +=
"Unrecognised instruction: ";
447 text.append(insn.i.opcode, 16);
453 const char *pTrapMnemonic;
457 pTrapMnemonic =
"lgt";
460 pTrapMnemonic =
"llt";
463 pTrapMnemonic =
"lne";
466 pTrapMnemonic =
"eq";
469 pTrapMnemonic =
"lge";
472 pTrapMnemonic =
"lle";
475 pTrapMnemonic =
"gt";
478 pTrapMnemonic =
"ge";
481 pTrapMnemonic =
"lt";
484 pTrapMnemonic =
"le";
487 pTrapMnemonic =
"ne";
493 if (insn.d.d == 0x1F)
500 text += pTrapMnemonic;
504 text += g_pRegisters[insn.d.a];
506 text.append(static_cast<int16_t>(insn.d.imm));
510 void PPCDisassembler::mulli(
513 SIGNED_D_OP(
"mulli");
516 void PPCDisassembler::subfic(
519 SIGNED_D_OP(
"subfic");
522 void PPCDisassembler::cmpli(
526 switch (insn.d.d & 0x7)
553 text += g_pRegisters[insn.d.a];
555 text.append(static_cast<int16_t>(insn.d.imm));
558 void PPCDisassembler::cmpi(
562 switch ((insn.d.d >> 2) & 0x7)
589 text += g_pRegisters[insn.d.a];
591 text.append(static_cast<int16_t>(insn.d.imm));
594 void PPCDisassembler::addic(
597 SIGNED_D_OP(
"addic");
600 void PPCDisassembler::addic_dot(
603 SIGNED_D_OP(
"addic.");
606 void PPCDisassembler::addi(
612 text += g_pRegisters[insn.d.d];
614 text.append(static_cast<int16_t>(insn.d.imm));
622 void PPCDisassembler::addis(
628 text += g_pRegisters[insn.d.d];
630 text.append(static_cast<int16_t>(insn.d.imm));
634 SIGNED_D_OP(
"addis");
638 void PPCDisassembler::bc(
643 conditionalBranch(insn, text);
652 switch (insn.b.bi >> 2)
680 int32_t addr =
static_cast<int32_t
>(insn.b.bd) << 2;
682 text.append(static_cast<uint32_t>(addr), 16);
687 text.append(static_cast<uint32_t>(addr +
m_nLocation - 4), 16);
690 void PPCDisassembler::sc(
696 void PPCDisassembler::b(
707 int32_t addr =
static_cast<int32_t
>(insn.i.li) << 2;
710 if (addr & (1 << 25))
712 addr |= (0x3F) << 26;
719 text.append(static_cast<uint32_t>(addr), 16);
722 void PPCDisassembler::op13(
735 conditionalBranch(insn, text);
774 conditionalBranch(insn, text);
782 text +=
"Unrecognised opcode 13 XO: ";
787 void PPCDisassembler::rlwimi(
795 text += g_pRegisters[insn.m.a];
797 text += g_pRegisters[insn.m.s];
803 if (insn.m.mb < insn.m.me + 1)
805 for (
int i = insn.m.mb; (i % 32) <= insn.m.me; i++)
806 mask |= 1 >> (i % 32);
808 text.append(mask, 16);
810 else if (insn.m.mb == insn.m.me + 1)
812 text +=
"&0xFFFFFFFF";
817 for (
int i = insn.m.me + 1; (i % 32) <= insn.m.mb - 1; i++)
818 mask &= 1 >> (i % 32);
820 text.append(mask, 16);
824 void PPCDisassembler::rlwinm(
832 text += g_pRegisters[insn.m.a];
834 text += g_pRegisters[insn.m.s];
840 if (insn.m.mb < insn.m.me + 1)
842 for (
int i = insn.m.mb; i <= insn.m.me; i++)
845 text.append(mask, 16);
847 else if (insn.m.mb == insn.m.me + 1)
849 text +=
"&0xFFFFFFFF";
854 for (
int i = insn.m.me + 1; i <= insn.m.mb - 1; i++)
857 text.append(mask, 16);
861 void PPCDisassembler::rlwnm(
869 text += g_pRegisters[insn.m.a];
871 text += g_pRegisters[insn.m.s];
877 if (insn.m.mb < insn.m.me + 1)
879 for (
int i = insn.m.mb; (i % 32) <= insn.m.me; i++)
880 mask |= 1 >> (i % 32);
882 text.append(mask, 16);
884 else if (insn.m.mb == insn.m.me + 1)
886 text +=
"&0xFFFFFFFF";
891 for (
int i = insn.m.me + 1; (i % 32) <= insn.m.mb - 1; i++)
892 mask &= 1 >> (i % 32);
894 text.append(mask, 16);
898 void PPCDisassembler::ori(
901 UNSIGNED_SWAPPED_D_OP(
"ori");
904 void PPCDisassembler::oris(
907 UNSIGNED_SWAPPED_D_OP(
"oris");
910 void PPCDisassembler::xori(
913 UNSIGNED_SWAPPED_D_OP(
"xori");
916 void PPCDisassembler::xoris(
919 UNSIGNED_SWAPPED_D_OP(
"xoris");
922 void PPCDisassembler::andi_dot(
925 UNSIGNED_SWAPPED_D_OP(
"andi.");
928 void PPCDisassembler::andis_dot(
931 UNSIGNED_SWAPPED_D_OP(
"andis.");
934 void PPCDisassembler::op1e(
938 text +=
"Unimplemented instruction: ";
939 text.append(insn.integer, 16);
942 void PPCDisassembler::op1f(
956 text += g_pRegisters[insn.xo.a];
958 text += g_pRegisters[insn.xo.b];
962 const char *pTrapMnemonic;
966 pTrapMnemonic =
"lgt";
969 pTrapMnemonic =
"llt";
972 pTrapMnemonic =
"lne";
975 pTrapMnemonic =
"eq";
978 pTrapMnemonic =
"lge";
981 pTrapMnemonic =
"lle";
984 pTrapMnemonic =
"gt";
987 pTrapMnemonic =
"ge";
990 pTrapMnemonic =
"lt";
993 pTrapMnemonic =
"le";
996 pTrapMnemonic =
"ne";
1002 if (insn.d.d == 0x1F)
1009 text += pTrapMnemonic;
1012 text += g_pRegisters[insn.d.a];
1014 text.append(static_cast<int16_t>(insn.d.imm));
1018 ARITH_XO_OP(
"subfc");
1021 ARITH_XO_OP(
"mulhdu");
1024 ARITH_XO_OP(
"addc");
1027 ARITH_XO_OP(
"mulhwu");
1031 text += g_pRegisters[insn.xo.d];
1034 LOAD_STORE_XO_OP(
"lwarx");
1037 LOAD_STORE_XO_OP(
"lwzx");
1040 LOGICAL_XO_OP(
"slw");
1047 text += g_pRegisters[insn.xo.a];
1049 text += g_pRegisters[insn.xo.d];
1063 text += g_pRegisters[insn.xo.a];
1065 text += g_pRegisters[insn.xo.b];
1068 ARITH_XO_OP(
"subf");
1074 text += g_pRegisters[insn.xo.a];
1077 text += g_pRegisters[insn.xo.b];
1080 LOAD_STORE_XO_OP(
"lwzux");
1087 ARITH_XO_OP(
"mulhw");
1091 text += g_pRegisters[insn.xo.d];
1097 text += g_pRegisters[insn.xo.a];
1100 text += g_pRegisters[insn.xo.b];
1103 LOAD_STORE_XO_OP(
"lbzx");
1112 text += g_pRegisters[insn.xo.d];
1114 text += g_pRegisters[insn.xo.a];
1117 LOAD_STORE_XO_OP(
"lbzux");
1120 LOGICAL_XO_OP(
"nor");
1123 ARITH_XO_OP(
"subfe");
1126 ARITH_XO_OP(
"adde");
1129 text +=
"TODO:: implement mtcrf";
1133 text += g_pRegisters[insn.xo.d];
1136 LOAD_STORE_XO_OP(
"stwcx");
1139 LOAD_STORE_XO_OP(
"stwx");
1142 LOAD_STORE_XO_OP(
"stwux");
1145 UNARY_ARITH_XO_OP(
"subfze");
1148 UNARY_ARITH_XO_OP(
"addze");
1151 LOAD_STORE_XO_OP(
"stbx");
1154 UNARY_ARITH_XO_OP(
"subfme");
1157 UNARY_ARITH_XO_OP(
"addme");
1160 ARITH_XO_OP(
"mullw");
1164 text += g_pRegisters[insn.xo.a];
1166 text += g_pRegisters[insn.xo.b];
1169 LOAD_STORE_XO_OP(
"stbux");
1176 text += g_pRegisters[insn.xo.a];
1178 text += g_pRegisters[insn.xo.b];
1180 text.append(insn.xo.d, 16);
1183 LOAD_STORE_XO_OP(
"lhzx");
1186 LOGICAL_XO_OP(
"eqv");
1189 LOAD_STORE_XO_OP(
"lhzux");
1192 LOGICAL_XO_OP(
"xor");
1198 uint32_t spr = (insn.xfx.spr & 0x1f) << 5;
1199 spr |= (insn.xfx.spr >> 5) & 0x1f;
1201 if (sprMnemonic(spr))
1202 text += sprMnemonic(spr);
1206 text += g_pRegisters[insn.xfx.d];
1207 if (!sprMnemonic(spr))
1215 LOAD_STORE_XO_OP(
"lwax");
1218 LOAD_STORE_XO_OP(
"lhax");
1221 LOAD_STORE_XO_OP(
"lhaux");
1224 LOAD_STORE_XO_OP(
"sthx");
1227 LOGICAL_XO_OP(
"orc");
1230 LOGICAL_XO_OP(
"or");
1233 ARITH_XO_OP(
"divwu");
1239 uint32_t spr = (insn.xfx.spr & 0x1f) << 5;
1240 spr |= (insn.xfx.spr >> 5) & 0x1f;
1242 if (sprMnemonic(spr))
1243 text += sprMnemonic(spr);
1247 if (!sprMnemonic(spr))
1252 text += g_pRegisters[insn.xfx.d];
1257 text += g_pRegisters[insn.xo.a];
1259 text += g_pRegisters[insn.xo.b];
1262 LOGICAL_XO_OP(
"nand");
1265 ARITH_XO_OP(
"divw");
1272 LOAD_STORE_XO_OP(
"lswx");
1275 LOAD_STORE_XO_OP(
"lwbrx");
1278 LOGICAL_XO_OP(
"srw");
1282 text += g_pRegisters[insn.xo.d];
1287 LOAD_STORE_XO_OP(
"lswi");
1294 text += g_pRegisters[insn.xo.d];
1296 text += g_pRegisters[insn.xo.b];
1299 LOAD_STORE_XO_OP(
"stswx");
1302 LOAD_STORE_XO_OP(
"stwbrx");
1305 LOAD_STORE_XO_OP(
"stswi");
1308 LOAD_STORE_XO_OP(
"lhbrx");
1311 LOGICAL_XO_OP(
"srawi");
1317 LOAD_STORE_XO_OP(
"sthbrx");
1324 text += g_pRegisters[insn.xo.a];
1326 text += g_pRegisters[insn.xo.d];
1333 text += g_pRegisters[insn.xo.a];
1335 text += g_pRegisters[insn.xo.d];
1339 text += g_pRegisters[insn.xo.a];
1341 text += g_pRegisters[insn.xo.b];
1345 text += g_pRegisters[insn.xo.a];
1347 text += g_pRegisters[insn.xo.b];
1350 text +=
"Unsupported 0x1F instruction, XO: 0x";
1351 text.append(insn.xo.xo, 16);
1356 void PPCDisassembler::lwz(
1359 LOAD_STORE_D_OP(
"lwz");
1362 void PPCDisassembler::lwzu(
1365 LOAD_STORE_D_OP(
"lwzu");
1368 void PPCDisassembler::lbz(
1371 LOAD_STORE_D_OP(
"lbz");
1374 void PPCDisassembler::lbzu(
1377 LOAD_STORE_D_OP(
"lbzu");
1380 void PPCDisassembler::stw(
1383 LOAD_STORE_D_OP(
"stw");
1386 void PPCDisassembler::stwu(
1389 LOAD_STORE_D_OP(
"stwu");
1392 void PPCDisassembler::stb(
1395 LOAD_STORE_D_OP(
"stb");
1398 void PPCDisassembler::stbu(
1401 LOAD_STORE_D_OP(
"stbu");
1404 void PPCDisassembler::lhz(
1407 LOAD_STORE_D_OP(
"lhz");
1410 void PPCDisassembler::lhzu(
1413 LOAD_STORE_D_OP(
"lhzu");
1416 void PPCDisassembler::lha(
1419 LOAD_STORE_D_OP(
"lha");
1422 void PPCDisassembler::lhau(
1425 LOAD_STORE_D_OP(
"lhau");
1428 void PPCDisassembler::sth(
1431 LOAD_STORE_D_OP(
"stb");
1434 void PPCDisassembler::sthu(
1437 LOAD_STORE_D_OP(
"sthu");
1440 void PPCDisassembler::lmw(
1443 LOAD_STORE_D_OP(
"lmw");
1446 void PPCDisassembler::stmw(
1449 LOAD_STORE_D_OP(
"stmw");
1452 void PPCDisassembler::lfs(
1458 void PPCDisassembler::lfsu(
1464 void PPCDisassembler::lfd(
1470 void PPCDisassembler::lfdu(
1476 void PPCDisassembler::stfs(
1482 void PPCDisassembler::stfsu(
1488 void PPCDisassembler::stfd(
1494 void PPCDisassembler::stfdu(
1500 void PPCDisassembler::op3a(
1505 void PPCDisassembler::op3b(
1510 void PPCDisassembler::op3e(
1515 void PPCDisassembler::op3f(
void disassemble(LargeStaticString &text)
void setMode(size_t nMode)
void twi(Instruction insn, LargeStaticString &text)
void setLocation(uintptr_t nLocation)