From f96d2c28796655d493db2e1d51cb8f0afa52070e Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Thu, 12 Sep 2024 18:59:24 +0300 Subject: [PATCH] Implement periodt variant of instructions. --- PowerRecomp/main.cpp | 57 +++++++++++++++++++++++--------- PowerUtils/ppc_context.h | 2 +- tests/PowerAnalyse/add-cond.cpp | 10 ++++++ tests/PowerAnalyse/add-cond.elf | Bin 0 -> 1472 bytes 4 files changed, 52 insertions(+), 17 deletions(-) create mode 100644 tests/PowerAnalyse/add-cond.cpp create mode 100644 tests/PowerAnalyse/add-cond.elf diff --git a/PowerRecomp/main.cpp b/PowerRecomp/main.cpp index d368e1c..30228ce 100644 --- a/PowerRecomp/main.cpp +++ b/PowerRecomp/main.cpp @@ -6,7 +6,7 @@ #include #include -#define TEST_FILE "cond.elf" +#define TEST_FILE "add-cond.elf" int main() { @@ -81,14 +81,13 @@ int main() } else { - // TODO: need to handle instructions that treat r0 as 0 - std::println(f, "\t// {:x} {} {}", base - 4, insn.opcode->name, insn.op_str); switch (insn.opcode->id) { case PPC_INST_ADD: - // TODO: . variant std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 + ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_ADDI: @@ -99,7 +98,6 @@ int main() break; case PPC_INST_ADDIS: - // TODO: validate the sign extend std::println(f, "\tctx.r{}.s64 = ctx.r{}.s64 + {};", insn.operands[0], insn.operands[1], static_cast(insn.operands[2] << 16)); break; @@ -107,23 +105,27 @@ int main() break; case PPC_INST_AND: - // TODO: . variant std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_ANDC: - // TODO: . variant std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & ~ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_ANDI: - // TODO: . variant std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & {};", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_ANDIS: - // TODO: . variant std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & {};", insn.operands[0], insn.operands[1], insn.operands[2] << 16); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_ATTN: @@ -222,9 +224,21 @@ int main() break; case PPC_INST_CCTPL: + // no op + break; + case PPC_INST_CCTPM: + // no op + break; + case PPC_INST_CLRLDI: + std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & 0x{:X};", insn.operands[0], insn.operands[1], (1ull << (64 - insn.operands[2])) - 1); + break; + case PPC_INST_CLRLWI: + std::println(f, "\tctx.r{}.u64 = ctx.r{}.u32 & 0x{:X};", insn.operands[0], insn.operands[1], (1ull << (32 - insn.operands[2])) - 1); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_CMPD: @@ -261,7 +275,11 @@ int main() case PPC_INST_CNTLZD: case PPC_INST_CNTLZW: + break; + case PPC_INST_DB16CYC: + // no op + break; case PPC_INST_DCBF: // no op @@ -399,8 +417,9 @@ int main() break; case PPC_INST_MR: - // TODO: . variant std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64;", insn.operands[0], insn.operands[1]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_MTCR: @@ -431,8 +450,9 @@ 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]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_NAND: @@ -440,8 +460,9 @@ int main() break; case PPC_INST_NEG: - // TODO: . variant std::println(f, "\tctx.r{}.s64 = -ctx.r{}.s64;", insn.operands[0], insn.operands[1]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_NOP: @@ -453,13 +474,15 @@ int main() break; case PPC_INST_NOT: - // TODO: . variant std::println(f, "\tctx.r{}.u64 = ~ctx.r{}.u64;", insn.operands[0], insn.operands[1]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_OR: - // TODO: . variant std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 | ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_ORC: @@ -535,8 +558,9 @@ int main() break; case PPC_INST_SUBF: - // TODO: . variant std::println(f, "\tctx.r{}.s64 = ctx.r{}.s64 - ctx.r{}.s64;", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_SUBFC: @@ -649,8 +673,9 @@ int main() break; case PPC_INST_XOR: - // TODO: . variant std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 ^ ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.opcode->opcode & 0x1) + std::println(f, "\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_XORI: diff --git a/PowerUtils/ppc_context.h b/PowerUtils/ppc_context.h index c619f40..f45cad2 100644 --- a/PowerUtils/ppc_context.h +++ b/PowerUtils/ppc_context.h @@ -7,7 +7,7 @@ #define _byteswap_ushort __builtin_bswap16 #define _byteswap_ulong __builtin_bswap32 #define _byteswap_uint64 __builtin_bswap64 -#define PPC_FUNC extern inline __attribute__((weak,noinline)) +#define PPC_FUNC __attribute__((weak,noinline)) #else #define PPC_FUNC __declspec(noinline) #endif diff --git a/tests/PowerAnalyse/add-cond.cpp b/tests/PowerAnalyse/add-cond.cpp new file mode 100644 index 0000000..4502193 --- /dev/null +++ b/tests/PowerAnalyse/add-cond.cpp @@ -0,0 +1,10 @@ +int add(int a, int b) +{ + int c = a + b; + return c == 0 ? 50000 : c; +} + +extern "C" int _start() +{ + return add(1, 2); +} \ No newline at end of file diff --git a/tests/PowerAnalyse/add-cond.elf b/tests/PowerAnalyse/add-cond.elf new file mode 100644 index 0000000000000000000000000000000000000000..b889772b2d0839b31c80ba898c48d69ba34a1b67 GIT binary patch literal 1472 zcma)6T}u>E7=CAFwY5|%l0+jG5;Cw+Qz)tnm$sWHH8?a&AJO0Bo%F33wj71FivMfLJfqq_kJHriRsK(l&t@ z?jP4cp=}nnS#X&K%B^=Id;aA3#=(cx>T4;lypqawUqtbSIOMq3`;jM%t0dJ6)*FmZ z0jxWK8N3Id1gyCC^BZWt3#BN{wij(xo(D-9#!+SAnmg|h)URR?O;; z)xxNir1u4MLG=O+wp!1q>K&~2jK~RC&*lAGR=OKTS&($a^>?FmwfpwaRRnz&i8lc^}L6E=|;XII5-#+^nqiV_iuCl|1YLT(Cg-|sXJyWm^~VTfoH=woRc~$o>K{6 z44L|Aob7ioo<|&g!hqzvwsPi}{%K4mJAy$2e1ucYryJ`=}wy z(2bZl_C4cp$NTTav