From ace670d381ff7d3312df674e1a2cb62542bf890a Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 5 Nov 2025 00:46:29 +0000 Subject: [PATCH] fix xs stuffs Signed-off-by: lizzie --- externals/powah/data2code.c | 10 +++-- externals/powah/powah_emit.hpp | 8 ++-- externals/powah/powah_gen_base.hpp | 4 +- externals/powah/tests.cpp | 37 +++++++++++++++++++ .../ppc64/emit_ppc64_data_processing.cpp | 4 +- 5 files changed, 52 insertions(+), 11 deletions(-) diff --git a/externals/powah/data2code.c b/externals/powah/data2code.c index 13a6bdbb16..76f98c5e18 100644 --- a/externals/powah/data2code.c +++ b/externals/powah/data2code.c @@ -43,6 +43,7 @@ int main(int argc, char *argv[]) { }; #define OP_EXT ((i_opcode << 26) | (i_extopc << 1)) +#define OP_EXT_XS ((i_opcode << 26) | (i_extopc << 2)) if (strchr(mem, '[') != NULL) *strchr(mem, '[') = '\0'; if (strchr(mem, '.') != NULL) *strchr(mem, '.') = '_'; @@ -186,16 +187,17 @@ int main(int argc, char *argv[]) { "}\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, rt, ra, sh, false); " + " emit_%s(0x%08x, ra, rt, sh, false); " "}\n" - , mem, form, OP_EXT); + , mem, form, OP_EXT_XS); printf( "void %s_(GPR const rt, GPR const ra, uint32_t sh) {" - " emit_%s(0x%08x, rt, ra, sh, true); " + " emit_%s(0x%08x, ra, rt, sh, true); " "}\n" - , mem, form, OP_EXT); + , mem, form, OP_EXT_XS); } else if (!strcmp(form, "XL")) { if (!strcmp(mem, "BCLR")) { printf( diff --git a/externals/powah/powah_emit.hpp b/externals/powah/powah_emit.hpp index b00be04623..1aa11f53a2 100644 --- a/externals/powah/powah_emit.hpp +++ b/externals/powah/powah_emit.hpp @@ -211,10 +211,10 @@ struct Context { } void emit_XS(uint32_t op, GPR const rt, GPR const ra, uint32_t sh, bool rc) { base[offset++] = (op | - bitExt(rt.index, 6, 5) - | bitExt(ra.index, 11, 5) - | bitExt(sh, 16, 5) - | bitExt(sh >> 5, 30, 1) + ((rt.index & 0x1f) << 16) + | ((ra.index & 0x1f) << 21) + | ((sh & 0x1f) << 11) + | ((sh >> 4) & 0x02) | bitExt(rc, 31, 1) ); } diff --git a/externals/powah/powah_gen_base.hpp b/externals/powah/powah_gen_base.hpp index 6852da14f4..97b2410a09 100644 --- a/externals/powah/powah_gen_base.hpp +++ b/externals/powah/powah_gen_base.hpp @@ -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(0x7c00033a, rt, ra, sh, false); } -void SRADI_(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c00033a, rt, ra, sh, 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 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); } diff --git a/externals/powah/tests.cpp b/externals/powah/tests.cpp index 65baedb47b..c9e0add6b2 100644 --- a/externals/powah/tests.cpp +++ b/externals/powah/tests.cpp @@ -174,6 +174,43 @@ TEST_CASE("ppc64: rlwimi madness", "[ppc64]") { REQUIRE(data[7] == EB32(0x0e004379)); } +/* + 0: 78 1b 68 7c mr 8, 3 + 4: 38 28 83 7c and 3, 4, 5 + 8: 74 00 6a 7c cntlzd 10, 3 + c: 76 06 69 7c sradi 9, 3, 32 + 10: 82 d1 4a 79 rldicl 10, 10, 58, 6 + 14: 00 00 29 55 rlwinm 9, 9, 0, 0, 0 + 18: 64 f0 4a 79 sldi 10, 10, 30 + 1c: 78 53 29 7d or 9, 9, 10 + 20: 00 00 28 f9 std 9, 0(8) + 24: 20 00 80 4e blr +*/ +TEST_CASE("ppc64: functor-2", "[ppc64]") { + std::vector data(64); + powah::Context ctx(data.data(), data.size()); + ctx.MR(powah::R8, powah::R3); + ctx.AND(powah::R3, powah::R4, powah::R5); + ctx.CNTLZD(powah::R10, powah::R3); + ctx.SRADI(powah::R9, powah::R3, 32); + ctx.RLDICL(powah::R10, powah::R10, 58, 6); + 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.BLR(); + REQUIRE(data[0] == EB32(0x781b687c)); + REQUIRE(data[1] == EB32(0x3828837c)); + REQUIRE(data[2] == EB32(0x74006a7c)); + REQUIRE(data[3] == EB32(0x7606697c)); + REQUIRE(data[4] == EB32(0x82d14a79)); + REQUIRE(data[5] == EB32(0x00002955)); + REQUIRE(data[6] == EB32(0x64f04a79)); + REQUIRE(data[7] == EB32(0x7853297d)); + REQUIRE(data[8] == EB32(0x000028f9)); + REQUIRE(data[9] == EB32(0x2000804e)); +} + TEST_CASE("ppc64: functor-1", "[ppc64]") { std::vector data(64); powah::Context ctx(data.data(), data.size()); 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 cef9a7b06d..ee3002ce89 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 @@ -562,7 +562,9 @@ 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.RLDICL(result, src_a, 0, 32); // Truncate - code.AND_(result, result, src_b); + code.AND(result, result, src_b); + auto const tmp = ctx.reg_alloc.ScratchGpr(); + code.ANDI_(tmp, result, 0); ctx.reg_alloc.DefineValue(inst, result); }