diff --git a/PowerRecomp/main.cpp b/PowerRecomp/main.cpp index b2979cc..60da7de 100644 --- a/PowerRecomp/main.cpp +++ b/PowerRecomp/main.cpp @@ -63,16 +63,13 @@ int main() name = std::format("sub_{:X}", base); } - std::println(f, "PPC_FUNC void {}(PPCContext& __restrict callerCtx, uint8_t* base) {{", name); - std::println(f, "\tPPCContext ctx = callerCtx;"); + std::println(f, "PPC_FUNC void {}(PPCContext& __restrict ctx, uint8_t* base) {{", name); std::println(f, "\tuint32_t ea;\n"); ppc_insn insn; while (base < end) { - auto block = fn.SearchBlock(base); - if (block != -1 && (fn.base + fn.blocks[block].base) == base) - std::println(f, "loc_{:X}:", base); + std::println(f, "loc_{:X}:", base); ppc::Disassemble(data, 4, base, insn); @@ -140,27 +137,32 @@ int main() case PPC_INST_BCTR: case PPC_INST_BCTRL: + break; + case PPC_INST_BDNZ: + std::println(f, "\tif (--ctx.ctr != 0) goto loc_{:X};", insn.operands[0]); + break; + case PPC_INST_BDNZF: case PPC_INST_BEQ: break; case PPC_INST_BEQLR: - std::println(f, "\tif (ctx.cr{}.eq) goto end;", insn.operands[0]); + std::println(f, "\tif (ctx.cr{}.eq) return;", insn.operands[0]); break; case PPC_INST_BGE: break; case PPC_INST_BGELR: - std::println(f, "\tif (!ctx.cr{}.lt) goto end;", insn.operands[0]); + std::println(f, "\tif (!ctx.cr{}.lt) return;", insn.operands[0]); break; case PPC_INST_BGT: break; case PPC_INST_BGTLR: - std::println(f, "\tif (ctx.cr{}.gt) goto end;", insn.operands[0]); + std::println(f, "\tif (ctx.cr{}.gt) return;", insn.operands[0]); break; case PPC_INST_BL: @@ -176,18 +178,19 @@ int main() targetName = std::format("sub_{:X}", insn.operands[0]); } std::println(f, "\tctx.lr = 0x{:X};", base); - std::println(f, "\tcallerCtx = ctx;"); - std::println(f, "\t{}(callerCtx, base);", targetName); - std::println(f, "\tctx = callerCtx;"); + std::println(f, "\t{}(ctx, base);", targetName); break; } case PPC_INST_BLE: + std::println(f, "\tif (!ctx.cr{}.gt) goto loc_{:X};", insn.operands[0], insn.operands[1]); + break; + case PPC_INST_BLELR: break; case PPC_INST_BLR: - std::println(f, "\tgoto end;"); + std::println(f, "\treturn;"); break; case PPC_INST_BLRL: @@ -218,7 +221,12 @@ int main() break; case PPC_INST_CMPW: + break; + case PPC_INST_CMPWI: + std::println(f, "\tctx.cr{}.compare(ctx.r{}.s32, {});", insn.operands[0], insn.operands[1], int32_t(insn.operands[2])); + break; + case PPC_INST_CNTLZD: case PPC_INST_CNTLZW: case PPC_INST_DB16CYC: @@ -364,7 +372,12 @@ int main() break; case PPC_INST_MTCR: + break; + case PPC_INST_MTCTR: + std::println(f, "\tctx.ctr = ctx.r{}.u64;", insn.operands[0]); + break; + case PPC_INST_MTFSF: break; @@ -386,6 +399,8 @@ int main() break; case PPC_INST_MULLW: + // TODO: . variant + std::println(f, "\tctx.r{}.s64 = ctx.r{}.s32 * ctx.r{}.s32;", insn.operands[0], insn.operands[1], insn.operands[2]); break; case PPC_INST_NAND: @@ -617,9 +632,6 @@ int main() } } - std::println(f, "end:"); - std::println(f, "\tcallerCtx = ctx;"); - std::println(f, "}}\n"); } diff --git a/tests/PowerAnalyse/loop.cpp b/tests/PowerAnalyse/loop.cpp new file mode 100644 index 0000000..cc9f4a3 --- /dev/null +++ b/tests/PowerAnalyse/loop.cpp @@ -0,0 +1,15 @@ +int loop(int a) +{ + int result = 0; + for (int i = 0; i < a; i++) + { + result = result * 31 + i; + result *= result; + } + return result; +} + +extern "C" int _start() +{ + return loop(30); +} diff --git a/tests/PowerAnalyse/loop.elf b/tests/PowerAnalyse/loop.elf new file mode 100644 index 0000000..3f7c6e4 Binary files /dev/null and b/tests/PowerAnalyse/loop.elf differ diff --git a/thirdparty/disasm/ppc-dis.c b/thirdparty/disasm/ppc-dis.c index f89c353..23fe767 100644 --- a/thirdparty/disasm/ppc-dis.c +++ b/thirdparty/disasm/ppc-dis.c @@ -5663,6 +5663,8 @@ static int decode_insn_powerpc(bfd_vma memaddr, disassemble_info* info, int bige insn = bfd_getl32(buffer); oinsn->instruction = insn; + memset(oinsn->operands, 0, sizeof(oinsn->operands)); + /* Get the major opcode of the instruction. */ op = PPC_OP(insn);