Enable JIT in non-constructor so that a user-defined value can be set later

This commit is contained in:
gbeauche 2007-01-21 13:44:27 +00:00
parent 3b6a579f33
commit 9999881c78
15 changed files with 103 additions and 58 deletions

View File

@ -118,12 +118,6 @@ static uint8 *emul_op_trampoline;
static uint8 *native_op_trampoline;
#endif
// JIT Compiler enabled?
static inline bool enable_jit_p()
{
return PrefsFindBool("jit");
}
/**
* PowerPC emulator glue with special 'sheep' opcodes
@ -181,9 +175,13 @@ public:
};
sheepshaver_cpu::sheepshaver_cpu()
: powerpc_cpu(enable_jit_p())
{
init_decoder();
#if PPC_ENABLE_JIT
if (PrefsFindBool("jit"))
enable_jit();
#endif
}
void sheepshaver_cpu::init_decoder()

View File

@ -24,13 +24,9 @@
#define X86_TARGET_64BIT 1
#include "cpu/jit/x86/jit-target-codegen.hpp"
struct amd64_codegen
class amd64_codegen
: public x86_codegen
{
amd64_codegen(int cache_size = -1)
: x86_codegen(cache_size)
{ }
public:
#define DEFINE_OP(NAME, OP) \

View File

@ -28,9 +28,17 @@ int __op_jmp0, __op_jmp1;
#define DEFINE_GEN(NAME,RET,ARGS) RET basic_dyngen::NAME ARGS
#include "basic-dyngen-ops.hpp"
basic_dyngen::basic_dyngen(dyngen_cpu_base cpu, int cache_size)
: parent_cpu(cpu), jit_codegen(cache_size)
basic_dyngen::basic_dyngen(dyngen_cpu_base cpu)
: parent_cpu(cpu)
{
}
bool
basic_dyngen::initialize(void)
{
if (!jit_codegen::initialize())
return false;
execute_func = gen_start();
gen_op_execute();
gen_end();
@ -43,6 +51,8 @@ basic_dyngen::basic_dyngen(dyngen_cpu_base cpu, int cache_size)
set_code_start(code_ptr());
#endif
#endif
return true;
}
void

View File

@ -80,7 +80,10 @@ class basic_dyngen
public:
// Constructor, parent CPU required
basic_dyngen(dyngen_cpu_base cpu, int cache_size = -1);
basic_dyngen(dyngen_cpu_base cpu);
// Initialization
bool initialize(void);
// Return CPU context associated to this code generator
dyngen_cpu_base cpu() const

View File

@ -25,20 +25,19 @@
#define DEBUG 0
#include "debug.h"
// Default cache size
// Default cache size in KB
#if defined(__alpha__)
const int JIT_CACHE_SIZE = 2 * 1024 * 1024;
const int JIT_CACHE_SIZE = 2 * 1024;
#elif defined(__powerpc__) || defined(__ppc__)
const int JIT_CACHE_SIZE = 4 * 1024 * 1024;
const int JIT_CACHE_SIZE = 4 * 1024;
#else
const int JIT_CACHE_SIZE = 8 * 1024 * 1024;
const int JIT_CACHE_SIZE = 8 * 1024;
#endif
const int JIT_CACHE_SIZE_GUARD = 4096;
basic_jit_cache::basic_jit_cache(int init_cache_size)
: tcode_start(NULL), code_start(NULL), code_p(NULL), code_end(NULL), data(NULL)
basic_jit_cache::basic_jit_cache()
: cache_size(0), tcode_start(NULL), code_start(NULL), code_p(NULL), code_end(NULL), data(NULL)
{
init_translation_cache(init_cache_size);
}
basic_jit_cache::~basic_jit_cache()
@ -56,10 +55,9 @@ basic_jit_cache::~basic_jit_cache()
}
bool
basic_jit_cache::init_translation_cache(int size)
basic_jit_cache::init_translation_cache(uint32 size)
{
if (size == -1)
size = JIT_CACHE_SIZE;
size *= 1024;
// Round up translation cache size to 16 KB boundaries
const uint32 roundup = 16 * 1024;
@ -93,9 +91,27 @@ basic_jit_cache::kill_translation_cache()
if (tcode_start) {
D(bug("basic_jit_cache: Release translation cache\n"));
vm_release(tcode_start, cache_size);
cache_size = 0;
tcode_start = NULL;
}
}
bool
basic_jit_cache::initialize(void)
{
if (cache_size == 0)
set_cache_size(JIT_CACHE_SIZE);
return tcode_start && cache_size;
}
void
basic_jit_cache::set_cache_size(uint32 size)
{
kill_translation_cache();
if (size)
init_translation_cache(size);
}
uint8 *
basic_jit_cache::copy_data(const uint8 *block, uint32 size)
{

View File

@ -48,7 +48,7 @@ class basic_jit_cache
protected:
// Initialize translation cache
bool init_translation_cache(int size);
bool init_translation_cache(uint32 size);
void kill_translation_cache();
// Initialize user code start
@ -63,9 +63,12 @@ public:
public:
// Default constructor & destructor (use default JIT_CACHE_SIZE)
basic_jit_cache(int init_cache_size = -1);
basic_jit_cache();
~basic_jit_cache();
bool initialize(void);
void set_cache_size(uint32 size);
// Invalidate translation cache
void invalidate_cache();
bool full_translation_cache() const

View File

@ -33,9 +33,6 @@ typedef amd64_codegen jit_codegen;
struct jit_codegen
: public basic_jit_cache
{
jit_codegen(int cache_size = -1)
: basic_jit_cache(cache_size)
{ }
};
#endif

View File

@ -67,10 +67,6 @@ protected:
public:
x86_codegen(int cache_size = -1)
: basic_jit_cache(cache_size)
{ }
/* XXX this avoids emit_XXX() functions because GCC cannot
optimize out intermediate code_ptr() updates */
#define GEN_CODE(CODE) do { \

View File

@ -302,6 +302,16 @@ void powerpc_cpu::initialize()
#endif
}
#if PPC_ENABLE_JIT
void powerpc_cpu::enable_jit(uint32 cache_size)
{
use_jit = true;
if (cache_size)
codegen.set_cache_size(cache_size);
codegen.initialize();
}
#endif
// Memory allocator returning powerpc_cpu objects aligned on 16-byte boundaries
// FORMAT: [ alignment ] magic identifier, offset to malloc'ed data, powerpc_cpu data
void *powerpc_cpu::operator new(size_t size)
@ -341,20 +351,19 @@ void powerpc_cpu::operator delete(void *p)
}
#ifdef SHEEPSHAVER
powerpc_cpu::powerpc_cpu(bool do_use_jit)
: use_jit(do_use_jit)
powerpc_cpu::powerpc_cpu()
#if PPC_ENABLE_JIT
, codegen(this)
: codegen(this)
#endif
#else
powerpc_cpu::powerpc_cpu(task_struct *parent_task)
: basic_cpu(parent_task), use_jit(true)
: basic_cpu(parent_task)
#if PPC_ENABLE_JIT
, codegen(this)
#endif
#endif
{
#if !PPC_ENABLE_JIT
#if PPC_ENABLE_JIT
use_jit = false;
#endif
++ppc_refcount;

View File

@ -247,15 +247,12 @@ private:
// Current execute() nested level
int execute_depth;
// Do we enable the JIT compiler?
bool use_jit;
public:
// Initialization & finalization
void initialize();
#ifdef SHEEPSHAVER
powerpc_cpu(bool do_use_jit = true);
powerpc_cpu();
#else
powerpc_cpu(task_struct *parent_task);
#endif
@ -332,6 +329,10 @@ protected:
COMPILE_EPILOGUE_OK // generated code, including basic block epilogue
};
virtual int compile1(codegen_context_t & cg_context) { return COMPILE_FAILURE; }
bool use_jit;
public:
void enable_jit(uint32 cache_size = 0);
#endif
private:

View File

@ -31,8 +31,8 @@
#define DEFINE_GEN(NAME,RET,ARGS) RET powerpc_dyngen::NAME ARGS
#include "ppc-dyngen-ops.hpp"
powerpc_dyngen::powerpc_dyngen(dyngen_cpu_base cpu, int cache_size)
: basic_dyngen(cpu, cache_size)
powerpc_dyngen::powerpc_dyngen(dyngen_cpu_base cpu)
: basic_dyngen(cpu)
{
#ifdef SHEEPSHAVER
printf("Detected CPU features:");

View File

@ -55,7 +55,7 @@ public:
typedef nv_mem_fun_t< void, powerpc_dyngen > gen_handler_t;
// Default constructor
powerpc_dyngen(dyngen_cpu_base cpu, int cache_size = -1);
powerpc_dyngen(dyngen_cpu_base cpu);
// Generate prologue
uint8 *gen_start(uint32 pc);

View File

@ -31,9 +31,16 @@
const powerpc_jit::jit_info_t *powerpc_jit::jit_info[PPC_I(MAX)];
// PowerPC JIT initializer
powerpc_jit::powerpc_jit(dyngen_cpu_base cpu, int cache_size)
: powerpc_dyngen(cpu, cache_size)
powerpc_jit::powerpc_jit(dyngen_cpu_base cpu)
: powerpc_dyngen(cpu)
{
}
bool powerpc_jit::initialize(void)
{
if (!powerpc_dyngen::initialize())
return false;
static bool once = true;
if (once) {
@ -208,6 +215,8 @@ powerpc_jit::powerpc_jit(dyngen_cpu_base cpu, int cache_size)
}
#endif
}
return true;
}
// Dispatch mid-level code generators

View File

@ -28,7 +28,10 @@ struct powerpc_jit
: public powerpc_dyngen
{
// Default constructor
powerpc_jit(dyngen_cpu_base cpu, int cache_size = -1);
powerpc_jit(dyngen_cpu_base cpu);
// Initialization
bool initialize(void);
bool gen_vector_1(int mnemo, int vD);
bool gen_vector_2(int mnemo, int vD, int vA, int vB);

View File

@ -35,10 +35,6 @@
#define NATIVE_POWERPC
#endif
#ifndef USE_JIT
#define USE_JIT 0
#endif
#if EMU_KHEPERIX
#include "sysdeps.h"
#include "vm_alloc.h"
@ -217,10 +213,6 @@ void init_emul_op_trampolines(basic_dyngen & dg)
{
}
#endif
#define ENABLE_JIT_P (USE_JIT && 1)
#else
#define ENABLE_JIT_P 0
#endif
struct powerpc_cpu_base
@ -243,7 +235,6 @@ struct powerpc_cpu_base
};
powerpc_cpu_base::powerpc_cpu_base()
: powerpc_cpu(ENABLE_JIT_P)
{
init_decoder();
}
@ -279,6 +270,7 @@ struct powerpc_cpu_base
{
powerpc_cpu_base();
void execute(uintptr);
void enable_jit() { }
void invalidate_cache() { }
void invalidate_cache_range(uint32 *start, uint32 size) { }
@ -329,6 +321,7 @@ struct powerpc_cpu_base
{
powerpc_cpu_base();
void execute(uintptr);
void enable_jit() { }
void invalidate_cache() { }
void invalidate_cache_range(uint32 *start, uint32 size) { }
@ -382,6 +375,7 @@ public:
powerpc_cpu_base();
~powerpc_cpu_base();
void execute(uintptr);
void enable_jit() { }
void invalidate_cache() { tb_flush(); }
void invalidate_cache_range(uint32 *start, uint32 size) { invalidate_cache(); }
@ -2185,6 +2179,16 @@ int main(int argc, char *argv[])
FILE *fp = NULL;
powerpc_test_cpu *ppc = new powerpc_test_cpu;
if (argc > 1) {
const char *arg = argv[1];
if (strcmp(arg, "--jit") == 0) {
--argc;
argv[1] = argv[0];
++argv;
ppc->enable_jit();
}
}
if (argc > 1) {
const char *file = argv[1];
#ifdef NATIVE_POWERPC