diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-03-22 15:23:14 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-03-22 15:23:14 +0000 |
commit | dab2ed991a49678fbd4d45ff1b328340a77057df (patch) | |
tree | 0c587c5ef62faa0c3bf9b39a7ce9281c0a63e2b2 /exec-i386.c | |
parent | e591824733ec698d92d1f09c2ffb9b86b799d6da (diff) |
better 16 bit code support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@38 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec-i386.c')
-rw-r--r-- | exec-i386.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/exec-i386.c b/exec-i386.c index 0dbaccc830..e83d220369 100644 --- a/exec-i386.c +++ b/exec-i386.c @@ -38,7 +38,8 @@ #define CODE_GEN_HASH_SIZE (1 << CODE_GEN_HASH_BITS) typedef struct TranslationBlock { - unsigned long pc; /* simulated PC corresponding to this block */ + unsigned long pc; /* simulated PC corresponding to this block (EIP + CS base) */ + unsigned long cs_base; /* CS base for this block */ unsigned int flags; /* flags defining in which context the code was generated */ uint8_t *tc_ptr; /* pointer to the translated code */ struct TranslationBlock *hash_next; /* next matching block */ @@ -140,6 +141,7 @@ static void tb_flush(void) /* find a translation block in the translation cache. If not found, allocate a new one */ static inline TranslationBlock *tb_find_and_alloc(unsigned long pc, + unsigned long cs_base, unsigned int flags) { TranslationBlock **ptb, *tb; @@ -151,7 +153,7 @@ static inline TranslationBlock *tb_find_and_alloc(unsigned long pc, tb = *ptb; if (!tb) break; - if (tb->pc == pc && tb->flags == flags) + if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags) return tb; ptb = &tb->hash_next; } @@ -161,6 +163,7 @@ static inline TranslationBlock *tb_find_and_alloc(unsigned long pc, tb = &tbs[nb_tbs++]; *ptb = tb; tb->pc = pc; + tb->cs_base = cs_base; tb->flags = flags; tb->tc_ptr = NULL; tb->hash_next = NULL; @@ -198,7 +201,7 @@ int cpu_x86_exec(CPUX86State *env1) int code_gen_size, ret; void (*gen_func)(void); TranslationBlock *tb; - uint8_t *tc_ptr; + uint8_t *tc_ptr, *cs_base, *pc; unsigned int flags; /* first we save global registers */ @@ -251,17 +254,21 @@ int cpu_x86_exec(CPUX86State *env1) /* we compute the CPU state. We assume it will not change during the whole generated block. */ flags = env->seg_cache[R_CS].seg_32bit << GEN_FLAG_CODE32_SHIFT; + flags |= env->seg_cache[R_SS].seg_32bit << GEN_FLAG_SS32_SHIFT; flags |= (((unsigned long)env->seg_cache[R_DS].base | (unsigned long)env->seg_cache[R_ES].base | (unsigned long)env->seg_cache[R_SS].base) != 0) << GEN_FLAG_ADDSEG_SHIFT; - tb = tb_find_and_alloc((unsigned long)env->pc, flags); + cs_base = env->seg_cache[R_CS].base; + pc = cs_base + env->eip; + tb = tb_find_and_alloc((unsigned long)pc, (unsigned long)cs_base, + flags); tc_ptr = tb->tc_ptr; if (!tb->tc_ptr) { /* if no translated code available, then translate it now */ tc_ptr = code_gen_ptr; cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE, - &code_gen_size, (uint8_t *)env->pc, flags); + &code_gen_size, pc, cs_base, flags); tb->tc_ptr = tc_ptr; code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); } |