diff --git a/src/dynarmic/src/dynarmic/backend/ppc64/abi.h b/src/dynarmic/src/dynarmic/backend/ppc64/abi.h index 1b24e1e9a8..51af0d73b7 100644 --- a/src/dynarmic/src/dynarmic/backend/ppc64/abi.h +++ b/src/dynarmic/src/dynarmic/backend/ppc64/abi.h @@ -55,9 +55,16 @@ constexpr powah::GPR ABI_PARAM4 = powah::R6; // See https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#REG constexpr std::initializer_list GPR_ORDER{ - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 + //6, 7, 8, 9, 10, 11, 12, //volatile + // r13 is thread-id + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 //non-volatile }; +constexpr std::initializer_list ABI_CALLEER_SAVED{ + powah::R3, powah::R4, powah::R5, powah::R6, + powah::R7, powah::R8, powah::R9, powah::R10, + powah::R11, powah::R12 +}; constexpr std::initializer_list ABI_CALLEE_SAVED{ powah::R14, powah::R15, powah::R16, powah::R17, powah::R18, powah::R19, powah::R20, powah::R21, diff --git a/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp b/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp index 0d4e6e93c5..38e40af3f5 100644 --- a/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp +++ b/src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp @@ -20,6 +20,7 @@ #include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/microinstruction.h" #include "dynarmic/ir/opcodes.h" +#include "stack_layout.h" namespace Dynarmic::Backend::PPC64 { @@ -154,20 +155,16 @@ void EmitTerminal(powah::Context& code, EmitContext& ctx, IR::Term::ReturnToDisp } void EmitTerminal(powah::Context& code, EmitContext& ctx, IR::Term::LinkBlock terminal, IR::LocationDescriptor initial_location, bool) { - auto const tmp = ctx.reg_alloc.ScratchGpr(); if (ctx.emit_conf.a64_variant) { + auto const tmp = ctx.reg_alloc.ScratchGpr(); code.LI(tmp, terminal.next.Value()); code.STD(tmp, PPC64::RJIT, offsetof(A64JitState, pc)); code.LD(tmp, PPC64::RJIT, offsetof(A64JitState, run_fn)); code.MTCTR(tmp); - for (u32 i = 0; i < 16; ++i) - code.STD(powah::GPR{14 + i}, powah::R1, -(offsetof(StackLayout, extra_regs) + (i * 8))); - code.ADDIS(powah::R1, powah::R1, -sizeof(StackLayout)); code.BCTRL(); - code.ADDI(powah::R1, powah::R1, sizeof(StackLayout)); - for (u32 i = 0; i < 16; ++i) - code.LD(powah::GPR{14 + i}, powah::R1, -(offsetof(StackLayout, extra_regs) + (i * 8))); + code.LD(powah::R2, powah::R1, offsetof(StackLayout, sp)); } else { + auto const tmp = ctx.reg_alloc.ScratchGpr(); code.LI(tmp, terminal.next.Value()); code.STW(tmp, PPC64::RJIT, offsetof(A32JitState, regs) + sizeof(u32) * 15); ASSERT(false && "unimp"); @@ -225,10 +222,14 @@ EmittedBlockInfo EmitPPC64(powah::Context& code, IR::Block block, const EmitConf auto const start_offset = code.offset; ebi.entry_point = &code.base[start_offset]; + code.MFLR(powah::R0); + code.STD(powah::R0, powah::R1, offsetof(StackLayout, lr)); // Non-volatile saves - std::vector gpr_order{GPR_ORDER}; - for (size_t i = 0; i < gpr_order.size(); ++i) - code.STD(powah::GPR{gpr_order[i]}, powah::R1, -(i * 8)); + std::vector abi_callee_saved{ABI_CALLEE_SAVED}; + for (size_t i = 0; i < abi_callee_saved.size(); ++i) + code.STD(abi_callee_saved[i], powah::R1, -(8 + i * 8)); + code.STDU(powah::R1, powah::R1, -sizeof(StackLayout)); + code.STD(powah::R2, powah::R1, offsetof(StackLayout, sp)); for (auto iter = block.begin(); iter != block.end(); ++iter) { IR::Inst* inst = &*iter; @@ -257,8 +258,11 @@ EmittedBlockInfo EmitPPC64(powah::Context& code, IR::Block block, const EmitConf // auto const cycles_to_add = block.CycleCount(); EmitTerminal(code, ctx, ctx.block.GetTerminal(), ctx.block.Location(), false); - for (size_t i = 0; i < gpr_order.size(); ++i) - code.LD(powah::GPR{gpr_order[i]}, powah::R1, -(i * 8)); + code.ADDI(powah::R1, powah::R1, sizeof(StackLayout)); + code.LD(powah::R0, powah::R1, offsetof(StackLayout, lr)); + code.MTLR(powah::R0); + for (size_t i = 0; i < abi_callee_saved.size(); ++i) + code.LD(abi_callee_saved[i], powah::R1, -(8 + i * 8)); code.BLR(); code.ApplyRelocs(); diff --git a/src/dynarmic/src/dynarmic/backend/ppc64/stack_layout.h b/src/dynarmic/src/dynarmic/backend/ppc64/stack_layout.h index fa4948b364..d672ccea6b 100644 --- a/src/dynarmic/src/dynarmic/backend/ppc64/stack_layout.h +++ b/src/dynarmic/src/dynarmic/backend/ppc64/stack_layout.h @@ -12,11 +12,12 @@ namespace Dynarmic::Backend::PPC64 { constexpr size_t SpillCount = 16; struct alignas(16) StackLayout { - std::array regs; + u64 resv0; //0 + u64 resv1; //8 + u64 lr; //16 + u64 sp; //24 std::array spill; u64 check_bit; - void* lr; - std::array extra_regs; }; static_assert(sizeof(StackLayout) % 16 == 0);