extern uint16_t gen_opc_buf[OPC_BUF_SIZE];
extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
-extern uint32_t gen_opc_pc[OPC_BUF_SIZE];
+extern long gen_labels[OPC_BUF_SIZE];
+extern int nb_gen_labels;
+extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
+extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
struct TranslationBlock *jmp_first;
} TranslationBlock;
-static inline unsigned int tb_hash_func(unsigned long pc)
+static inline unsigned int tb_hash_func(target_ulong pc)
{
return pc & (CODE_GEN_HASH_SIZE - 1);
}
return pc & (CODE_GEN_PHYS_HASH_SIZE - 1);
}
-TranslationBlock *tb_alloc(unsigned long pc);
+TranslationBlock *tb_alloc(target_ulong pc);
void tb_flush(CPUState *env);
void tb_link(TranslationBlock *tb);
void tb_link_phys(TranslationBlock *tb,
#elif defined(__APPLE__)
#define ASM_DATA_SECTION ".data\n"
#define ASM_PREVIOUS_SECTION ".text\n"
-#define ASM_NAME(x) "_" #x
#else
#define ASM_DATA_SECTION ".section \".data\"\n"
#define ASM_PREVIOUS_SECTION ".previous\n"
-#define ASM_NAME(x) stringify(x)
#endif
#if defined(__powerpc__)
/* we patch the jump instruction directly */
-#define JUMP_TB(opname, tbparam, n, eip)\
+#define GOTO_TB(opname, tbparam, n)\
do {\
asm volatile (ASM_DATA_SECTION\
ASM_NAME(__op_label) #n "." ASM_NAME(opname) ":\n"\
ASM_PREVIOUS_SECTION \
"b " ASM_NAME(__op_jmp) #n "\n"\
"1:\n");\
- T0 = (long)(tbparam) + (n);\
- EIP = eip;\
- EXIT_TB();\
-} while (0)
-
-#define JUMP_TB2(opname, tbparam, n)\
-do {\
- asm volatile ("b " ASM_NAME(__op_jmp) #n "\n");\
} while (0)
#elif defined(__i386__) && defined(USE_DIRECT_JUMP)
/* we patch the jump instruction directly */
-#define JUMP_TB(opname, tbparam, n, eip)\
+#define GOTO_TB(opname, tbparam, n)\
do {\
asm volatile (".section .data\n"\
ASM_NAME(__op_label) #n "." ASM_NAME(opname) ":\n"\
ASM_PREVIOUS_SECTION \
"jmp " ASM_NAME(__op_jmp) #n "\n"\
"1:\n");\
- T0 = (long)(tbparam) + (n);\
- EIP = eip;\
- EXIT_TB();\
-} while (0)
-
-#define JUMP_TB2(opname, tbparam, n)\
-do {\
- asm volatile ("jmp " ASM_NAME(__op_jmp) #n "\n");\
} while (0)
#else
/* jump to next block operations (more portable code, does not need
cache flushing, but slower because of indirect jump) */
-#define JUMP_TB(opname, tbparam, n, eip)\
+#define GOTO_TB(opname, tbparam, n)\
do {\
- static void __attribute__((unused)) *__op_label ## n = &&label ## n;\
static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\
+ static void __attribute__((unused)) *__op_label ## n = &&label ## n;\
goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
-label ## n:\
- T0 = (long)(tbparam) + (n);\
- EIP = eip;\
-dummy_label ## n:\
- EXIT_TB();\
+label ## n: ;\
+dummy_label ## n: ;\
} while (0)
-/* second jump to same destination 'n' */
-#define JUMP_TB2(opname, tbparam, n)\
+#endif
+
+/* XXX: will be suppressed */
+#define JUMP_TB(opname, tbparam, n, eip)\
do {\
- goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n - 2]);\
+ GOTO_TB(opname, tbparam, n);\
+ T0 = (long)(tbparam) + (n);\
+ EIP = (int32_t)eip;\
+ EXIT_TB();\
} while (0)
-#endif
-
extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
#ifdef __i386__
static inline int testandset (int *p)
{
- char ret;
- long int readval;
+ long int readval = 0;
- __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
- : "=q" (ret), "=m" (*p), "=a" (readval)
- : "r" (1), "m" (*p), "a" (0)
- : "memory");
- return ret;
+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
+ : "+m" (*p), "+a" (readval)
+ : "r" (1)
+ : "cc");
+ return readval;
}
#endif
#ifdef __x86_64__
static inline int testandset (int *p)
{
- char ret;
- int readval;
+ long int readval = 0;
- __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
- : "=q" (ret), "=m" (*p), "=a" (readval)
- : "r" (1), "m" (*p), "a" (0)
- : "memory");
- return ret;
+ __asm__ __volatile__ ("lock; cmpxchgl %2, %0"
+ : "+m" (*p), "+a" (readval)
+ : "r" (1)
+ : "cc");
+ return readval;
}
#endif
: "=r" (ret)
: "m" (p)
: "cc","memory");
- return ret == 0;
+ return ret;
}
#endif
extern int tb_invalidated_flag;
-#if (defined(TARGET_I386) || defined(TARGET_PPC)) && \
- !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
-void tlb_fill(unsigned long addr, int is_write, int is_user,
+void tlb_fill(target_ulong addr, int is_write, int is_user,
void *retaddr);
#define ACCESS_TYPE 3
#define DATA_SIZE 4
#include "softmmu_header.h"
+#define DATA_SIZE 8
+#include "softmmu_header.h"
+
#undef ACCESS_TYPE
#undef MEMSUFFIX
#undef env
/* XXX: i386 target specific */
static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
{
- int is_user, index;
+ int is_user, index, pd;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
#if defined(TARGET_I386)
is_user = ((env->hflags & HF_CPL_MASK) == 3);
#elif defined (TARGET_PPC)
is_user = msr_pr;
+#elif defined (TARGET_SPARC)
+ is_user = (env->psrs == 0);
#else
#error "Unimplemented !"
#endif
if (__builtin_expect(env->tlb_read[is_user][index].address !=
(addr & TARGET_PAGE_MASK), 0)) {
-#if defined (TARGET_PPC)
- env->access_type = ACCESS_CODE;
- ldub_code((void *)addr);
- env->access_type = ACCESS_INT;
-#else
- ldub_code((void *)addr);
-#endif
+ ldub_code(addr);
+ }
+ pd = env->tlb_read[is_user][index].address & ~TARGET_PAGE_MASK;
+ if (pd > IO_MEM_ROM) {
+ cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr);
}
return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base;
}
#endif
+
+
+#ifdef USE_KQEMU
+extern int kqemu_fd;
+extern int kqemu_flushed;
+
+int kqemu_init(CPUState *env);
+int kqemu_cpu_exec(CPUState *env);
+void kqemu_flush_page(CPUState *env, target_ulong addr);
+void kqemu_flush(CPUState *env, int global);
+
+static inline int kqemu_is_ok(CPUState *env)
+{
+ return(env->kqemu_enabled &&
+ (env->hflags & HF_CPL_MASK) == 3 &&
+ (env->eflags & IOPL_MASK) != IOPL_MASK &&
+ (env->cr[0] & CR0_PE_MASK) &&
+ (env->eflags & IF_MASK) &&
+ !(env->eflags & VM_MASK));
+}
+
+#endif