From 2dd35c461180debe722df1132698d4ac1f60c569 Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Sun, 15 Sep 2024 22:04:40 +0300 Subject: [PATCH] Implement bitwise rotation instructions. --- PowerRecomp/main.cpp | 42 +++++++++++++++++++++++++++++++++++-- thirdparty/disasm/ppc-dis.c | 8 +++---- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/PowerRecomp/main.cpp b/PowerRecomp/main.cpp index 13fe5ba..3986df0 100644 --- a/PowerRecomp/main.cpp +++ b/PowerRecomp/main.cpp @@ -10,6 +10,14 @@ #define TEST_FILE "default.xex" +static uint64_t computeMask(uint32_t mstart, uint32_t mstop) +{ + mstart &= 0x3F; + mstop &= 0x3F; + uint64_t value = (UINT64_MAX >> mstart) ^ ((mstop >= 63) ? 0 : UINT64_MAX >> (mstop + 1)); + return mstart <= mstop ? value : ~value; +} + int main() { const auto file = LoadFile(TEST_FILE).value(); @@ -809,8 +817,6 @@ int main() case PPC_INST_MTMSRD: case PPC_INST_MTXER: - case PPC_INST_MULCHWU: - case PPC_INST_MULHHW: break; case PPC_INST_MULHW: @@ -878,13 +884,45 @@ int main() break; case PPC_INST_RLDICL: + println("\tctx.r{}.u64 = _rotl64(ctx.r{}.u64, {}) & 0x{:X};", insn.operands[0], insn.operands[1], insn.operands[2], computeMask(insn.operands[3], 63)); + break; + case PPC_INST_RLDICR: + println("\tctx.r{}.u64 = _rotl64(ctx.r{}.u64, {}) & 0x{:X};", insn.operands[0], insn.operands[1], insn.operands[2], computeMask(0, insn.operands[3])); + break; + case PPC_INST_RLDIMI: + { + const uint64_t mask = computeMask(insn.operands[3], ~insn.operands[1]); + println("\tctx.r{}.u64 = (_rotl64(ctx.r{}.u64, {}) & 0x{:X}) | (ctx.r{}.u64 & 0x{:X});", insn.operands[0], insn.operands[1], insn.operands[2], mask, insn.operands[0], ~mask); + break; + } + case PPC_INST_RLWIMI: + { + const uint64_t mask = computeMask(insn.operands[3] + 32, insn.operands[4] + 32); + println("\tctx.r{}.u64 = (_rotl(ctx.r{}.u32, {}) & 0x{:X}) | (ctx.r{}.u64 & 0x{:X});", insn.operands[0], insn.operands[1], insn.operands[2], mask, insn.operands[0], ~mask); + break; + } + case PPC_INST_RLWINM: + println("\tctx.r{}.u64 = _rotl(ctx.r{}.u32, {}) & 0x{:X};", insn.operands[0], insn.operands[1], insn.operands[2], computeMask(insn.operands[3] + 32, insn.operands[4] + 32)); + if (insn.opcode->opcode & 0x1) + println("\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); + break; + case PPC_INST_ROTLDI: + println("\tctx.r{}.u64 = _rotl64(ctx.r{}.u64, {});", insn.operands[0], insn.operands[1], insn.operands[2]); + break; + case PPC_INST_ROTLW: + println("\tctx.r{}.u64 = _rotl(ctx.r{}.u32, ctx.r{}.u8 & 0x1F);", insn.operands[0], insn.operands[1], insn.operands[2]); + break; + case PPC_INST_ROTLWI: + println("\tctx.r{}.u64 = _rotl(ctx.r{}.u32, {});", insn.operands[0], insn.operands[1], insn.operands[2]); + if (insn.opcode->opcode & 0x1) + println("\tctx.cr0.compare(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]); break; case PPC_INST_SLD: diff --git a/thirdparty/disasm/ppc-dis.c b/thirdparty/disasm/ppc-dis.c index 23fe767..bb2f5aa 100644 --- a/thirdparty/disasm/ppc-dis.c +++ b/thirdparty/disasm/ppc-dis.c @@ -2234,10 +2234,10 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "maclhwuo.", XO(4,396,1,1), XO_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MACLHWUO }, { "mulchw", XRC(4,168,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHW }, { "mulchw.", XRC(4,168,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHW }, -{ "mulchwu", XRC(4,136,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU }, -{ "mulchwu.", XRC(4,136,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU }, -{ "mulhhw", XRC(4,40,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW }, -{ "mulhhw.", XRC(4,40,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW }, +//{ "mulchwu", XRC(4,136,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU }, +//{ "mulchwu.", XRC(4,136,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULCHWU }, +//{ "mulhhw", XRC(4,40,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW }, +//{ "mulhhw.", XRC(4,40,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHW }, { "mulhhwu", XRC(4,8,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHWU }, { "mulhhwu.", XRC(4,8,1), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULHHWU }, { "mullhw", XRC(4,424,0), X_MASK, PPC405 | PPC440, { RT, RA, RB }, PPC_INST_MULLHW },