mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-08 08:51:03 +00:00
initial global prologue/epilogue implementation
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4407 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
b03cce8e08
commit
7cb69cae20
65
cpu-exec.c
65
cpu-exec.c
@ -18,8 +18,10 @@
|
|||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#define CPU_NO_GLOBAL_REGS
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
#include "disas.h"
|
#include "disas.h"
|
||||||
|
#include "tcg.h"
|
||||||
|
|
||||||
#if !defined(CONFIG_SOFTMMU)
|
#if !defined(CONFIG_SOFTMMU)
|
||||||
#undef EAX
|
#undef EAX
|
||||||
@ -292,7 +294,6 @@ int cpu_exec(CPUState *env1)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
int ret, interrupt_request;
|
int ret, interrupt_request;
|
||||||
unsigned long (*gen_func)(void);
|
|
||||||
TranslationBlock *tb;
|
TranslationBlock *tb;
|
||||||
uint8_t *tc_ptr;
|
uint8_t *tc_ptr;
|
||||||
|
|
||||||
@ -652,67 +653,7 @@ int cpu_exec(CPUState *env1)
|
|||||||
tc_ptr = tb->tc_ptr;
|
tc_ptr = tb->tc_ptr;
|
||||||
env->current_tb = tb;
|
env->current_tb = tb;
|
||||||
/* execute the generated code */
|
/* execute the generated code */
|
||||||
gen_func = (void *)tc_ptr;
|
next_tb = tcg_qemu_tb_exec(tc_ptr);
|
||||||
#if defined(__sparc__)
|
|
||||||
__asm__ __volatile__("call %0\n\t"
|
|
||||||
"mov %%o7,%%i0"
|
|
||||||
: /* no outputs */
|
|
||||||
: "r" (gen_func)
|
|
||||||
: "i0", "i1", "i2", "i3", "i4", "i5",
|
|
||||||
"o0", "o1", "o2", "o3", "o4", "o5",
|
|
||||||
"l0", "l1", "l2", "l3", "l4", "l5",
|
|
||||||
"l6", "l7");
|
|
||||||
#elif defined(__hppa__)
|
|
||||||
asm volatile ("ble 0(%%sr4,%1)\n"
|
|
||||||
"copy %%r31,%%r18\n"
|
|
||||||
"copy %%r28,%0\n"
|
|
||||||
: "=r" (next_tb)
|
|
||||||
: "r" (gen_func)
|
|
||||||
: "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
||||||
"r8", "r9", "r10", "r11", "r12", "r13",
|
|
||||||
"r18", "r19", "r20", "r21", "r22", "r23",
|
|
||||||
"r24", "r25", "r26", "r27", "r28", "r29",
|
|
||||||
"r30", "r31");
|
|
||||||
#elif defined(__arm__)
|
|
||||||
asm volatile ("mov pc, %0\n\t"
|
|
||||||
".global exec_loop\n\t"
|
|
||||||
"exec_loop:\n\t"
|
|
||||||
: /* no outputs */
|
|
||||||
: "r" (gen_func)
|
|
||||||
: "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14");
|
|
||||||
#elif defined(__ia64)
|
|
||||||
struct fptr {
|
|
||||||
void *ip;
|
|
||||||
void *gp;
|
|
||||||
} fp;
|
|
||||||
|
|
||||||
fp.ip = tc_ptr;
|
|
||||||
fp.gp = code_gen_buffer + 2 * (1 << 20);
|
|
||||||
(*(void (*)(void)) &fp)();
|
|
||||||
#elif defined(__i386)
|
|
||||||
asm volatile ("sub $12, %%esp\n\t"
|
|
||||||
"push %%ebp\n\t"
|
|
||||||
"call *%1\n\t"
|
|
||||||
"pop %%ebp\n\t"
|
|
||||||
"add $12, %%esp\n\t"
|
|
||||||
: "=a" (next_tb)
|
|
||||||
: "a" (gen_func)
|
|
||||||
: "ebx", "ecx", "edx", "esi", "edi", "cc",
|
|
||||||
"memory");
|
|
||||||
#elif defined(__x86_64__)
|
|
||||||
asm volatile ("sub $8, %%rsp\n\t"
|
|
||||||
"push %%rbp\n\t"
|
|
||||||
"call *%1\n\t"
|
|
||||||
"pop %%rbp\n\t"
|
|
||||||
"add $8, %%rsp\n\t"
|
|
||||||
: "=a" (next_tb)
|
|
||||||
: "a" (gen_func)
|
|
||||||
: "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9",
|
|
||||||
"r10", "r11", "r12", "r13", "r14", "r15", "cc",
|
|
||||||
"memory");
|
|
||||||
#else
|
|
||||||
next_tb = gen_func();
|
|
||||||
#endif
|
|
||||||
env->current_tb = NULL;
|
env->current_tb = NULL;
|
||||||
/* reset soft MMU for next block (it can currently
|
/* reset soft MMU for next block (it can currently
|
||||||
only be set by a memory fault) */
|
only be set by a memory fault) */
|
||||||
|
44
exec.c
44
exec.c
@ -89,6 +89,7 @@ int nb_tbs;
|
|||||||
/* any access to the tbs or the page table must use this lock */
|
/* any access to the tbs or the page table must use this lock */
|
||||||
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
|
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
|
||||||
|
|
||||||
|
uint8_t code_gen_prologue[1024] __attribute__((aligned (32)));
|
||||||
uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32)));
|
uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32)));
|
||||||
uint8_t *code_gen_ptr;
|
uint8_t *code_gen_ptr;
|
||||||
|
|
||||||
@ -173,6 +174,31 @@ typedef struct subpage_t {
|
|||||||
void *opaque[TARGET_PAGE_SIZE][2][4];
|
void *opaque[TARGET_PAGE_SIZE][2][4];
|
||||||
} subpage_t;
|
} subpage_t;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
static void map_exec(void *addr, long size)
|
||||||
|
{
|
||||||
|
DWORD old_protect;
|
||||||
|
VirtualProtect(addr, size,
|
||||||
|
PAGE_EXECUTE_READWRITE, &old_protect);
|
||||||
|
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void map_exec(void *addr, long size)
|
||||||
|
{
|
||||||
|
unsigned long start, end;
|
||||||
|
|
||||||
|
start = (unsigned long)addr;
|
||||||
|
start &= ~(qemu_real_host_page_size - 1);
|
||||||
|
|
||||||
|
end = (unsigned long)addr + size;
|
||||||
|
end += qemu_real_host_page_size - 1;
|
||||||
|
end &= ~(qemu_real_host_page_size - 1);
|
||||||
|
|
||||||
|
mprotect((void *)start, end - start,
|
||||||
|
PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void page_init(void)
|
static void page_init(void)
|
||||||
{
|
{
|
||||||
/* NOTE: we can always suppose that qemu_host_page_size >=
|
/* NOTE: we can always suppose that qemu_host_page_size >=
|
||||||
@ -184,26 +210,12 @@ static void page_init(void)
|
|||||||
|
|
||||||
GetSystemInfo(&system_info);
|
GetSystemInfo(&system_info);
|
||||||
qemu_real_host_page_size = system_info.dwPageSize;
|
qemu_real_host_page_size = system_info.dwPageSize;
|
||||||
|
|
||||||
VirtualProtect(code_gen_buffer, sizeof(code_gen_buffer),
|
|
||||||
PAGE_EXECUTE_READWRITE, &old_protect);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
qemu_real_host_page_size = getpagesize();
|
qemu_real_host_page_size = getpagesize();
|
||||||
{
|
|
||||||
unsigned long start, end;
|
|
||||||
|
|
||||||
start = (unsigned long)code_gen_buffer;
|
|
||||||
start &= ~(qemu_real_host_page_size - 1);
|
|
||||||
|
|
||||||
end = (unsigned long)code_gen_buffer + sizeof(code_gen_buffer);
|
|
||||||
end += qemu_real_host_page_size - 1;
|
|
||||||
end &= ~(qemu_real_host_page_size - 1);
|
|
||||||
|
|
||||||
mprotect((void *)start, end - start,
|
|
||||||
PROT_READ | PROT_WRITE | PROT_EXEC);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
map_exec(code_gen_buffer, sizeof(code_gen_buffer));
|
||||||
|
map_exec(code_gen_prologue, sizeof(code_gen_prologue));
|
||||||
|
|
||||||
if (qemu_host_page_size == 0)
|
if (qemu_host_page_size == 0)
|
||||||
qemu_host_page_size = qemu_real_host_page_size;
|
qemu_host_page_size = qemu_real_host_page_size;
|
||||||
|
Loading…
Reference in New Issue
Block a user