Implement some loop instructions & add loop test.

This commit is contained in:
Skyth 2024-09-12 16:42:26 +03:00
parent c82c4688e7
commit 6f32dc35a2
4 changed files with 44 additions and 15 deletions

View File

@ -63,15 +63,12 @@ int main()
name = std::format("sub_{:X}", base); name = std::format("sub_{:X}", base);
} }
std::println(f, "PPC_FUNC void {}(PPCContext& __restrict callerCtx, uint8_t* base) {{", name); std::println(f, "PPC_FUNC void {}(PPCContext& __restrict ctx, uint8_t* base) {{", name);
std::println(f, "\tPPCContext ctx = callerCtx;");
std::println(f, "\tuint32_t ea;\n"); std::println(f, "\tuint32_t ea;\n");
ppc_insn insn; ppc_insn insn;
while (base < end) 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); ppc::Disassemble(data, 4, base, insn);
@ -140,27 +137,32 @@ int main()
case PPC_INST_BCTR: case PPC_INST_BCTR:
case PPC_INST_BCTRL: case PPC_INST_BCTRL:
break;
case PPC_INST_BDNZ: 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_BDNZF:
case PPC_INST_BEQ: case PPC_INST_BEQ:
break; break;
case PPC_INST_BEQLR: 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; break;
case PPC_INST_BGE: case PPC_INST_BGE:
break; break;
case PPC_INST_BGELR: 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; break;
case PPC_INST_BGT: case PPC_INST_BGT:
break; break;
case PPC_INST_BGTLR: 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; break;
case PPC_INST_BL: case PPC_INST_BL:
@ -176,18 +178,19 @@ int main()
targetName = std::format("sub_{:X}", insn.operands[0]); targetName = std::format("sub_{:X}", insn.operands[0]);
} }
std::println(f, "\tctx.lr = 0x{:X};", base); std::println(f, "\tctx.lr = 0x{:X};", base);
std::println(f, "\tcallerCtx = ctx;"); std::println(f, "\t{}(ctx, base);", targetName);
std::println(f, "\t{}(callerCtx, base);", targetName);
std::println(f, "\tctx = callerCtx;");
break; break;
} }
case PPC_INST_BLE: 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: case PPC_INST_BLELR:
break; break;
case PPC_INST_BLR: case PPC_INST_BLR:
std::println(f, "\tgoto end;"); std::println(f, "\treturn;");
break; break;
case PPC_INST_BLRL: case PPC_INST_BLRL:
@ -218,7 +221,12 @@ int main()
break; break;
case PPC_INST_CMPW: case PPC_INST_CMPW:
break;
case PPC_INST_CMPWI: case PPC_INST_CMPWI:
std::println(f, "\tctx.cr{}.compare<int32_t>(ctx.r{}.s32, {});", insn.operands[0], insn.operands[1], int32_t(insn.operands[2]));
break;
case PPC_INST_CNTLZD: case PPC_INST_CNTLZD:
case PPC_INST_CNTLZW: case PPC_INST_CNTLZW:
case PPC_INST_DB16CYC: case PPC_INST_DB16CYC:
@ -364,7 +372,12 @@ int main()
break; break;
case PPC_INST_MTCR: case PPC_INST_MTCR:
break;
case PPC_INST_MTCTR: case PPC_INST_MTCTR:
std::println(f, "\tctx.ctr = ctx.r{}.u64;", insn.operands[0]);
break;
case PPC_INST_MTFSF: case PPC_INST_MTFSF:
break; break;
@ -386,6 +399,8 @@ int main()
break; break;
case PPC_INST_MULLW: 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; break;
case PPC_INST_NAND: case PPC_INST_NAND:
@ -617,9 +632,6 @@ int main()
} }
} }
std::println(f, "end:");
std::println(f, "\tcallerCtx = ctx;");
std::println(f, "}}\n"); std::println(f, "}}\n");
} }

View File

@ -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);
}

BIN
tests/PowerAnalyse/loop.elf Normal file

Binary file not shown.

View File

@ -5663,6 +5663,8 @@ static int decode_insn_powerpc(bfd_vma memaddr, disassemble_info* info, int bige
insn = bfd_getl32(buffer); insn = bfd_getl32(buffer);
oinsn->instruction = insn; oinsn->instruction = insn;
memset(oinsn->operands, 0, sizeof(oinsn->operands));
/* Get the major opcode of the instruction. */ /* Get the major opcode of the instruction. */
op = PPC_OP(insn); op = PPC_OP(insn);