Commit 7cb69cae2053e0fbba5b9ac50bd31bd1a4f8f8cb
1 parent
b03cce8e
initial global prologue/epilogue implementation
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4407 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
31 additions
and
78 deletions
cpu-exec.c
| @@ -18,8 +18,10 @@ | @@ -18,8 +18,10 @@ | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 19 | */ | 19 | */ |
| 20 | #include "config.h" | 20 | #include "config.h" |
| 21 | +#define CPU_NO_GLOBAL_REGS | ||
| 21 | #include "exec.h" | 22 | #include "exec.h" |
| 22 | #include "disas.h" | 23 | #include "disas.h" |
| 24 | +#include "tcg.h" | ||
| 23 | 25 | ||
| 24 | #if !defined(CONFIG_SOFTMMU) | 26 | #if !defined(CONFIG_SOFTMMU) |
| 25 | #undef EAX | 27 | #undef EAX |
| @@ -292,7 +294,6 @@ int cpu_exec(CPUState *env1) | @@ -292,7 +294,6 @@ int cpu_exec(CPUState *env1) | ||
| 292 | #endif | 294 | #endif |
| 293 | #endif | 295 | #endif |
| 294 | int ret, interrupt_request; | 296 | int ret, interrupt_request; |
| 295 | - unsigned long (*gen_func)(void); | ||
| 296 | TranslationBlock *tb; | 297 | TranslationBlock *tb; |
| 297 | uint8_t *tc_ptr; | 298 | uint8_t *tc_ptr; |
| 298 | 299 | ||
| @@ -652,67 +653,7 @@ int cpu_exec(CPUState *env1) | @@ -652,67 +653,7 @@ int cpu_exec(CPUState *env1) | ||
| 652 | tc_ptr = tb->tc_ptr; | 653 | tc_ptr = tb->tc_ptr; |
| 653 | env->current_tb = tb; | 654 | env->current_tb = tb; |
| 654 | /* execute the generated code */ | 655 | /* execute the generated code */ |
| 655 | - gen_func = (void *)tc_ptr; | ||
| 656 | -#if defined(__sparc__) | ||
| 657 | - __asm__ __volatile__("call %0\n\t" | ||
| 658 | - "mov %%o7,%%i0" | ||
| 659 | - : /* no outputs */ | ||
| 660 | - : "r" (gen_func) | ||
| 661 | - : "i0", "i1", "i2", "i3", "i4", "i5", | ||
| 662 | - "o0", "o1", "o2", "o3", "o4", "o5", | ||
| 663 | - "l0", "l1", "l2", "l3", "l4", "l5", | ||
| 664 | - "l6", "l7"); | ||
| 665 | -#elif defined(__hppa__) | ||
| 666 | - asm volatile ("ble 0(%%sr4,%1)\n" | ||
| 667 | - "copy %%r31,%%r18\n" | ||
| 668 | - "copy %%r28,%0\n" | ||
| 669 | - : "=r" (next_tb) | ||
| 670 | - : "r" (gen_func) | ||
| 671 | - : "r1", "r2", "r3", "r4", "r5", "r6", "r7", | ||
| 672 | - "r8", "r9", "r10", "r11", "r12", "r13", | ||
| 673 | - "r18", "r19", "r20", "r21", "r22", "r23", | ||
| 674 | - "r24", "r25", "r26", "r27", "r28", "r29", | ||
| 675 | - "r30", "r31"); | ||
| 676 | -#elif defined(__arm__) | ||
| 677 | - asm volatile ("mov pc, %0\n\t" | ||
| 678 | - ".global exec_loop\n\t" | ||
| 679 | - "exec_loop:\n\t" | ||
| 680 | - : /* no outputs */ | ||
| 681 | - : "r" (gen_func) | ||
| 682 | - : "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14"); | ||
| 683 | -#elif defined(__ia64) | ||
| 684 | - struct fptr { | ||
| 685 | - void *ip; | ||
| 686 | - void *gp; | ||
| 687 | - } fp; | ||
| 688 | - | ||
| 689 | - fp.ip = tc_ptr; | ||
| 690 | - fp.gp = code_gen_buffer + 2 * (1 << 20); | ||
| 691 | - (*(void (*)(void)) &fp)(); | ||
| 692 | -#elif defined(__i386) | ||
| 693 | - asm volatile ("sub $12, %%esp\n\t" | ||
| 694 | - "push %%ebp\n\t" | ||
| 695 | - "call *%1\n\t" | ||
| 696 | - "pop %%ebp\n\t" | ||
| 697 | - "add $12, %%esp\n\t" | ||
| 698 | - : "=a" (next_tb) | ||
| 699 | - : "a" (gen_func) | ||
| 700 | - : "ebx", "ecx", "edx", "esi", "edi", "cc", | ||
| 701 | - "memory"); | ||
| 702 | -#elif defined(__x86_64__) | ||
| 703 | - asm volatile ("sub $8, %%rsp\n\t" | ||
| 704 | - "push %%rbp\n\t" | ||
| 705 | - "call *%1\n\t" | ||
| 706 | - "pop %%rbp\n\t" | ||
| 707 | - "add $8, %%rsp\n\t" | ||
| 708 | - : "=a" (next_tb) | ||
| 709 | - : "a" (gen_func) | ||
| 710 | - : "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", | ||
| 711 | - "r10", "r11", "r12", "r13", "r14", "r15", "cc", | ||
| 712 | - "memory"); | ||
| 713 | -#else | ||
| 714 | - next_tb = gen_func(); | ||
| 715 | -#endif | 656 | + next_tb = tcg_qemu_tb_exec(tc_ptr); |
| 716 | env->current_tb = NULL; | 657 | env->current_tb = NULL; |
| 717 | /* reset soft MMU for next block (it can currently | 658 | /* reset soft MMU for next block (it can currently |
| 718 | only be set by a memory fault) */ | 659 | only be set by a memory fault) */ |
exec.c
| @@ -89,6 +89,7 @@ int nb_tbs; | @@ -89,6 +89,7 @@ int nb_tbs; | ||
| 89 | /* any access to the tbs or the page table must use this lock */ | 89 | /* any access to the tbs or the page table must use this lock */ |
| 90 | spinlock_t tb_lock = SPIN_LOCK_UNLOCKED; | 90 | spinlock_t tb_lock = SPIN_LOCK_UNLOCKED; |
| 91 | 91 | ||
| 92 | +uint8_t code_gen_prologue[1024] __attribute__((aligned (32))); | ||
| 92 | uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32))); | 93 | uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32))); |
| 93 | uint8_t *code_gen_ptr; | 94 | uint8_t *code_gen_ptr; |
| 94 | 95 | ||
| @@ -173,6 +174,31 @@ typedef struct subpage_t { | @@ -173,6 +174,31 @@ typedef struct subpage_t { | ||
| 173 | void *opaque[TARGET_PAGE_SIZE][2][4]; | 174 | void *opaque[TARGET_PAGE_SIZE][2][4]; |
| 174 | } subpage_t; | 175 | } subpage_t; |
| 175 | 176 | ||
| 177 | +#ifdef _WIN32 | ||
| 178 | +static void map_exec(void *addr, long size) | ||
| 179 | +{ | ||
| 180 | + DWORD old_protect; | ||
| 181 | + VirtualProtect(addr, size, | ||
| 182 | + PAGE_EXECUTE_READWRITE, &old_protect); | ||
| 183 | + | ||
| 184 | +} | ||
| 185 | +#else | ||
| 186 | +static void map_exec(void *addr, long size) | ||
| 187 | +{ | ||
| 188 | + unsigned long start, end; | ||
| 189 | + | ||
| 190 | + start = (unsigned long)addr; | ||
| 191 | + start &= ~(qemu_real_host_page_size - 1); | ||
| 192 | + | ||
| 193 | + end = (unsigned long)addr + size; | ||
| 194 | + end += qemu_real_host_page_size - 1; | ||
| 195 | + end &= ~(qemu_real_host_page_size - 1); | ||
| 196 | + | ||
| 197 | + mprotect((void *)start, end - start, | ||
| 198 | + PROT_READ | PROT_WRITE | PROT_EXEC); | ||
| 199 | +} | ||
| 200 | +#endif | ||
| 201 | + | ||
| 176 | static void page_init(void) | 202 | static void page_init(void) |
| 177 | { | 203 | { |
| 178 | /* NOTE: we can always suppose that qemu_host_page_size >= | 204 | /* NOTE: we can always suppose that qemu_host_page_size >= |
| @@ -184,26 +210,12 @@ static void page_init(void) | @@ -184,26 +210,12 @@ static void page_init(void) | ||
| 184 | 210 | ||
| 185 | GetSystemInfo(&system_info); | 211 | GetSystemInfo(&system_info); |
| 186 | qemu_real_host_page_size = system_info.dwPageSize; | 212 | qemu_real_host_page_size = system_info.dwPageSize; |
| 187 | - | ||
| 188 | - VirtualProtect(code_gen_buffer, sizeof(code_gen_buffer), | ||
| 189 | - PAGE_EXECUTE_READWRITE, &old_protect); | ||
| 190 | } | 213 | } |
| 191 | #else | 214 | #else |
| 192 | qemu_real_host_page_size = getpagesize(); | 215 | qemu_real_host_page_size = getpagesize(); |
| 193 | - { | ||
| 194 | - unsigned long start, end; | ||
| 195 | - | ||
| 196 | - start = (unsigned long)code_gen_buffer; | ||
| 197 | - start &= ~(qemu_real_host_page_size - 1); | ||
| 198 | - | ||
| 199 | - end = (unsigned long)code_gen_buffer + sizeof(code_gen_buffer); | ||
| 200 | - end += qemu_real_host_page_size - 1; | ||
| 201 | - end &= ~(qemu_real_host_page_size - 1); | ||
| 202 | - | ||
| 203 | - mprotect((void *)start, end - start, | ||
| 204 | - PROT_READ | PROT_WRITE | PROT_EXEC); | ||
| 205 | - } | ||
| 206 | #endif | 216 | #endif |
| 217 | + map_exec(code_gen_buffer, sizeof(code_gen_buffer)); | ||
| 218 | + map_exec(code_gen_prologue, sizeof(code_gen_prologue)); | ||
| 207 | 219 | ||
| 208 | if (qemu_host_page_size == 0) | 220 | if (qemu_host_page_size == 0) |
| 209 | qemu_host_page_size = qemu_real_host_page_size; | 221 | qemu_host_page_size = qemu_real_host_page_size; |