@ -207,7 +207,8 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
tb_lock ( ) ;
tb = tb_gen_code ( cpu , orig_tb - > pc , orig_tb - > cs_base , orig_tb - > flags ,
max_cycles | CF_NOCACHE
| ( ignore_icount ? CF_IGNORE_ICOUNT : 0 ) ) ;
| ( ignore_icount ? CF_IGNORE_ICOUNT : 0 )
| curr_cflags ( ) ) ;
tb - > orig_tb = orig_tb ;
tb_unlock ( ) ;
@ -225,31 +226,27 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
static void cpu_exec_step ( CPUState * cpu )
{
CPUClass * cc = CPU_GET_CLASS ( cpu ) ;
CPUArchState * env = ( CPUArchState * ) cpu - > env_ptr ;
TranslationBlock * tb ;
target_ulong cs_base , pc ;
uint32_t flags ;
uint32_t cflags = 1 | CF_IGNORE_ICOUNT ;
cpu_get_tb_cpu_state ( env , & pc , & cs_base , & flags ) ;
if ( sigsetjmp ( cpu - > jmp_env , 0 ) = = 0 ) {
mmap_lock ( ) ;
tb_lock ( ) ;
tb = tb_gen_code ( cpu , pc , cs_base , flags ,
1 | CF_NOCACHE | CF_IGNORE_ICOUNT ) ;
tb - > orig_tb = NULL ;
tb_unlock ( ) ;
mmap_unlock ( ) ;
tb = tb_lookup__cpu_state ( cpu , & pc , & cs_base , & flags ,
cflags & CF_HASH_MASK ) ;
if ( tb = = NULL ) {
mmap_lock ( ) ;
tb_lock ( ) ;
tb = tb_gen_code ( cpu , pc , cs_base , flags , cflags ) ;
tb_unlock ( ) ;
mmap_unlock ( ) ;
}
cc - > cpu_exec_enter ( cpu ) ;
/* execute the generated code */
trace_exec_tb_nocache ( tb , pc ) ;
trace_exec_tb ( tb , pc ) ;
cpu_tb_exec ( cpu , tb ) ;
cc - > cpu_exec_exit ( cpu ) ;
tb_lock ( ) ;
tb_phys_invalidate ( tb , - 1 ) ;
tb_free ( tb ) ;
tb_unlock ( ) ;
} else {
/* We may have exited due to another problem here, so we need
* to reset any tb_locks we may have taken but didn ' t release .
@ -281,6 +278,7 @@ struct tb_desc {
CPUArchState * env ;
tb_page_addr_t phys_page1 ;
uint32_t flags ;
uint32_t cf_mask ;
uint32_t trace_vcpu_dstate ;
} ;
@ -294,7 +292,7 @@ static bool tb_cmp(const void *p, const void *d)
tb - > cs_base = = desc - > cs_base & &
tb - > flags = = desc - > flags & &
tb - > trace_vcpu_dstate = = desc - > trace_vcpu_dstate & &
! ( atomic_read ( & tb - > cflags ) & CF_INVALID ) ) {
( tb_cflags ( tb ) & ( CF_HASH_MASK | CF_INVALID ) ) = = desc - > cf_mask ) {
/* check next page if needed */
if ( tb - > page_addr [ 1 ] = = - 1 ) {
return true ;
@ -313,7 +311,8 @@ static bool tb_cmp(const void *p, const void *d)
}
TranslationBlock * tb_htable_lookup ( CPUState * cpu , target_ulong pc ,
target_ulong cs_base , uint32_t flags )
target_ulong cs_base , uint32_t flags ,
uint32_t cf_mask )
{
tb_page_addr_t phys_pc ;
struct tb_desc desc ;
@ -322,11 +321,12 @@ TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
desc . env = ( CPUArchState * ) cpu - > env_ptr ;
desc . cs_base = cs_base ;
desc . flags = flags ;
desc . cf_mask = cf_mask ;
desc . trace_vcpu_dstate = * cpu - > trace_dstate ;
desc . pc = pc ;
phys_pc = get_page_addr_code ( desc . env , pc ) ;
desc . phys_page1 = phys_pc & TARGET_PAGE_MASK ;
h = tb_hash_func ( phys_pc , pc , flags , * cpu - > trace_dstate ) ;
h = tb_hash_func ( phys_pc , pc , flags , cf_mask , * cpu - > trace_dstate ) ;
return qht_lookup ( & tcg_ctx . tb_ctx . htable , tb_cmp , & desc , h ) ;
}
@ -373,8 +373,9 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
target_ulong cs_base , pc ;
uint32_t flags ;
bool acquired_tb_lock = false ;
uint32_t cf_mask = curr_cflags ( ) ;
tb = tb_lookup__cpu_state ( cpu , & pc , & cs_base , & flags ) ;
tb = tb_lookup__cpu_state ( cpu , & pc , & cs_base , & flags , cf_mask ) ;
if ( tb = = NULL ) {
/* mmap_lock is needed by tb_gen_code, and mmap_lock must be
* taken outside tb_lock . As system emulation is currently
@ -387,10 +388,10 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
/* There's a chance that our desired tb has been translated while
* taking the locks so we check again inside the lock .
*/
tb = tb_htable_lookup ( cpu , pc , cs_base , flags ) ;
tb = tb_htable_lookup ( cpu , pc , cs_base , flags , cf_mask ) ;
if ( likely ( tb = = NULL ) ) {
/* if no translated code available, then translate it now */
tb = tb_gen_code ( cpu , pc , cs_base , flags , 0 ) ;
tb = tb_gen_code ( cpu , pc , cs_base , flags , cf_mask ) ;
}
mmap_unlock ( ) ;