direct chaining for PowerPC and i386
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@185 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
d1fe2b2459
commit
0ca790b92e
183
cpu-i386.h
183
cpu-i386.h
@ -459,187 +459,4 @@ int page_get_flags(unsigned long address);
|
|||||||
void page_set_flags(unsigned long start, unsigned long end, int flags);
|
void page_set_flags(unsigned long start, unsigned long end, int flags);
|
||||||
void page_unprotect_range(uint8_t *data, unsigned long data_size);
|
void page_unprotect_range(uint8_t *data, unsigned long data_size);
|
||||||
|
|
||||||
/***************************************************/
|
|
||||||
/* internal functions */
|
|
||||||
|
|
||||||
#define GEN_FLAG_CODE32_SHIFT 0
|
|
||||||
#define GEN_FLAG_ADDSEG_SHIFT 1
|
|
||||||
#define GEN_FLAG_SS32_SHIFT 2
|
|
||||||
#define GEN_FLAG_VM_SHIFT 3
|
|
||||||
#define GEN_FLAG_ST_SHIFT 4
|
|
||||||
#define GEN_FLAG_CPL_SHIFT 7
|
|
||||||
#define GEN_FLAG_IOPL_SHIFT 9
|
|
||||||
#define GEN_FLAG_TF_SHIFT 11
|
|
||||||
|
|
||||||
int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
|
|
||||||
int *gen_code_size_ptr,
|
|
||||||
uint8_t *pc_start, uint8_t *cs_base, int flags,
|
|
||||||
int *code_size_ptr);
|
|
||||||
void cpu_x86_tblocks_init(void);
|
|
||||||
void page_init(void);
|
|
||||||
int page_unprotect(unsigned long address);
|
|
||||||
|
|
||||||
#define CODE_GEN_MAX_SIZE 65536
|
|
||||||
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
|
|
||||||
|
|
||||||
#define CODE_GEN_HASH_BITS 15
|
|
||||||
#define CODE_GEN_HASH_SIZE (1 << CODE_GEN_HASH_BITS)
|
|
||||||
|
|
||||||
/* maximum total translate dcode allocated */
|
|
||||||
#define CODE_GEN_BUFFER_SIZE (2048 * 1024)
|
|
||||||
//#define CODE_GEN_BUFFER_SIZE (128 * 1024)
|
|
||||||
|
|
||||||
typedef struct TranslationBlock {
|
|
||||||
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 */
|
|
||||||
uint16_t size; /* size of target code for this block (1 <=
|
|
||||||
size <= TARGET_PAGE_SIZE) */
|
|
||||||
uint8_t *tc_ptr; /* pointer to the translated code */
|
|
||||||
struct TranslationBlock *hash_next; /* next matching block */
|
|
||||||
struct TranslationBlock *page_next[2]; /* next blocks in even/odd page */
|
|
||||||
} TranslationBlock;
|
|
||||||
|
|
||||||
static inline unsigned int tb_hash_func(unsigned long pc)
|
|
||||||
{
|
|
||||||
return pc & (CODE_GEN_HASH_SIZE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tb_flush(void);
|
|
||||||
TranslationBlock *tb_alloc(unsigned long pc,
|
|
||||||
unsigned long size);
|
|
||||||
|
|
||||||
extern TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
|
|
||||||
|
|
||||||
extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
|
|
||||||
extern uint8_t *code_gen_ptr;
|
|
||||||
|
|
||||||
/* 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,
|
|
||||||
unsigned long pc,
|
|
||||||
unsigned long 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef offsetof
|
|
||||||
#define offsetof(type, field) ((size_t) &((type *)0)->field)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __powerpc__
|
|
||||||
static inline int testandset (int *p)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"0: lwarx %0,0,%1 ;"
|
|
||||||
" xor. %0,%3,%0;"
|
|
||||||
" bne 1f;"
|
|
||||||
" stwcx. %2,0,%1;"
|
|
||||||
" bne- 0b;"
|
|
||||||
"1: "
|
|
||||||
: "=&r" (ret)
|
|
||||||
: "r" (p), "r" (1), "r" (0)
|
|
||||||
: "cr0", "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __i386__
|
|
||||||
static inline int testandset (int *p)
|
|
||||||
{
|
|
||||||
char ret;
|
|
||||||
long int readval;
|
|
||||||
|
|
||||||
__asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
|
|
||||||
: "=q" (ret), "=m" (*p), "=a" (readval)
|
|
||||||
: "r" (1), "m" (*p), "a" (0)
|
|
||||||
: "memory");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __s390__
|
|
||||||
static inline int testandset (int *p)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
__asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"
|
|
||||||
" jl 0b"
|
|
||||||
: "=&d" (ret)
|
|
||||||
: "r" (1), "a" (p), "0" (*p)
|
|
||||||
: "cc", "memory" );
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __alpha__
|
|
||||||
int testandset (int *p)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
unsigned long one;
|
|
||||||
|
|
||||||
__asm__ __volatile__ ("0: mov 1,%2\n"
|
|
||||||
" ldl_l %0,%1\n"
|
|
||||||
" stl_c %2,%1\n"
|
|
||||||
" beq %2,1f\n"
|
|
||||||
".subsection 2\n"
|
|
||||||
"1: br 0b\n"
|
|
||||||
".previous"
|
|
||||||
: "=r" (ret), "=m" (*p), "=r" (one)
|
|
||||||
: "m" (*p));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __sparc__
|
|
||||||
static inline int testandset (int *p)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
__asm__ __volatile__("ldstub [%1], %0"
|
|
||||||
: "=r" (ret)
|
|
||||||
: "r" (p)
|
|
||||||
: "memory");
|
|
||||||
|
|
||||||
return (ret ? 1 : 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef int spinlock_t;
|
|
||||||
|
|
||||||
#define SPIN_LOCK_UNLOCKED 0
|
|
||||||
|
|
||||||
static inline void spin_lock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
while (testandset(lock));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void spin_unlock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
*lock = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int spin_trylock(spinlock_t *lock)
|
|
||||||
{
|
|
||||||
return !testandset(lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern spinlock_t tb_lock;
|
|
||||||
|
|
||||||
#endif /* CPU_I386_H */
|
#endif /* CPU_I386_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user