mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-20 15:29:48 +00:00
Statically allocate the translation cache on PowerPC. This makes it possible
to generate direct bl instructions for function invokation.
This commit is contained in:
parent
e30001bc00
commit
36ce9c07e6
@ -606,6 +606,34 @@ if [[ "x$EMULATED_PPC" = "xyes" ]]; then
|
|||||||
fi
|
fi
|
||||||
CPUSRCS="$CPUSRCS ../kpx_cpu/sheepshaver_glue.cpp"
|
CPUSRCS="$CPUSRCS ../kpx_cpu/sheepshaver_glue.cpp"
|
||||||
fi
|
fi
|
||||||
|
if [[ "x$ac_cv_use_dyngen" = "xyes" ]]; then
|
||||||
|
AC_CACHE_CHECK([whether static data regions are executable],
|
||||||
|
ac_cv_have_static_data_exec, [
|
||||||
|
AC_TRY_RUN([int main(void) {
|
||||||
|
#if defined(__powerpc__)
|
||||||
|
static unsigned int p[8] = {0x4e800020,};
|
||||||
|
asm volatile("dcbst 0,%0" : : "r" (p) : "memory");
|
||||||
|
asm volatile("sync" : : : "memory");
|
||||||
|
asm volatile("icbi 0,%0" : : "r" (p) : "memory");
|
||||||
|
asm volatile("sync" : : : "memory");
|
||||||
|
asm volatile("isync" : : : "memory");
|
||||||
|
((void (*)(void))p)();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
#if defined(__i386__)
|
||||||
|
static unsigned char p[] = {0xc3};
|
||||||
|
((void (*)(void))p)();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}], ac_cv_have_static_data_exec=yes, ac_cv_have_static_data_exec=no,
|
||||||
|
dnl When cross-compiling, do not assume anything.
|
||||||
|
ac_cv_have_static_data_exec=no
|
||||||
|
)
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
AC_TRANSLATE_DEFINE(HAVE_STATIC_DATA_EXEC, "$ac_cv_have_static_data_exec",
|
||||||
|
[Define if your system marks static data pages as executable.])
|
||||||
|
|
||||||
dnl Generate Makefile.
|
dnl Generate Makefile.
|
||||||
AC_SUBST(DYNGENSRCS)
|
AC_SUBST(DYNGENSRCS)
|
||||||
|
@ -25,6 +25,16 @@
|
|||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
// FIXME: Define this only for SheepShaver. Kheperix will need
|
||||||
|
// something like KPX_MAX_CPUS == 1.
|
||||||
|
#ifndef SHEEPSHAVER
|
||||||
|
#undef HAVE_STATIC_DATA_EXEC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_STATIC_DATA_EXEC
|
||||||
|
static uint8 g_translation_cache[basic_jit_cache::JIT_CACHE_SIZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
basic_jit_cache::basic_jit_cache(uint32 init_cache_size)
|
basic_jit_cache::basic_jit_cache(uint32 init_cache_size)
|
||||||
: tcode_start(NULL), code_start(NULL), code_p(NULL), code_end(NULL)
|
: tcode_start(NULL), code_start(NULL), code_p(NULL), code_end(NULL)
|
||||||
{
|
{
|
||||||
@ -41,8 +51,15 @@ basic_jit_cache::init_translation_cache(uint32 size)
|
|||||||
{
|
{
|
||||||
// Round up translation cache size to next 16 KB boundaries
|
// Round up translation cache size to next 16 KB boundaries
|
||||||
const uint32 roundup = 16 * 1024;
|
const uint32 roundup = 16 * 1024;
|
||||||
cache_size = (size + JIT_CACHE_SIZE_GUARD + roundup - 1) & -roundup;
|
uint32 effective_cache_size = (size - JIT_CACHE_SIZE_GUARD) & -roundup;
|
||||||
|
cache_size = size & -roundup;
|
||||||
|
|
||||||
|
#if HAVE_STATIC_DATA_EXEC
|
||||||
|
if (cache_size <= JIT_CACHE_SIZE) {
|
||||||
|
tcode_start = g_translation_cache;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
tcode_start = (uint8 *)vm_acquire(cache_size, VM_MAP_PRIVATE | VM_MAP_32BIT);
|
tcode_start = (uint8 *)vm_acquire(cache_size, VM_MAP_PRIVATE | VM_MAP_32BIT);
|
||||||
if (tcode_start == VM_MAP_FAILED) {
|
if (tcode_start == VM_MAP_FAILED) {
|
||||||
tcode_start = NULL;
|
tcode_start = NULL;
|
||||||
@ -56,16 +73,21 @@ basic_jit_cache::init_translation_cache(uint32 size)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
D(bug("basic_jit_cache: Translation cache: %d KB at %p\n", cache_size / 1024, tcode_start));
|
D(bug("basic_jit_cache: Translation cache: %d KB at %p\n", cache_size / 1024, tcode_start));
|
||||||
code_start = tcode_start;
|
code_start = tcode_start;
|
||||||
code_p = code_start;
|
code_p = code_start;
|
||||||
code_end = code_p + cache_size;
|
code_end = code_p + effective_cache_size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
basic_jit_cache::kill_translation_cache()
|
basic_jit_cache::kill_translation_cache()
|
||||||
{
|
{
|
||||||
if (tcode_start)
|
if (tcode_start) {
|
||||||
|
#if HAVE_STATIC_DATA_EXEC
|
||||||
|
if (cache_size > JIT_CACHE_SIZE)
|
||||||
|
#endif
|
||||||
vm_release(tcode_start, cache_size);
|
vm_release(tcode_start, cache_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,10 @@
|
|||||||
class basic_jit_cache
|
class basic_jit_cache
|
||||||
{
|
{
|
||||||
// Default cache size (2 MB)
|
// Default cache size (2 MB)
|
||||||
|
public:
|
||||||
static const uint32 JIT_CACHE_SIZE = 2 * 1024 * 1024;
|
static const uint32 JIT_CACHE_SIZE = 2 * 1024 * 1024;
|
||||||
static const uint32 JIT_CACHE_SIZE_GUARD = 4096;
|
static const uint32 JIT_CACHE_SIZE_GUARD = 4096;
|
||||||
|
private:
|
||||||
uint32 cache_size;
|
uint32 cache_size;
|
||||||
|
|
||||||
// Translation cache (allocated base, current pointer, end pointer)
|
// Translation cache (allocated base, current pointer, end pointer)
|
||||||
|
Loading…
Reference in New Issue
Block a user