Browse Source

the abi sucks

Signed-off-by: lizzie <lizzie@eden-emu.dev>
dynarmic-ppc64
lizzie 2 weeks ago
parent
commit
328f496ef9
No known key found for this signature in database GPG Key ID: 287378CADCAB13
  1. 9
      src/dynarmic/src/dynarmic/backend/ppc64/abi.h
  2. 28
      src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp
  3. 7
      src/dynarmic/src/dynarmic/backend/ppc64/stack_layout.h

9
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 // See https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#REG
constexpr std::initializer_list<u32> GPR_ORDER{ constexpr std::initializer_list<u32> 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<powah::GPR> 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<powah::GPR> ABI_CALLEE_SAVED{ constexpr std::initializer_list<powah::GPR> ABI_CALLEE_SAVED{
powah::R14, powah::R15, powah::R16, powah::R17, powah::R14, powah::R15, powah::R16, powah::R17,
powah::R18, powah::R19, powah::R20, powah::R21, powah::R18, powah::R19, powah::R20, powah::R21,

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

@ -20,6 +20,7 @@
#include "dynarmic/ir/basic_block.h" #include "dynarmic/ir/basic_block.h"
#include "dynarmic/ir/microinstruction.h" #include "dynarmic/ir/microinstruction.h"
#include "dynarmic/ir/opcodes.h" #include "dynarmic/ir/opcodes.h"
#include "stack_layout.h"
namespace Dynarmic::Backend::PPC64 { 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) { 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) { if (ctx.emit_conf.a64_variant) {
auto const tmp = ctx.reg_alloc.ScratchGpr();
code.LI(tmp, terminal.next.Value()); code.LI(tmp, terminal.next.Value());
code.STD(tmp, PPC64::RJIT, offsetof(A64JitState, pc)); code.STD(tmp, PPC64::RJIT, offsetof(A64JitState, pc));
code.LD(tmp, PPC64::RJIT, offsetof(A64JitState, run_fn)); code.LD(tmp, PPC64::RJIT, offsetof(A64JitState, run_fn));
code.MTCTR(tmp); 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.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 { } else {
auto const tmp = ctx.reg_alloc.ScratchGpr();
code.LI(tmp, terminal.next.Value()); code.LI(tmp, terminal.next.Value());
code.STW(tmp, PPC64::RJIT, offsetof(A32JitState, regs) + sizeof(u32) * 15); code.STW(tmp, PPC64::RJIT, offsetof(A32JitState, regs) + sizeof(u32) * 15);
ASSERT(false && "unimp"); ASSERT(false && "unimp");
@ -225,10 +222,14 @@ EmittedBlockInfo EmitPPC64(powah::Context& code, IR::Block block, const EmitConf
auto const start_offset = code.offset; auto const start_offset = code.offset;
ebi.entry_point = &code.base[start_offset]; ebi.entry_point = &code.base[start_offset];
code.MFLR(powah::R0);
code.STD(powah::R0, powah::R1, offsetof(StackLayout, lr));
// Non-volatile saves // Non-volatile saves
std::vector<u32> 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<powah::GPR> 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) { for (auto iter = block.begin(); iter != block.end(); ++iter) {
IR::Inst* inst = &*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(); // auto const cycles_to_add = block.CycleCount();
EmitTerminal(code, ctx, ctx.block.GetTerminal(), ctx.block.Location(), false); 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.BLR();
code.ApplyRelocs(); code.ApplyRelocs();

7
src/dynarmic/src/dynarmic/backend/ppc64/stack_layout.h

@ -12,11 +12,12 @@ namespace Dynarmic::Backend::PPC64 {
constexpr size_t SpillCount = 16; constexpr size_t SpillCount = 16;
struct alignas(16) StackLayout { struct alignas(16) StackLayout {
std::array<u64, 18> regs;
u64 resv0; //0
u64 resv1; //8
u64 lr; //16
u64 sp; //24
std::array<u64, SpillCount> spill; std::array<u64, SpillCount> spill;
u64 check_bit; u64 check_bit;
void* lr;
std::array<u64, 29> extra_regs;
}; };
static_assert(sizeof(StackLayout) % 16 == 0); static_assert(sizeof(StackLayout) % 16 == 0);

Loading…
Cancel
Save