From 108988f1b368d39c0aa9b8921ab6338e96a50de8 Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 5 Nov 2025 00:53:19 +0000 Subject: [PATCH] even more stupid fixes i feel angry Signed-off-by: lizzie --- externals/powah/data2code.c | 6 ++-- externals/powah/powah_emit.hpp | 2 +- externals/powah/powah_gen_base.hpp | 14 ++++---- externals/powah/tests.cpp | 2 +- .../src/dynarmic/backend/ppc64/emit_ppc64.cpp | 26 ++++++++------- .../ppc64/emit_ppc64_data_processing.cpp | 32 +++++++++++++++---- 6 files changed, 52 insertions(+), 30 deletions(-) diff --git a/externals/powah/data2code.c b/externals/powah/data2code.c index 76f98c5e18..05b2fd4e1a 100644 --- a/externals/powah/data2code.c +++ b/externals/powah/data2code.c @@ -183,19 +183,19 @@ int main(int argc, char *argv[]) { } else if (!strcmp(form, "DS")) { printf( "void %s(GPR const rt, GPR const ra, uint32_t d) {" - " emit_%s(0x%08x, rt, ra, d); " + " emit_%s(0x%08x, rt, ra, d >> 2); " "}\n" , mem, form, OP_EXT); } else if (!strcmp(form, "XS")) { /* HUGE DIFFERENCE DO NOT REMOVE */ printf( "void %s(GPR const rt, GPR const ra, uint32_t sh) {" - " emit_%s(0x%08x, ra, rt, sh, false); " + " emit_%s(0x%08x, rt, ra, sh, false); " "}\n" , mem, form, OP_EXT_XS); printf( "void %s_(GPR const rt, GPR const ra, uint32_t sh) {" - " emit_%s(0x%08x, ra, rt, sh, true); " + " emit_%s(0x%08x, rt, ra, sh, true); " "}\n" , mem, form, OP_EXT_XS); } else if (!strcmp(form, "XL")) { diff --git a/externals/powah/powah_emit.hpp b/externals/powah/powah_emit.hpp index 1aa11f53a2..858f846574 100644 --- a/externals/powah/powah_emit.hpp +++ b/externals/powah/powah_emit.hpp @@ -254,7 +254,7 @@ struct Context { base[offset++] = (op | bitExt(rt.index, 6, 5) | bitExt(ra.index, 11, 5) - | bitExt(d >> 2, 16, 14) + | bitExt(d, 16, 14) ); } void emit_M(uint32_t op, GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me, bool rc) { diff --git a/externals/powah/powah_gen_base.hpp b/externals/powah/powah_gen_base.hpp index 97b2410a09..bba6bc9067 100644 --- a/externals/powah/powah_gen_base.hpp +++ b/externals/powah/powah_gen_base.hpp @@ -224,10 +224,10 @@ void LBZUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ee, ra, rt void LBZUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ee, ra, rt, rb, true); } void LBZX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ae, ra, rt, rb, false); } void LBZX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ae, ra, rt, rb, true); } -void LD(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000000, rt, ra, d); } +void LD(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000000, rt, ra, d >> 2); } void LDARX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a8, ra, rt, rb, false); } void LDARX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a8, ra, rt, rb, true); } -void LDU(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000002, rt, ra, d); } +void LDU(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000002, rt, ra, d >> 2); } void LDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006a, ra, rt, rb, false); } void LDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006a, ra, rt, rb, true); } void LDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00002a, ra, rt, rb, false); } @@ -263,7 +263,7 @@ void LSWI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004aa, ra, rt, void LSWI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004aa, ra, rt, rb, true); } void LSWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042a, ra, rt, rb, false); } void LSWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042a, ra, rt, rb, true); } -void LWA(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000004, rt, ra, d); } +void LWA(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000004, rt, ra, d >> 2); } void LWARX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000028, ra, rt, rb, false); } void LWARX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000028, ra, rt, rb, true); } void LWAUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ea, ra, rt, rb, false); } @@ -384,8 +384,8 @@ void SLW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000030, ra, rt, void SLW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000030, ra, rt, rb, true); } void SRAD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000634, ra, rt, rb, false); } void SRAD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000634, ra, rt, rb, true); } -void SRADI(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, ra, rt, sh, false); } -void SRADI_(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, ra, rt, sh, true); } +void SRADI(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, rt, ra, sh, false); } +void SRADI_(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, rt, ra, sh, true); } void SRD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000436, ra, rt, rb, false); } void SRD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000436, ra, rt, rb, true); } void SRAW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000630, ra, rt, rb, false); } @@ -400,10 +400,10 @@ void STBUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ee, ra, rt void STBUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ee, ra, rt, rb, true); } void STBX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ae, ra, rt, rb, false); } void STBX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ae, ra, rt, rb, true); } -void STD(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xf8000000, rt, ra, d); } +void STD(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xf8000000, rt, ra, d >> 2); } void STDCX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ac, ra, rt, rb, false); } void STDCX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ac, ra, rt, rb, true); } -void STDU(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xf8000002, rt, ra, d); } +void STDU(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xf8000002, rt, ra, d >> 2); } void STDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016a, ra, rt, rb, false); } void STDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016a, ra, rt, rb, true); } void STDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012a, ra, rt, rb, false); } diff --git a/externals/powah/tests.cpp b/externals/powah/tests.cpp index c9e0add6b2..43fff657c8 100644 --- a/externals/powah/tests.cpp +++ b/externals/powah/tests.cpp @@ -197,7 +197,7 @@ TEST_CASE("ppc64: functor-2", "[ppc64]") { ctx.RLWINM(powah::R9, powah::R9, 0, 0, 0); ctx.SLDI(powah::R10, powah::R10, 30); ctx.OR(powah::R9, powah::R9, powah::R10); - ctx.STD(powah::R9, powah::R8, 8); + ctx.STD(powah::R9, powah::R8, 0); ctx.BLR(); REQUIRE(data[0] == EB32(0x781b687c)); REQUIRE(data[1] == EB32(0x3828837c)); diff --git a/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp b/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp index 25db5e641d..4f3fcff594 100644 --- a/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp +++ b/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp @@ -9,6 +9,7 @@ #include #include +#include "abi.h" #include "dynarmic/backend/ppc64/a32_core.h" #include "dynarmic/backend/ppc64/a64_core.h" #include "dynarmic/backend/ppc64/abi.h" @@ -67,11 +68,20 @@ void EmitIR(powah::Context& code, EmitContext& ctx, I ASSERT(false && "unimp value live"); return; } + + // All logical operations whom set (RC) are going to compute as the following: + // 1. Rt <- logical_op (Ra, Rb) + // 2. Compare as Signed(Rt) against 0 + // Basically, it's equivalent to say: + // + // add r0, r1, r2 -> add. r0, r1, r2 + // cmpli r0, 0 + // // CR0: - // 0 - N/LT, result is negative - // 1 - P/GT, result is positive - // 2 - Z/EQ, result is zero - // 3 - S/SO, summary overflow (carry?) + // 0 - 0x08 - N/LT, result is negative + // 1 - 0x04 - P/GT, result is positive + // 2 - 0x02 - Z/EQ, result is zero + // 3 - 0x01 - S/SO, summary overflow (carry?) // XER: // 32 - SO // 33 - Overflow @@ -99,14 +109,8 @@ void EmitIR(powah::Context& code, EmitContext& ctx, I // code.OR(tmp3, tmp3, tmp4); } else { // MFCR Fills RT 32:63, RT 0:31 left blank - auto const source = ctx.reg_alloc.UseGpr(inst->GetArg(0)); auto const tmp3 = ctx.reg_alloc.ScratchGpr(); - auto const tmp = ctx.reg_alloc.ScratchGpr(); - code.LI(tmp, -1); - code.RLDICR(tmp, tmp, 0, 0); - code.MFCR(powah::R0, tmp3, powah::R0); - code.CMPW(tmp, source); - code.MFCR(powah::R0, tmp3, powah::R0); + code.MR(tmp3, PPC64::RNZCV); ctx.reg_alloc.DefineValue(inst, tmp3); } } diff --git a/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_data_processing.cpp b/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_data_processing.cpp index ee3002ce89..44323a4721 100644 --- a/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_data_processing.cpp +++ b/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_data_processing.cpp @@ -558,14 +558,33 @@ void EmitIR(powah::Context& code, EmitContext& ctx, IR: template<> void EmitIR(powah::Context& code, EmitContext& ctx, IR::Inst* inst) { - auto const result = ctx.reg_alloc.ScratchGpr(); auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0)); auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1)); - code.RLDICL(result, src_a, 0, 32); // Truncate - code.AND(result, result, src_b); - auto const tmp = ctx.reg_alloc.ScratchGpr(); - code.ANDI_(tmp, result, 0); - ctx.reg_alloc.DefineValue(inst, result); + auto const tmp3 = ctx.reg_alloc.ScratchGpr(); + auto const tmp10 = ctx.reg_alloc.ScratchGpr(); + auto const tmp9 = PPC64::RNZCV; + code.RLDICL(tmp3, src_a, 0, 32); // Truncate + code.AND(tmp3, tmp3, src_b); + code.CNTLZD(tmp10, tmp3); + code.SRADI(tmp9, tmp3, 32); + code.SRDI(tmp10, tmp10, 6); + code.RLWINM(tmp9, tmp9, 0, 0, 0); + code.SLDI(tmp10, tmp10, 30); + code.OR(tmp9, tmp9, tmp10); + +/* + and 3,4,5 + cntlzd 10,3 + sradi 9,3,32 + srdi 10,10,6 + rlwinm 9,9,0,0,0 + sldi 10,10,30 + or 9,9,10 + std 9,0(8) + blr +*/ + + ctx.reg_alloc.DefineValue(inst, tmp3); } template<> @@ -574,7 +593,6 @@ void EmitIR(powah::Context& code, EmitContext& ctx, IR::Inst* auto const src_a = ctx.reg_alloc.UseGpr(inst->GetArg(0)); auto const src_b = ctx.reg_alloc.UseGpr(inst->GetArg(1)); code.AND_(result, src_a, src_b); - code.ADDI(result, result, 0); //update cr0 ctx.reg_alloc.DefineValue(inst, result); }