/[qemu]/qemu/cpu-i386.h
ViewVC logotype

Diff of /qemu/cpu-i386.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.26 by bellard, Wed May 14 21:51:13 2003 UTC revision 1.27 by bellard, Sun May 25 16:51:57 2003 UTC
# Line 459  int page_get_flags(unsigned long address Line 459  int page_get_flags(unsigned long address
459  void page_set_flags(unsigned long start, unsigned long end, int flags);  void page_set_flags(unsigned long start, unsigned long end, int flags);
460  void page_unprotect_range(uint8_t *data, unsigned long data_size);  void page_unprotect_range(uint8_t *data, unsigned long data_size);
461    
 /***************************************************/  
 /* 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;  
   
462  #endif /* CPU_I386_H */  #endif /* CPU_I386_H */

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.27

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26