| 105 |
#define CODE_GEN_MAX_SIZE 65536 |
#define CODE_GEN_MAX_SIZE 65536 |
| 106 |
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ |
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ |
| 107 |
|
|
|
#define CODE_GEN_HASH_BITS 15 |
|
|
#define CODE_GEN_HASH_SIZE (1 << CODE_GEN_HASH_BITS) |
|
|
|
|
| 108 |
#define CODE_GEN_PHYS_HASH_BITS 15 |
#define CODE_GEN_PHYS_HASH_BITS 15 |
| 109 |
#define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS) |
#define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS) |
| 110 |
|
|
| 164 |
#define CF_SINGLE_INSN 0x0008 /* compile only a single instruction */ |
#define CF_SINGLE_INSN 0x0008 /* compile only a single instruction */ |
| 165 |
|
|
| 166 |
uint8_t *tc_ptr; /* pointer to the translated code */ |
uint8_t *tc_ptr; /* pointer to the translated code */ |
|
struct TranslationBlock *hash_next; /* next matching tb for virtual address */ |
|
| 167 |
/* next matching tb for physical address. */ |
/* next matching tb for physical address. */ |
| 168 |
struct TranslationBlock *phys_hash_next; |
struct TranslationBlock *phys_hash_next; |
| 169 |
/* first and second physical page containing code. The lower bit |
/* first and second physical page containing code. The lower bit |
| 187 |
struct TranslationBlock *jmp_first; |
struct TranslationBlock *jmp_first; |
| 188 |
} TranslationBlock; |
} TranslationBlock; |
| 189 |
|
|
| 190 |
static inline unsigned int tb_hash_func(target_ulong pc) |
static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc) |
| 191 |
{ |
{ |
| 192 |
return pc & (CODE_GEN_HASH_SIZE - 1); |
return (pc ^ (pc >> TB_JMP_CACHE_BITS)) & (TB_JMP_CACHE_SIZE - 1); |
| 193 |
} |
} |
| 194 |
|
|
| 195 |
static inline unsigned int tb_phys_hash_func(unsigned long pc) |
static inline unsigned int tb_phys_hash_func(unsigned long pc) |
| 199 |
|
|
| 200 |
TranslationBlock *tb_alloc(target_ulong pc); |
TranslationBlock *tb_alloc(target_ulong pc); |
| 201 |
void tb_flush(CPUState *env); |
void tb_flush(CPUState *env); |
|
void tb_link(TranslationBlock *tb); |
|
| 202 |
void tb_link_phys(TranslationBlock *tb, |
void tb_link_phys(TranslationBlock *tb, |
| 203 |
target_ulong phys_pc, target_ulong phys_page2); |
target_ulong phys_pc, target_ulong phys_page2); |
| 204 |
|
|
|
extern TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE]; |
|
| 205 |
extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; |
extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; |
| 206 |
|
|
| 207 |
extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE]; |
extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE]; |
| 208 |
extern uint8_t *code_gen_ptr; |
extern uint8_t *code_gen_ptr; |
| 209 |
|
|
|
/* find a translation block in the translation cache. If not found, |
|
|
return NULL and the pointer to the last element of the list in pptb */ |
|
|
static inline TranslationBlock *tb_find(TranslationBlock ***pptb, |
|
|
target_ulong pc, |
|
|
target_ulong cs_base, |
|
|
unsigned int flags) |
|
|
{ |
|
|
TranslationBlock **ptb, *tb; |
|
|
unsigned int h; |
|
|
|
|
|
h = tb_hash_func(pc); |
|
|
ptb = &tb_hash[h]; |
|
|
for(;;) { |
|
|
tb = *ptb; |
|
|
if (!tb) |
|
|
break; |
|
|
if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags) |
|
|
return tb; |
|
|
ptb = &tb->hash_next; |
|
|
} |
|
|
*pptb = ptb; |
|
|
return NULL; |
|
|
} |
|
|
|
|
|
|
|
| 210 |
#if defined(USE_DIRECT_JUMP) |
#if defined(USE_DIRECT_JUMP) |
| 211 |
|
|
| 212 |
#if defined(__powerpc__) |
#if defined(__powerpc__) |