Revision 7cb69cae
b/cpu-exec.c | ||
---|---|---|
18 | 18 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | 19 |
*/ |
20 | 20 |
#include "config.h" |
21 |
#define CPU_NO_GLOBAL_REGS |
|
21 | 22 |
#include "exec.h" |
22 | 23 |
#include "disas.h" |
24 |
#include "tcg.h" |
|
23 | 25 |
|
24 | 26 |
#if !defined(CONFIG_SOFTMMU) |
25 | 27 |
#undef EAX |
... | ... | |
292 | 294 |
#endif |
293 | 295 |
#endif |
294 | 296 |
int ret, interrupt_request; |
295 |
unsigned long (*gen_func)(void); |
|
296 | 297 |
TranslationBlock *tb; |
297 | 298 |
uint8_t *tc_ptr; |
298 | 299 |
|
... | ... | |
652 | 653 |
tc_ptr = tb->tc_ptr; |
653 | 654 |
env->current_tb = tb; |
654 | 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 | 657 |
env->current_tb = NULL; |
717 | 658 |
/* reset soft MMU for next block (it can currently |
718 | 659 |
only be set by a memory fault) */ |
b/exec.c | ||
---|---|---|
89 | 89 |
/* any access to the tbs or the page table must use this lock */ |
90 | 90 |
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED; |
91 | 91 |
|
92 |
uint8_t code_gen_prologue[1024] __attribute__((aligned (32))); |
|
92 | 93 |
uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32))); |
93 | 94 |
uint8_t *code_gen_ptr; |
94 | 95 |
|
... | ... | |
173 | 174 |
void *opaque[TARGET_PAGE_SIZE][2][4]; |
174 | 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 | 202 |
static void page_init(void) |
177 | 203 |
{ |
178 | 204 |
/* NOTE: we can always suppose that qemu_host_page_size >= |
... | ... | |
184 | 210 |
|
185 | 211 |
GetSystemInfo(&system_info); |
186 | 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 | 214 |
#else |
192 | 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 | 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 | 220 |
if (qemu_host_page_size == 0) |
209 | 221 |
qemu_host_page_size = qemu_real_host_page_size; |
Also available in: Unified diff