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