mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-20 00:31:28 +00:00
better handling of static translation cache allocation, handle nested
execution paths from the cpu core, cleanups for KPX_MAX_CPUS == 1.
This commit is contained in:
parent
c1dba58808
commit
4a3cd024ed
@ -118,9 +118,6 @@ public:
|
||||
uint32 get_cr() const { return cr().get(); }
|
||||
void set_cr(uint32 v) { cr().set(v); }
|
||||
|
||||
// Execution loop
|
||||
void execute(uint32 entry, bool enable_cache = false);
|
||||
|
||||
// Execute 68k routine
|
||||
void execute_68k(uint32 entry, M68kRegisters *r);
|
||||
|
||||
@ -244,12 +241,6 @@ void sheepshaver_cpu::execute_sheep(uint32 opcode)
|
||||
}
|
||||
}
|
||||
|
||||
// Execution loop
|
||||
void sheepshaver_cpu::execute(uint32 entry, bool enable_cache)
|
||||
{
|
||||
powerpc_cpu::execute(entry, enable_cache);
|
||||
}
|
||||
|
||||
// Handle MacOS interrupt
|
||||
void sheepshaver_cpu::interrupt(uint32 entry)
|
||||
{
|
||||
@ -686,7 +677,7 @@ void emul_ppc(uint32 entry)
|
||||
current_cpu->start_log();
|
||||
#endif
|
||||
// start emulation loop and enable code translation or caching
|
||||
current_cpu->execute(entry, true);
|
||||
current_cpu->execute(entry);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -28,8 +28,8 @@ int __op_jmp0, __op_jmp1;
|
||||
#define DEFINE_GEN(NAME,ARGS) void basic_dyngen::NAME ARGS
|
||||
#include "basic-dyngen-ops.hpp"
|
||||
|
||||
basic_dyngen::basic_dyngen(dyngen_cpu_base cpu)
|
||||
: parent_cpu(cpu)
|
||||
basic_dyngen::basic_dyngen(dyngen_cpu_base cpu, int cache_size)
|
||||
: parent_cpu(cpu), basic_jit_cache(cache_size)
|
||||
{
|
||||
execute_func = gen_start();
|
||||
gen_op_execute();
|
||||
|
@ -52,7 +52,7 @@ class basic_dyngen
|
||||
public:
|
||||
|
||||
// Constructor, parent CPU required
|
||||
basic_dyngen(dyngen_cpu_base cpu);
|
||||
basic_dyngen(dyngen_cpu_base cpu, int cache_size = -1);
|
||||
|
||||
// Return CPU context associated to this code generator
|
||||
dyngen_cpu_base cpu() const
|
||||
|
@ -30,10 +30,13 @@
|
||||
#endif
|
||||
|
||||
#if STATIC_ICACHE_ALLOC
|
||||
static uint8 g_translation_cache[basic_jit_cache::JIT_CACHE_SIZE];
|
||||
const int G_TRANSLATION_CACHE_SIZE = 3 * 1024 * 1024; // 3 MB
|
||||
static uint8 g_translation_cache[G_TRANSLATION_CACHE_SIZE];
|
||||
static uint8 *g_translation_cache_p;
|
||||
static uint8 *g_translation_cache_end_p;
|
||||
#endif
|
||||
|
||||
basic_jit_cache::basic_jit_cache(uint32 init_cache_size)
|
||||
basic_jit_cache::basic_jit_cache(int init_cache_size)
|
||||
: tcode_start(NULL), code_start(NULL), code_p(NULL), code_end(NULL)
|
||||
{
|
||||
init_translation_cache(init_cache_size);
|
||||
@ -45,16 +48,27 @@ basic_jit_cache::~basic_jit_cache()
|
||||
}
|
||||
|
||||
bool
|
||||
basic_jit_cache::init_translation_cache(uint32 size)
|
||||
basic_jit_cache::init_translation_cache(int size)
|
||||
{
|
||||
// Round up translation cache size to next 16 KB boundaries
|
||||
const uint32 roundup = 16 * 1024;
|
||||
uint32 effective_cache_size = (size - JIT_CACHE_SIZE_GUARD) & -roundup;
|
||||
cache_size = size & -roundup;
|
||||
#if STATIC_ICACHE_ALLOC
|
||||
if (g_translation_cache_p == 0) {
|
||||
g_translation_cache_p = g_translation_cache;
|
||||
g_translation_cache_end_p = g_translation_cache_p + G_TRANSLATION_CACHE_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (size == -1)
|
||||
size = JIT_CACHE_SIZE;
|
||||
|
||||
// Round up translation cache size to next guard size boundaries boundaries
|
||||
const uint32 roundup = JIT_CACHE_SIZE_GUARD;
|
||||
cache_size = (size + roundup - 1) & -roundup;
|
||||
assert(cache_size > 0);
|
||||
|
||||
#if STATIC_ICACHE_ALLOC
|
||||
if (cache_size <= JIT_CACHE_SIZE) {
|
||||
tcode_start = g_translation_cache;
|
||||
if (cache_size <= (g_translation_cache_end_p - g_translation_cache_p)) {
|
||||
tcode_start = g_translation_cache_p;
|
||||
g_translation_cache_p += cache_size;
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
@ -75,7 +89,7 @@ basic_jit_cache::init_translation_cache(uint32 size)
|
||||
D(bug("basic_jit_cache: Translation cache: %d KB at %p\n", cache_size / 1024, tcode_start));
|
||||
code_start = tcode_start;
|
||||
code_p = code_start;
|
||||
code_end = code_p + effective_cache_size;
|
||||
code_end = code_p + size;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -84,8 +98,16 @@ basic_jit_cache::kill_translation_cache()
|
||||
{
|
||||
if (tcode_start) {
|
||||
#if STATIC_ICACHE_ALLOC
|
||||
if (cache_size > JIT_CACHE_SIZE)
|
||||
if ((tcode_start - g_translation_cache) <= G_TRANSLATION_CACHE_SIZE) {
|
||||
if (tcode_start == g_translation_cache_p - cache_size) {
|
||||
D(bug("basic_jit_cache: Merge back free translation cache: %d KB at %p\n",
|
||||
cache_size / 1024, tcode_start));
|
||||
g_translation_cache_p -= cache_size;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
D(bug("basic_jit_cache: Release translation cache\n"));
|
||||
vm_release(tcode_start, cache_size);
|
||||
}
|
||||
}
|
||||
|
@ -28,10 +28,8 @@
|
||||
class basic_jit_cache
|
||||
{
|
||||
// Default cache size (2 MB)
|
||||
public:
|
||||
static const uint32 JIT_CACHE_SIZE = 2 * 1024 * 1024;
|
||||
static const uint32 JIT_CACHE_SIZE_GUARD = 4096;
|
||||
private:
|
||||
uint32 cache_size;
|
||||
|
||||
// Translation cache (allocated base, current pointer, end pointer)
|
||||
@ -43,7 +41,7 @@ private:
|
||||
protected:
|
||||
|
||||
// Initialize translation cache
|
||||
bool init_translation_cache(uint32 size);
|
||||
bool init_translation_cache(int size);
|
||||
void kill_translation_cache();
|
||||
|
||||
// Initialize user code start
|
||||
@ -56,8 +54,8 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
// Default constructor & destructor
|
||||
basic_jit_cache(uint32 init_cache_size = JIT_CACHE_SIZE);
|
||||
// Default constructor & destructor (use default JIT_CACHE_SIZE)
|
||||
basic_jit_cache(int init_cache_size = -1);
|
||||
~basic_jit_cache();
|
||||
|
||||
// Invalidate translation cache
|
||||
|
@ -37,20 +37,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* PPC_NO_BASIC_CPU_BASE
|
||||
*
|
||||
* Define to not inherit from basic_cpu, thus removing two
|
||||
* vtables. Otherwise, access to registers require an extra
|
||||
* offset from "this" because vtables are stored before other
|
||||
* regular members.
|
||||
**/
|
||||
|
||||
#ifndef PPC_NO_BASIC_CPU_BASE
|
||||
#undef PPC_NO_BASIC_CPU_BASE
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* PPC_NO_STATIC_II_INDEX_TABLE
|
||||
*
|
||||
@ -144,8 +130,7 @@
|
||||
* Sanity checks and features enforcements
|
||||
**/
|
||||
|
||||
#ifdef SHEEPSHAVER
|
||||
#define PPC_NO_BASIC_CPU_BASE
|
||||
#if KPX_MAX_CPUS == 1
|
||||
#undef PPC_NO_STATIC_II_INDEX_TABLE
|
||||
#endif
|
||||
|
||||
|
@ -225,6 +225,7 @@ void powerpc_cpu::initialize()
|
||||
init_decoder();
|
||||
init_registers();
|
||||
init_decode_cache();
|
||||
execute_depth = 0;
|
||||
|
||||
// Init cache range invalidate recorder
|
||||
cache_range.start = cache_range.end = 0;
|
||||
@ -365,14 +366,16 @@ bool powerpc_cpu::check_spcflags()
|
||||
return true;
|
||||
}
|
||||
|
||||
void powerpc_cpu::execute(uint32 entry, bool enable_cache)
|
||||
|
||||
void powerpc_cpu::execute(uint32 entry)
|
||||
{
|
||||
pc() = entry;
|
||||
#if PPC_EXECUTE_DUMP_STATE
|
||||
const bool dump_state = true;
|
||||
#endif
|
||||
execute_depth++;
|
||||
#if PPC_ENABLE_JIT
|
||||
if (enable_cache) {
|
||||
if (execute_depth == 1) {
|
||||
for (;;) {
|
||||
block_info *bi = compile_block(pc());
|
||||
|
||||
@ -382,7 +385,7 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
|
||||
|
||||
if (!spcflags().empty()) {
|
||||
if (!check_spcflags())
|
||||
return;
|
||||
goto return_site;
|
||||
|
||||
// Force redecoding if cache was invalidated
|
||||
if (spcflags().test(SPCFLAG_JIT_EXEC_RETURN)) {
|
||||
@ -395,11 +398,11 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
goto return_site;
|
||||
}
|
||||
#endif
|
||||
#if PPC_DECODE_CACHE
|
||||
if (enable_cache) {
|
||||
if (execute_depth == 1) {
|
||||
for (;;) {
|
||||
#if PPC_PROFILE_COMPILE_TIME
|
||||
compile_count++;
|
||||
@ -474,7 +477,7 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
|
||||
|
||||
if (!spcflags().empty()) {
|
||||
if (!check_spcflags())
|
||||
return;
|
||||
goto return_site;
|
||||
|
||||
// Force redecoding if cache was invalidated
|
||||
if (spcflags().test(SPCFLAG_JIT_EXEC_RETURN)) {
|
||||
@ -487,7 +490,7 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
goto return_site;
|
||||
}
|
||||
#endif
|
||||
for (;;) {
|
||||
@ -508,8 +511,10 @@ void powerpc_cpu::execute(uint32 entry, bool enable_cache)
|
||||
dump_registers();
|
||||
#endif
|
||||
if (!spcflags().empty() && !check_spcflags())
|
||||
return;
|
||||
goto return_site;
|
||||
}
|
||||
return_site:
|
||||
--execute_depth;
|
||||
}
|
||||
|
||||
void powerpc_cpu::execute()
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <vector>
|
||||
|
||||
class powerpc_cpu
|
||||
#ifndef PPC_NO_BASIC_CPU_BASE
|
||||
#ifndef SHEEPSHAVER
|
||||
: public basic_cpu
|
||||
#endif
|
||||
{
|
||||
@ -200,10 +200,13 @@ private:
|
||||
// Check special CPU flags
|
||||
bool check_spcflags();
|
||||
|
||||
// Current execute() nested level
|
||||
int execute_depth;
|
||||
|
||||
public:
|
||||
|
||||
// Initialization & finalization
|
||||
#ifdef PPC_NO_BASIC_CPU_BASE
|
||||
#ifdef SHEEPSHAVER
|
||||
powerpc_cpu()
|
||||
#if PPC_ENABLE_JIT
|
||||
: codegen(this)
|
||||
@ -238,7 +241,7 @@ public:
|
||||
void fake_dump_registers(uint32);
|
||||
|
||||
// Start emulation loop
|
||||
void execute(uint32 entry, bool enable_cache = true);
|
||||
void execute(uint32 entry);
|
||||
void execute();
|
||||
|
||||
// Interrupts handling
|
||||
@ -311,7 +314,6 @@ private:
|
||||
friend class powerpc_dyngen;
|
||||
powerpc_dyngen codegen;
|
||||
block_info *compile_block(uint32 entry);
|
||||
powerpc_dyngen *codegen_ptr() { return &codegen; }
|
||||
#endif
|
||||
|
||||
// Semantic action templates
|
||||
|
@ -73,8 +73,8 @@ public:
|
||||
friend class powerpc_dyngen_helper;
|
||||
|
||||
// Default constructor
|
||||
powerpc_dyngen(dyngen_cpu_base cpu)
|
||||
: basic_dyngen(cpu)
|
||||
powerpc_dyngen(dyngen_cpu_base cpu, int cache_size = -1)
|
||||
: basic_dyngen(cpu, cache_size)
|
||||
{ }
|
||||
|
||||
// Load/store registers
|
||||
|
Loading…
Reference in New Issue
Block a user