3
externals/powah/powah_emit.hpp
vendored
3
externals/powah/powah_emit.hpp
vendored
@@ -366,6 +366,9 @@ struct Context {
|
||||
void LI(GPR const rx, uint32_t value) { ADDI(rx, R0, value); }
|
||||
void LIS(GPR const rx, uint32_t value) { ADDIS(rx, R0, value); }
|
||||
|
||||
void MFLR(GPR const rt) { MFSPR(powah::GPR{8}, rt, powah::GPR{0}); }
|
||||
void MTLR(GPR const rt) { MTSPR(powah::GPR{8}, rt, powah::GPR{0}); }
|
||||
|
||||
void BLR() {
|
||||
base[offset++] = 0x4e800020; //BCLR(R0, CR0, R0);
|
||||
}
|
||||
|
||||
@@ -72,8 +72,8 @@ struct A32Core final {
|
||||
static HaltReason Run(A32AddressSpace& process, A32JitState& thread_ctx, volatile u32* halt_reason) {
|
||||
auto const loc = thread_ctx.GetLocationDescriptor();
|
||||
auto const entry = process.GetOrEmit(loc);
|
||||
using CodeFn = HaltReason (*)(A32JitState*, volatile u32*);
|
||||
return (CodeFn(entry))(&thread_ctx, halt_reason);
|
||||
using CodeFn = HaltReason (*)(A32AddressSpace*, A32JitState*, volatile u32*);
|
||||
return (CodeFn(entry))(&process, &thread_ctx, halt_reason);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ struct A64JitState {
|
||||
u64 pc = 0;
|
||||
alignas(16) std::array<u64, 64> vec{};
|
||||
u64 sp = 0;
|
||||
u32 upper_location_descriptor;
|
||||
u32 upper_location_descriptor = 0;
|
||||
u32 exclusive_state = 0;
|
||||
u32 pstate = 0;
|
||||
u32 fpcr = 0;
|
||||
@@ -30,7 +30,9 @@ struct A64JitState {
|
||||
volatile u32 halt_reason = 0;
|
||||
u8 check_bit = 0;
|
||||
IR::LocationDescriptor GetLocationDescriptor() const {
|
||||
return IR::LocationDescriptor{regs[15] | (u64(upper_location_descriptor) << 32)};
|
||||
const u64 fpcr_u64 = u64(fpcr & A64::LocationDescriptor::fpcr_mask) << A64::LocationDescriptor::fpcr_shift;
|
||||
const u64 pc_u64 = pc & A64::LocationDescriptor::pc_mask;
|
||||
return IR::LocationDescriptor{pc_u64 | fpcr_u64};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@ struct A64AddressSpace final {
|
||||
CodePtr GetOrEmit(IR::LocationDescriptor desc) {
|
||||
if (auto const it = block_entries.find(desc.Value()); it != block_entries.end())
|
||||
return it->second;
|
||||
|
||||
const auto get_code = [this](u64 vaddr) {
|
||||
auto const get_code = [this](u64 vaddr) {
|
||||
return conf.callbacks->MemoryReadCode(vaddr);
|
||||
};
|
||||
IR::Block ir_block = A64::Translate(A64::LocationDescriptor{desc}, get_code, {conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
||||
@@ -75,8 +74,8 @@ struct A64Core final {
|
||||
static HaltReason Run(A64AddressSpace& process, A64JitState& thread_ctx, volatile u32* halt_reason) {
|
||||
const auto loc = thread_ctx.GetLocationDescriptor();
|
||||
const auto entry = process.GetOrEmit(loc);
|
||||
using CodeFn = HaltReason (*)(A64JitState*, volatile u32*);
|
||||
return (CodeFn(entry))(&thread_ctx, halt_reason);
|
||||
using CodeFn = HaltReason (*)(A64AddressSpace*, A64JitState*, volatile u32*);
|
||||
return (CodeFn(entry))(&process, &thread_ctx, halt_reason);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
|
||||
namespace Dynarmic::Backend::PPC64 {
|
||||
|
||||
constexpr powah::GPR RJIT = powah::R3; //yeah it's param, so what?
|
||||
// Jit fn signature => (AXXAddressSpace& process, AXXJitState& thread_ctx, volatile u32* halt_reason)
|
||||
constexpr powah::GPR RPROCESS = powah::R3;
|
||||
constexpr powah::GPR RJIT = powah::R4;
|
||||
constexpr powah::GPR RHALTREASON = powah::R5;
|
||||
constexpr powah::GPR RNZCV = powah::R31;
|
||||
|
||||
constexpr powah::GPR ABI_PARAM1 = powah::R3;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "dynarmic/backend/ppc64/emit_ppc64.h"
|
||||
|
||||
#include <bit>
|
||||
#include <cstdint>
|
||||
|
||||
#include <powah_emit.hpp>
|
||||
#include <fmt/ostream.h>
|
||||
@@ -156,10 +157,21 @@ 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();
|
||||
code.LI(tmp, terminal.next.Value());
|
||||
if (ctx.emit_conf.a64_variant)
|
||||
if (ctx.emit_conf.a64_variant) {
|
||||
code.STD(tmp, PPC64::RJIT, offsetof(A64JitState, pc));
|
||||
else
|
||||
code.MFLR(PPC64::RLINKFN);
|
||||
for (u32 i = 0; i < 4; ++i)
|
||||
code.STD(powah::GPR{3 + i}, powah::R1, -((GPR_ORDER.size() + i) * 8));
|
||||
code.ADDIS(powah::R1, powah::R1, -sizeof(StackLayout));
|
||||
code.BLR();
|
||||
code.ADDI(powah::R1, powah::R1, sizeof(StackLayout));
|
||||
for (u32 i = 0; i < 4; ++i)
|
||||
code.LD(powah::GPR{3 + i}, powah::R1, -((GPR_ORDER.size() + i) * 8));
|
||||
code.MTLR(PPC64::RLINKFN);
|
||||
} else {
|
||||
code.STW(tmp, PPC64::RJIT, offsetof(A32JitState, regs) + sizeof(u32) * 15);
|
||||
ASSERT(false && "unimp");
|
||||
}
|
||||
}
|
||||
|
||||
void EmitTerminal(powah::Context& code, EmitContext& ctx, IR::Term::LinkBlockFast terminal, IR::LocationDescriptor initial_location, bool) {
|
||||
@@ -211,7 +223,7 @@ EmittedBlockInfo EmitPPC64(powah::Context& code, IR::Block block, const EmitConf
|
||||
EmitContext ctx{block, reg_alloc, emit_conf, ebi};
|
||||
|
||||
auto const start_offset = code.offset;
|
||||
ebi.entry_point = CodePtr(code.base + start_offset);
|
||||
ebi.entry_point = &code.base[start_offset];
|
||||
|
||||
// Non-volatile saves
|
||||
std::vector<u32> gpr_order{GPR_ORDER};
|
||||
|
||||
@@ -21,21 +21,9 @@ enum class Opcode;
|
||||
|
||||
namespace Dynarmic::Backend::PPC64 {
|
||||
|
||||
using CodePtr = std::byte*;
|
||||
|
||||
enum class LinkTarget {
|
||||
ReturnFromRunCode,
|
||||
};
|
||||
|
||||
struct Relocation {
|
||||
std::ptrdiff_t code_offset;
|
||||
LinkTarget target;
|
||||
};
|
||||
|
||||
struct EmittedBlockInfo {
|
||||
CodePtr entry_point;
|
||||
std::uint32_t* entry_point;
|
||||
size_t size;
|
||||
std::vector<Relocation> relocations;
|
||||
};
|
||||
|
||||
struct EmitConfig {
|
||||
|
||||
Reference in New Issue
Block a user