Browse Source

first emitted block

Signed-off-by: lizzie <lizzie@eden-emu.dev>
dynarmic-ppc64
lizzie 2 months ago
parent
commit
b68db08e6a
No known key found for this signature in database GPG Key ID: 287378CADCAB13
  1. 3
      src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.h
  2. 26
      src/dynarmic/src/dynarmic/backend/ppc64/a32_core.h
  3. 17
      src/dynarmic/src/dynarmic/backend/ppc64/a32_interface.cpp
  4. 13
      src/dynarmic/src/dynarmic/backend/ppc64/a64_core.h
  5. 9
      src/dynarmic/src/dynarmic/backend/ppc64/a64_interface.cpp
  6. 6
      src/dynarmic/src/dynarmic/backend/ppc64/abi.h
  7. 17
      src/dynarmic/src/dynarmic/backend/ppc64/code_block.h
  8. 28
      src/dynarmic/src/dynarmic/backend/ppc64/emit_ppc64.cpp

3
src/dynarmic/src/dynarmic/backend/arm64/a64_address_space.h

@ -23,11 +23,8 @@ public:
protected: protected:
friend class A64Core; friend class A64Core;
void EmitPrelude();
EmitConfig GetEmitConfig() override; EmitConfig GetEmitConfig() override;
void RegisterNewBasicBlock(const IR::Block& block, const EmittedBlockInfo& block_info) override; void RegisterNewBasicBlock(const IR::Block& block, const EmittedBlockInfo& block_info) override;
const A64::UserConfig conf; const A64::UserConfig conf;
BlockRangeInformation<u64> block_ranges; BlockRangeInformation<u64> block_ranges;
}; };

26
src/dynarmic/src/dynarmic/backend/ppc64/a32_core.h

@ -30,47 +30,29 @@ struct A32JitState {
class A32AddressSpace final { class A32AddressSpace final {
public: public:
explicit A32AddressSpace(const A32::UserConfig& conf); explicit A32AddressSpace(const A32::UserConfig& conf);
IR::Block GenerateIR(IR::LocationDescriptor) const; IR::Block GenerateIR(IR::LocationDescriptor) const;
CodePtr Get(IR::LocationDescriptor descriptor); CodePtr Get(IR::LocationDescriptor descriptor);
CodePtr GetOrEmit(IR::LocationDescriptor descriptor); CodePtr GetOrEmit(IR::LocationDescriptor descriptor);
void ClearCache(); void ClearCache();
private: private:
friend class A32Core; friend class A32Core;
void EmitPrelude();
EmittedBlockInfo Emit(IR::Block ir_block); EmittedBlockInfo Emit(IR::Block ir_block);
void Link(EmittedBlockInfo& block); void Link(EmittedBlockInfo& block);
const A32::UserConfig conf; const A32::UserConfig conf;
CodeBlock cb; CodeBlock cb;
powah::Context as; powah::Context as;
ankerl::unordered_dense::map<u64, CodePtr> block_entries; ankerl::unordered_dense::map<u64, CodePtr> block_entries;
ankerl::unordered_dense::map<u64, EmittedBlockInfo> block_infos; ankerl::unordered_dense::map<u64, EmittedBlockInfo> block_infos;
struct PreludeInfo {
CodePtr end_of_prelude;
using RunCodeFuncType = HaltReason (*)(CodePtr entry_point, A32JitState* context, volatile u32* halt_reason);
RunCodeFuncType run_code;
CodePtr return_from_run_code;
} prelude_info;
}; };
class A32Core final { class A32Core final {
public: public:
explicit A32Core(const A32::UserConfig&) {} explicit A32Core(const A32::UserConfig&) {}
HaltReason Run(A32AddressSpace& process, A32JitState& thread_ctx, volatile u32* halt_reason) { HaltReason Run(A32AddressSpace& process, A32JitState& thread_ctx, volatile u32* halt_reason) {
const auto location_descriptor = thread_ctx.GetLocationDescriptor();
const auto entry_point = process.GetOrEmit(location_descriptor);
return process.prelude_info.run_code(entry_point, &thread_ctx, 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);
} }
}; };

17
src/dynarmic/src/dynarmic/backend/ppc64/a32_interface.cpp

@ -23,7 +23,7 @@ A32AddressSpace::A32AddressSpace(const A32::UserConfig& conf)
: conf(conf) : conf(conf)
, cb(conf.code_cache_size) , cb(conf.code_cache_size)
, as(cb.ptr<u8*>(), conf.code_cache_size) { , as(cb.ptr<u8*>(), conf.code_cache_size) {
EmitPrelude();
} }
IR::Block A32AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const { IR::Block A32AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const {
@ -33,15 +33,13 @@ IR::Block A32AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const {
} }
CodePtr A32AddressSpace::Get(IR::LocationDescriptor descriptor) { CodePtr A32AddressSpace::Get(IR::LocationDescriptor descriptor) {
if (const auto iter = block_entries.find(descriptor.Value()); iter != block_entries.end())
return iter->second;
return nullptr;
auto const it = block_entries.find(descriptor.Value());
return it != block_entries.end() ? it->second : nullptr;
} }
CodePtr A32AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) { CodePtr A32AddressSpace::GetOrEmit(IR::LocationDescriptor descriptor) {
if (CodePtr block_entry = Get(descriptor)) {
if (CodePtr block_entry = Get(descriptor); block_entry != nullptr)
return block_entry; return block_entry;
}
IR::Block ir_block = GenerateIR(descriptor); IR::Block ir_block = GenerateIR(descriptor);
const EmittedBlockInfo block_info = Emit(std::move(ir_block)); const EmittedBlockInfo block_info = Emit(std::move(ir_block));
@ -56,10 +54,6 @@ void A32AddressSpace::ClearCache() {
block_infos.clear(); block_infos.clear();
} }
void A32AddressSpace::EmitPrelude() {
UNREACHABLE();
}
EmittedBlockInfo A32AddressSpace::Emit(IR::Block block) { EmittedBlockInfo A32AddressSpace::Emit(IR::Block block) {
EmittedBlockInfo block_info = EmitPPC64(as, std::move(block), { EmittedBlockInfo block_info = EmitPPC64(as, std::move(block), {
.enable_cycle_counting = conf.enable_cycle_counting, .enable_cycle_counting = conf.enable_cycle_counting,
@ -70,7 +64,7 @@ EmittedBlockInfo A32AddressSpace::Emit(IR::Block block) {
} }
void A32AddressSpace::Link(EmittedBlockInfo& block_info) { void A32AddressSpace::Link(EmittedBlockInfo& block_info) {
UNREACHABLE();
//UNREACHABLE();
} }
} }
@ -160,7 +154,6 @@ struct Jit::Impl final {
private: private:
void RequestCacheInvalidation() { void RequestCacheInvalidation() {
// UNREACHABLE(); // UNREACHABLE();
invalidate_entire_cache = false; invalidate_entire_cache = false;
invalid_cache_ranges.clear(); invalid_cache_ranges.clear();
} }

13
src/dynarmic/src/dynarmic/backend/ppc64/a64_core.h

@ -52,12 +52,6 @@ private:
powah::Context as; powah::Context as;
ankerl::unordered_dense::map<u64, CodePtr> block_entries; ankerl::unordered_dense::map<u64, CodePtr> block_entries;
ankerl::unordered_dense::map<u64, EmittedBlockInfo> block_infos; ankerl::unordered_dense::map<u64, EmittedBlockInfo> block_infos;
struct PreludeInfo {
CodePtr end_of_prelude;
using RunCodeFuncType = HaltReason (*)(CodePtr entry_point, A64JitState* context, volatile u32* halt_reason);
RunCodeFuncType run_code;
CodePtr return_from_run_code;
} prelude_info;
}; };
class A64Core final { class A64Core final {
@ -65,9 +59,10 @@ public:
explicit A64Core(const A64::UserConfig&) {} explicit A64Core(const A64::UserConfig&) {}
HaltReason Run(A64AddressSpace& process, A64JitState& thread_ctx, volatile u32* halt_reason) { HaltReason Run(A64AddressSpace& process, A64JitState& thread_ctx, volatile u32* halt_reason) {
const auto location_descriptor = thread_ctx.GetLocationDescriptor();
const auto entry_point = process.GetOrEmit(location_descriptor);
return process.prelude_info.run_code(entry_point, &thread_ctx, 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);
} }
}; };

9
src/dynarmic/src/dynarmic/backend/ppc64/a64_interface.cpp

@ -22,7 +22,7 @@ A64AddressSpace::A64AddressSpace(const A64::UserConfig& conf)
: conf(conf) : conf(conf)
, cb(conf.code_cache_size) , cb(conf.code_cache_size)
, as(cb.ptr<u8*>(), conf.code_cache_size) { , as(cb.ptr<u8*>(), conf.code_cache_size) {
EmitPrelude();
} }
CodePtr A64AddressSpace::Get(IR::LocationDescriptor descriptor) { CodePtr A64AddressSpace::Get(IR::LocationDescriptor descriptor) {
@ -52,10 +52,6 @@ void A64AddressSpace::ClearCache() {
block_infos.clear(); block_infos.clear();
} }
void A64AddressSpace::EmitPrelude() {
UNREACHABLE();
}
EmittedBlockInfo A64AddressSpace::Emit(IR::Block block) { EmittedBlockInfo A64AddressSpace::Emit(IR::Block block) {
EmittedBlockInfo block_info = EmitPPC64(as, std::move(block), { EmittedBlockInfo block_info = EmitPPC64(as, std::move(block), {
.enable_cycle_counting = conf.enable_cycle_counting, .enable_cycle_counting = conf.enable_cycle_counting,
@ -66,7 +62,8 @@ EmittedBlockInfo A64AddressSpace::Emit(IR::Block block) {
} }
void A64AddressSpace::Link(EmittedBlockInfo& block_info) { void A64AddressSpace::Link(EmittedBlockInfo& block_info) {
UNREACHABLE();
// TODO(lizzie): Block linking
// UNREACHABLE();
} }
} }

6
src/dynarmic/src/dynarmic/backend/ppc64/abi.h

@ -15,7 +15,9 @@ constexpr powah::GPR ABI_PARAM2 = powah::R4;
constexpr powah::GPR ABI_PARAM3 = powah::R5; constexpr powah::GPR ABI_PARAM3 = powah::R5;
constexpr powah::GPR ABI_PARAM4 = powah::R6; constexpr powah::GPR ABI_PARAM4 = powah::R6;
constexpr std::initializer_list<u32> GPR_ORDER{8, 9, 18, 19, 20, 21, 22, 23, 24, 25, 5, 6, 7, 28, 29, 10, 11, 12, 13, 14, 15, 16, 17};
constexpr std::initializer_list<u32> FPR_ORDER{8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
// See https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#REG
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
};
} // namespace Dynarmic::Backend::RV64 } // namespace Dynarmic::Backend::RV64

17
src/dynarmic/src/dynarmic/backend/ppc64/code_block.h

@ -15,22 +15,23 @@ namespace Dynarmic::Backend::PPC64 {
class CodeBlock { class CodeBlock {
public: public:
explicit CodeBlock(std::size_t size) noexcept : memsize(size) {
mem = (u8*)mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT(mem != nullptr);
explicit CodeBlock(size_t size_) noexcept : size{size_} {
block = (u8*)mmap(nullptr, size, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
//printf("block = %p, size= %zx\n", block, size);
ASSERT(block != nullptr);
} }
~CodeBlock() noexcept { ~CodeBlock() noexcept {
if (mem != nullptr)
munmap(mem, memsize);
if (block != nullptr)
munmap(block, size);
} }
template<typename T> template<typename T>
T ptr() const noexcept { T ptr() const noexcept {
static_assert(std::is_pointer_v<T> || std::is_same_v<T, uintptr_t> || std::is_same_v<T, intptr_t>); static_assert(std::is_pointer_v<T> || std::is_same_v<T, uintptr_t> || std::is_same_v<T, intptr_t>);
return reinterpret_cast<T>(mem);
return reinterpret_cast<T>(block);
} }
protected: protected:
u8* mem = nullptr;
size_t memsize = 0;
void* block = nullptr;
size_t size = 0;
}; };
} // namespace Dynarmic::Backend::RV64 } // namespace Dynarmic::Backend::RV64

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

@ -87,26 +87,33 @@ void EmitIR<IR::Opcode::NZCVFromPackedFlags>(powah::Context&, EmitContext&, IR::
UNREACHABLE(); UNREACHABLE();
} }
EmittedBlockInfo EmitPPC64(powah::Context& as, IR::Block block, const EmitConfig& emit_conf) {
EmittedBlockInfo EmitPPC64(powah::Context& code, IR::Block block, const EmitConfig& emit_conf) {
EmittedBlockInfo ebi; EmittedBlockInfo ebi;
RegAlloc reg_alloc{as};
RegAlloc reg_alloc{code};
EmitContext ctx{block, reg_alloc, emit_conf, ebi}; EmitContext ctx{block, reg_alloc, emit_conf, ebi};
//ebi.entry_point = reinterpret_cast<CodePtr>(as.GetCursorPointer());
ebi.entry_point = CodePtr(code.base + code.offset);
code.BLR();
// 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));
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;
switch (inst->GetOpcode()) { switch (inst->GetOpcode()) {
#define OPCODE(name, type, ...) \ #define OPCODE(name, type, ...) \
case IR::Opcode::name: \ case IR::Opcode::name: \
EmitIR<IR::Opcode::name>(as, ctx, inst); \
EmitIR<IR::Opcode::name>(code, ctx, inst); \
break; break;
#define A32OPC(name, type, ...) \ #define A32OPC(name, type, ...) \
case IR::Opcode::A32##name: \ case IR::Opcode::A32##name: \
EmitIR<IR::Opcode::A32##name>(as, ctx, inst); \
EmitIR<IR::Opcode::A32##name>(code, ctx, inst); \
break; break;
#define A64OPC(name, type, ...) \ #define A64OPC(name, type, ...) \
case IR::Opcode::A64##name: \ case IR::Opcode::A64##name: \
EmitIR<IR::Opcode::A64##name>(as, ctx, inst); \
EmitIR<IR::Opcode::A64##name>(code, ctx, inst); \
break; break;
#include "dynarmic/ir/opcodes.inc" #include "dynarmic/ir/opcodes.inc"
#undef OPCODE #undef OPCODE
@ -116,8 +123,11 @@ EmittedBlockInfo EmitPPC64(powah::Context& as, IR::Block block, const EmitConfig
UNREACHABLE(); UNREACHABLE();
} }
} }
//UNREACHABLE();
//ebi.size = reinterpret_cast<CodePtr>(as.GetCursorPointer()) - ebi.entry_point;
for (size_t i = 0; i < gpr_order.size(); ++i)
code.LD(powah::GPR{gpr_order[i]}, powah::R1, -(i * 8));
code.BLR();
ebi.size = code.offset;
return ebi; return ebi;
} }

Loading…
Cancel
Save