Browse Source

even more stupid fixes i feel angry

Signed-off-by: lizzie <lizzie@eden-emu.dev>
dynarmic-ppc64
lizzie 2 months ago
parent
commit
108988f1b3
No known key found for this signature in database GPG Key ID: 287378CADCAB13
  1. 6
      externals/powah/data2code.c
  2. 2
      externals/powah/powah_emit.hpp
  3. 14
      externals/powah/powah_gen_base.hpp
  4. 2
      externals/powah/tests.cpp
  5. 26
      src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp
  6. 32
      src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_data_processing.cpp

6
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")) {

2
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) {

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

2
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));

26
src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp

@ -9,6 +9,7 @@
#include <fmt/ostream.h>
#include <mcl/bit/bit_field.hpp>
#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<IR::Opcode::GetNZCVFromOp>(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<IR::Opcode::GetNZCVFromOp>(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);
}
}

32
src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64_data_processing.cpp

@ -558,14 +558,33 @@ void EmitIR<IR::Opcode::SignedDiv64>(powah::Context& code, EmitContext& ctx, IR:
template<>
void EmitIR<IR::Opcode::And32>(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<IR::Opcode::And64>(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);
}

Loading…
Cancel
Save