VirtualBox

Changeset 13337

Show
Ignore:
Timestamp:
10/16/08 13:59:21 (3 months ago)
Author:
vboxsync
Message:

more recompiler work

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/recompiler_new/Makefile.kmk

    r13230 r13337  
    9292        exec.c                  \ 
    9393        translate-all.c         \ 
    94         translate-op.c          \ 
    95         tcg/tcg.c               \ 
    96         tcg/tcg-dyngen.c        \ 
    97         tcg/tcg-runtime.c       \ 
    98         fpu/softfloat-native.c  \ 
     94        host-utils.c            \ 
     95        tcg/tcg.c               \ 
     96        tcg/tcg-dyngen.c        \ 
     97        tcg/tcg-runtime.c       \ 
     98        fpu/softfloat-native.c  \ 
     99        target-i386/op_helper.c \ 
    99100        target-i386/helper.c    \ 
    100101        target-i386/helper2.c   \ 
  • trunk/src/recompiler_new/VBoxRecompiler.c

    r13230 r13337  
    2626#define LOG_GROUP LOG_GROUP_REM 
    2727#include "vl.h" 
     28#include "osdep.h" 
    2829#include "exec-all.h" 
    2930 
  • trunk/src/recompiler_new/dyngen-exec.h

    r11982 r13337  
    9090#define UINT64_MAX              ((uint64_t)(18446744073709551615)) 
    9191 
     92#ifdef _BSD 
     93typedef struct __sFILE FILE; 
     94#else 
    9295typedef struct FILE FILE; 
     96#endif 
    9397extern int fprintf(FILE *, const char *, ...); 
     98extern int fputs(const char *, FILE *); 
    9499extern int printf(const char *, ...); 
    95100#undef NULL 
     
    234239#define tostring(s)     #s 
    235240 
    236 #ifdef __alpha__ 
     241#if defined(__alpha__) || defined(__s390__) 
    237242/* the symbols are considered non exported so a br immediate is generated */ 
    238243#define __hidden __attribute__((visibility("hidden"))) 
     
    308313#endif 
    309314 
     315 
     316/* The return address may point to the start of the next instruction. 
     317   Subtracting one gets us the call instruction itself.  */ 
     318#if defined(__s390__) 
     319# define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1)) 
     320#elif defined(__arm__) 
     321/* Thumb return addresses have the low bit set, so we need to subtract two. 
     322   This is still safe in ARM mode because instructions are 4 bytes.  */ 
     323# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 2)) 
     324#else 
     325# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 1)) 
     326#endif 
    310327#endif /* !defined(__DYNGEN_EXEC_H__) */ 
  • trunk/src/recompiler_new/exec-all.h

    r13230 r13337  
    4444#endif /* VBOX */ 
    4545 
    46 #ifndef glue 
    47 #define xglue(x, y) x ## y 
    48 #define glue(x, y) xglue(x, y) 
    49 #define stringify(s)    tostring(s) 
    50 #define tostring(s)     #s 
    51 #endif 
    52  
    53 #if __GNUC__ < 3 
    54 #define __builtin_expect(x, n) (x) 
    55 #endif 
    56  
    57 #ifdef __i386__ 
    58 #define REGPARM(n) __attribute((regparm(n))) 
    59 #else 
    60 #define REGPARM(n) 
    61 #endif 
    62  
    6346/* is_jmp field values */ 
    6447#define DISAS_NEXT    0 /* next instruction can be analyzed */ 
     
    9780typedef void (GenOpFunc3)(long, long, long); 
    9881 
    99 #ifndef VBOX 
    100 extern FILE *logfile; 
    101 extern int loglevel; 
    102 #endif 
     82#include "qemu-log.h" 
    10383 
    10484void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); 
     
    171151    target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */ 
    172152    target_ulong cs_base; /* CS base for this block */ 
    173     unsigned int flags; /* flags defining in which context the code was generated */ 
     153    uint64_t flags; /* flags defining in which context the code was generated */ 
    174154    uint16_t size;      /* size of target code for this block (1 <= 
    175155                           size <= TARGET_PAGE_SIZE) */ 
     
    199179#  error "First 4GB aren't reachable. jmp dword [tb_next] wont work." 
    200180# endif 
    201     uint32_t tb_next[2]; /* address of jump generated code */ 
     181    unsigned long tb_next[2]; /* address of jump generated code */ 
    202182#endif 
    203183    /* list of TBs jumping to this one. This is a circular list using 
     
    331311extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; 
    332312 
    333 #ifdef __powerpc__ 
    334 static inline int testandset (int *p) 
    335 
    336     int ret; 
    337     __asm__ __volatile__ ( 
    338                           "0:    lwarx %0,0,%1\n" 
    339                           "      xor. %0,%3,%0\n" 
    340                           "      bne 1f\n" 
    341                           "      stwcx. %2,0,%1\n" 
    342                           "      bne- 0b\n" 
    343                           "1:    " 
    344                           : "=&r" (ret) 
    345                           : "r" (p), "r" (1), "r" (0) 
    346                           : "cr0", "memory"); 
    347     return ret; 
    348 
    349 #endif 
    350  
    351 #ifdef __i386__ 
    352 static inline int testandset (int *p) 
    353 
    354     long int readval = 0; 
    355  
    356     __asm__ __volatile__ ("lock; cmpxchgl %2, %0" 
    357                           : "+m" (*p), "+a" (readval) 
    358                           : "r" (1) 
    359                           : "cc"); 
    360     return readval; 
    361 
    362 #endif 
    363  
    364 #ifdef __x86_64__ 
    365 static inline int testandset (int *p) 
    366 
    367     long int readval = 0; 
    368  
    369     __asm__ __volatile__ ("lock; cmpxchgl %2, %0" 
    370                           : "+m" (*p), "+a" (readval) 
    371                           : "r" (1) 
    372                           : "cc"); 
    373     return readval; 
    374 
    375 #endif 
    376  
    377 #ifdef __s390__ 
    378 static inline int testandset (int *p) 
    379 
    380     int ret; 
    381  
    382     __asm__ __volatile__ ("0: cs    %0,%1,0(%2)\n" 
    383                           "   jl    0b" 
    384                           : "=&d" (ret) 
    385                           : "r" (1), "a" (p), "0" (*p) 
    386                           : "cc", "memory" ); 
    387     return ret; 
    388 
    389 #endif 
    390  
    391 #ifdef __alpha__ 
    392 static inline int testandset (int *p) 
    393 
    394     int ret; 
    395     unsigned long one; 
    396  
    397     __asm__ __volatile__ ("0:   mov 1,%2\n" 
    398                           "     ldl_l %0,%1\n" 
    399                           "     stl_c %2,%1\n" 
    400                           "     beq %2,1f\n" 
    401                           ".subsection 2\n" 
    402                           "1:   br 0b\n" 
    403                           ".previous" 
    404                           : "=r" (ret), "=m" (*p), "=r" (one) 
    405                           : "m" (*p)); 
    406     return ret; 
    407 
    408 #endif 
    409  
    410 #ifdef __sparc__ 
    411 static inline int testandset (int *p) 
    412 
    413         int ret; 
    414  
    415         __asm__ __volatile__("ldstub    [%1], %0" 
    416                              : "=r" (ret) 
    417                              : "r" (p) 
    418                              : "memory"); 
    419  
    420         return (ret ? 1 : 0); 
    421 
    422 #endif 
    423  
    424 #ifdef __arm__ 
    425 static inline int testandset (int *spinlock) 
    426 
    427     register unsigned int ret; 
    428     __asm__ __volatile__("swp %0, %1, [%2]" 
    429                          : "=r"(ret) 
    430                          : "0"(1), "r"(spinlock)); 
    431  
    432     return ret; 
    433 
    434 #endif 
    435  
    436 #ifdef __mc68000 
    437 static inline int testandset (int *p) 
    438 
    439     char ret; 
    440     __asm__ __volatile__("tas %1; sne %0" 
    441                          : "=r" (ret) 
    442                          : "m" (p) 
    443                          : "cc","memory"); 
    444     return ret; 
    445 
    446 #endif 
    447  
    448 #ifdef __ia64 
    449 #include <ia64intrin.h> 
    450  
    451 static inline int testandset (int *p) 
    452 
    453     return __sync_lock_test_and_set (p, 1); 
    454 
    455 #endif 
    456  
    457 typedef int spinlock_t; 
    458  
    459 #define SPIN_LOCK_UNLOCKED 0 
    460  
    461 #if defined(CONFIG_USER_ONLY) 
    462 static inline void spin_lock(spinlock_t *lock) 
    463 
    464     while (testandset(lock)); 
    465 
    466  
    467 static inline void spin_unlock(spinlock_t *lock) 
    468 
    469     *lock = 0; 
    470 
    471  
    472 static inline int spin_trylock(spinlock_t *lock) 
    473 
    474     return !testandset(lock); 
    475 
    476 #else 
    477 static inline void spin_lock(spinlock_t *lock) 
    478 
    479 
    480  
    481 static inline void spin_unlock(spinlock_t *lock) 
    482 
    483 
    484  
    485 static inline int spin_trylock(spinlock_t *lock) 
    486 
    487     return 1; 
    488 
    489 #endif 
     313#include "qemu-lock.h" 
    490314 
    491315extern spinlock_t tb_lock; 
     
    497321void tlb_fill(target_ulong addr, int is_write, int is_user, 
    498322              void *retaddr); 
     323 
     324#include "softmmu_defs.h" 
    499325 
    500326#define ACCESS_TYPE (NB_MMU_MODES + 1) 
  • trunk/src/recompiler_new/exec.c

    r13301 r13337  
    212212FILE *logfile; 
    213213int loglevel; 
     214#ifndef VBOX 
    214215static int log_append = 0; 
     216#endif 
    215217 
    216218/* statistics */ 
     
    18291831{ 
    18301832    int i; 
    1831     TranslationBlock *tb; 
    18321833 
    18331834#if defined(DEBUG_TLB) 
     
    19541955} 
    19551956 
     1957#ifndef VBOX 
    19561958int cpu_physical_memory_set_dirty_tracking(int enable) 
    19571959{ 
     
    19641966    return in_migration; 
    19651967} 
    1966  
     1968#endif 
    19671969 
    19681970static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry) 
     
    20362038int tlb_set_page_exec(CPUState *env, target_ulong vaddr, 
    20372039                      target_phys_addr_t paddr, int prot, 
    2038                       int is_user, int is_softmmu) 
     2040                      int mmu_idx, int is_softmmu) 
    20392041{ 
    20402042    PhysPageDesc *p; 
     
    20422044    unsigned int index; 
    20432045    target_ulong address; 
     2046    target_ulong code_address; 
    20442047    target_phys_addr_t addend; 
    20452048    int ret; 
    20462049    CPUTLBEntry *te; 
     2050    int i; 
     2051    target_phys_addr_t iotlb; 
    20472052 
    20482053    p = phys_page_find(paddr >> TARGET_PAGE_BITS); 
     
    20532058    } 
    20542059#if defined(DEBUG_TLB) 
    2055     printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n", 
    2056            vaddr, (int)paddr, prot, is_user, is_softmmu, pd); 
     2060    printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n", 
     2061           vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd); 
    20572062#endif 
    20582063 
    20592064    ret = 0; 
    2060 #if !defined(CONFIG_SOFTMMU) 
    2061     if (is_softmmu) 
    2062 #endif 
    2063     { 
    2064         if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { 
    2065             /* IO memory case */ 
    2066             address = vaddr | pd; 
    2067             addend = paddr; 
     2065    address = vaddr; 
     2066    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { 
     2067        /* IO memory case (romd handled later) */ 
     2068        address |= TLB_MMIO; 
     2069    } 
     2070#if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB) 
     2071    addend = pd & TARGET_PAGE_MASK; 
     2072#elif !defined(VBOX) 
     2073    addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK); 
     2074#else 
     2075    addend = (unsigned long)remR3GCPhys2HCVirt(env, pd & TARGET_PAGE_MASK); 
     2076#endif 
     2077    if ((pd & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) { 
     2078        /* Normal RAM.  */ 
     2079        iotlb = pd & TARGET_PAGE_MASK; 
     2080        if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM) 
     2081            iotlb |= IO_MEM_NOTDIRTY; 
     2082        else 
     2083            iotlb |= IO_MEM_ROM; 
     2084    } else { 
     2085        /* IO handlers are currently passed a phsical address. 
     2086           It would be nice to pass an offset from the base address 
     2087           of that region.  This would avoid having to special case RAM, 
     2088           and avoid full address decoding in every device. 
     2089           We can't use the high bits of pd for this because 
     2090           IO_MEM_ROMD uses these as a ram address.  */ 
     2091        iotlb = (pd & ~TARGET_PAGE_MASK) + paddr; 
     2092    } 
     2093 
     2094    code_address = address; 
     2095    /* Make accesses to pages with watchpoints go via the 
     2096       watchpoint trap routines.  */ 
     2097    for (i = 0; i < env->nb_watchpoints; i++) { 
     2098        if (vaddr == (env->watchpoint[i].vaddr & TARGET_PAGE_MASK)) { 
     2099            iotlb = io_mem_watch + paddr; 
     2100            /* TODO: The memory case can be optimized by not trapping 
     2101               reads of pages with a write breakpoint.  */ 
     2102            address |= TLB_MMIO; 
     2103        } 
     2104    } 
     2105 
     2106    index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 
     2107    env->iotlb[mmu_idx][index] = iotlb - vaddr; 
     2108    te = &env->tlb_table[mmu_idx][index]; 
     2109    te->addend = addend - vaddr; 
     2110    if (prot & PAGE_READ) { 
     2111        te->addr_read = address; 
     2112    } else { 
     2113        te->addr_read = -1; 
     2114    } 
     2115 
     2116    if (prot & PAGE_EXEC) { 
     2117        te->addr_code = code_address; 
     2118    } else { 
     2119        te->addr_code = -1; 
     2120    } 
     2121    if (prot & PAGE_WRITE) { 
     2122        if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || 
     2123            (pd & IO_MEM_ROMD)) { 
     2124            /* Write access calls the I/O callback.  */ 
     2125            te->addr_write = address | TLB_MMIO; 
     2126        } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
     2127                   !cpu_physical_memory_is_dirty(pd)) { 
     2128            te->addr_write = address | TLB_NOTDIRTY; 
    20682129        } else { 
    2069             /* standard memory */ 
    2070             address = vaddr; 
    2071 #if defined(VBOX) && defined(REM_PHYS_ADDR_IN_TLB) 
    2072             addend = pd & TARGET_PAGE_MASK; 
    2073 #elif !defined(VBOX) 
    2074             addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK); 
    2075 #else 
    2076             addend = (unsigned long)remR3GCPhys2HCVirt(env, pd & TARGET_PAGE_MASK); 
    2077 #endif 
    2078         } 
    2079  
    2080         index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 
    2081         addend -= vaddr; 
    2082         te = &env->tlb_table[is_user][index]; 
    2083         te->addend = addend; 
    2084         if (prot & PAGE_READ) { 
    2085             te->addr_read = address; 
    2086         } else { 
    2087             te->addr_read = -1; 
    2088         } 
    2089         if (prot & PAGE_EXEC) { 
    2090             te->addr_code = address; 
    2091         } else { 
    2092             te->addr_code = -1; 
    2093         } 
    2094         if (prot & PAGE_WRITE) { 
    2095             if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || 
    2096                 (pd & IO_MEM_ROMD)) { 
    2097                 /* write access calls the I/O callback */ 
    2098                 te->addr_write = vaddr | 
    2099                     (pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD)); 
    2100             } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
    2101                        !cpu_physical_memory_is_dirty(pd)) { 
    2102                 te->addr_write = vaddr | IO_MEM_NOTDIRTY; 
    2103             } else { 
    2104                 te->addr_write = address; 
    2105             } 
    2106         } else { 
    2107             te->addr_write = -1; 
    2108         } 
     2130            te->addr_write = address; 
     2131        } 
     2132    } else { 
     2133        te->addr_write = -1; 
     2134    } 
    21092135#ifdef VBOX 
    2110         /* inform raw mode about TLB page change */ 
    2111         remR3FlushPage(env, vaddr); 
    2112 #endif 
    2113     } 
    2114 #if !defined(CONFIG_SOFTMMU) 
    2115     else { 
    2116         if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) { 
    2117             /* IO access: no mapping is done as it will be handled by the 
    2118                soft MMU */ 
    2119             if (!(env->hflags & HF_SOFTMMU_MASK)) 
    2120                 ret = 2; 
    2121         } else { 
    2122             void *map_addr; 
    2123  
    2124             if (vaddr >= MMAP_AREA_END) { 
    2125                 ret = 2; 
    2126             } else { 
    2127                 if (prot & PROT_WRITE) { 
    2128                     if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || 
    2129 #if defined(TARGET_HAS_SMC) || 1 
    2130                         first_tb || 
    2131 #endif 
    2132                         ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
    2133                          !cpu_physical_memory_is_dirty(pd))) { 
    2134                         /* ROM: we do as if code was inside */ 
    2135                         /* if code is present, we only map as read only and save the 
    2136                            original mapping */ 
    2137                         VirtPageDesc *vp; 
    2138  
    2139                         vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS, 1); 
    2140                         vp->phys_addr = pd; 
    2141                         vp->prot = prot; 
    2142                         vp->valid_tag = virt_valid_tag; 
    2143                         prot &= ~PAGE_WRITE; 
    2144                     } 
    2145                 } 
    2146                 map_addr = mmap((void *)vaddr, TARGET_PAGE_SIZE, prot, 
    2147                                 MAP_SHARED | MAP_FIXED, phys_ram_fd, (pd & TARGET_PAGE_MASK)); 
    2148                 if (map_addr == MAP_FAILED) { 
    2149                     cpu_abort(env, "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n", 
    2150                               paddr, vaddr); 
    2151                 } 
    2152             } 
    2153         } 
    2154     } 
     2136    /* inform raw mode about TLB page change */ 
     2137    remR3FlushPage(env, vaddr); 
    21552138#endif 
    21562139    return ret; 
     
    24842467       flushed */ 
    24852468    if (dirty_flags == 0xff) 
    2486         tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr); 
     2469        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_io_vaddr); 
    24872470} 
    24882471 
     
    25292512       flushed */ 
    25302513    if (dirty_flags == 0xff) 
    2531         tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr); 
     2514        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_io_vaddr); 
    25322515} 
    25332516 
     
    25742557       flushed */ 
    25752558    if (dirty_flags == 0xff) 
    2576         tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr); 
     2559        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_io_vaddr); 
    25772560} 
    25782561 
  • trunk/src/recompiler_new/osdep.h

    r13230 r13337  
    2626#endif 
    2727 
    28 #define unlikely(cond)      RT_UNLIKELY(cond) 
    29  
    3028#else /* !VBOX */ 
    3129 
     
    5048#endif /* !VBOX */ 
    5149 
     50#ifdef __OpenBSD__ 
     51#include <sys/types.h> 
     52#include <sys/signal.h> 
    5253#endif 
     54 
     55#ifndef glue 
     56#define xglue(x, y) x ## y 
     57#define glue(x, y) xglue(x, y) 
     58#define stringify(s)    tostring(s) 
     59#define tostring(s)     #s 
     60#endif 
     61 
     62#ifndef likely 
     63#ifndef VBOX 
     64#if __GNUC__ < 3 
     65#define __builtin_expect(x, n) (x) 
     66#endif 
     67 
     68#define likely(x)   __builtin_expect(!!(x), 1) 
     69#define unlikely(x)   __builtin_expect(!!(x), 0) 
     70#else // VBOX 
     71#define likely(cond)        RT_LIKELY(cond) 
     72#define unlikely(cond)      RT_UNLIKELY(cond) 
     73#endif 
     74#endif // !likely 
     75 
     76#ifndef offsetof 
     77#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) 
     78#endif 
     79#ifndef container_of 
     80#define container_of(ptr, type, member) ({                      \ 
     81        const typeof(((type *) 0)->member) *__mptr = (ptr);     \ 
     82        (type *) ((char *) __mptr - offsetof(type, member));}) 
     83#endif 
     84 
     85#ifndef MIN 
     86#define MIN(a, b) (((a) < (b)) ? (a) : (b)) 
     87#endif 
     88#ifndef MAX 
     89#define MAX(a, b) (((a) > (b)) ? (a) : (b)) 
     90#endif 
     91 
     92#ifndef ARRAY_SIZE 
     93#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 
     94#endif 
     95 
     96#ifndef always_inline 
     97#if (__GNUC__ < 3) || defined(__APPLE__) 
     98#define always_inline inline 
     99#else 
     100#define always_inline __attribute__ (( always_inline )) __inline__ 
     101#define inline always_inline 
     102#endif 
     103#else 
     104#define inline always_inline 
     105#endif 
     106 
     107#ifdef __i386__ 
     108#define REGPARM __attribute((regparm(3))) 
     109#else 
     110#define REGPARM 
     111#endif 
     112 
     113#if defined (__GNUC__) && defined (__GNUC_MINOR_) 
     114# define QEMU_GNUC_PREREQ(maj, min) \ 
     115         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) 
     116#else 
     117# define QEMU_GNUC_PREREQ(maj, min) 0 
     118#endif 
     119 
     120void *qemu_memalign(size_t alignment, size_t size); 
     121void *qemu_vmalloc(size_t size); 
     122void qemu_vfree(void *ptr); 
     123 
     124#ifndef VBOX 
     125int qemu_create_pidfile(const char *filename); 
     126 
     127#ifdef _WIN32 
     128int ffs(int i); 
     129 
     130typedef struct { 
     131    long tv_sec; 
     132    long tv_usec; 
     133} qemu_timeval; 
     134int qemu_gettimeofday(qemu_timeval *tp); 
     135#else 
     136typedef struct timeval qemu_timeval; 
     137#define qemu_gettimeofday(tp) gettimeofday(tp, NULL); 
     138#endif /* !_WIN32 */ 
     139#endif // !VBOX 
     140 
     141#endif 
  • trunk/src/recompiler_new/softmmu_header.h

    r11982 r13337  
    4949#endif 
    5050 
    51 #if ACCESS_TYPE == 0 
    52  
    53 #define CPU_MEM_INDEX 0 
     51#if ACCESS_TYPE < (NB_MMU_MODES) 
     52 
     53#define CPU_MMU_INDEX ACCESS_TYPE 
    5454#define MMUSUFFIX _mmu 
    5555 
    56 #elif ACCESS_TYPE == 1 
    57  
    58 #define CPU_MEM_INDEX 1 
     56#elif ACCESS_TYPE == (NB_MMU_MODES) 
     57 
     58#define CPU_MMU_INDEX (cpu_mmu_index(env)) 
    5959#define MMUSUFFIX _mmu 
    6060 
    61 #elif ACCESS_TYPE == 2 
    62  
    63 #ifdef TARGET_I386 
    64 #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) 
    65 #elif defined (TARGET_PPC) 
    66 #define CPU_MEM_INDEX (msr_pr) 
    67 #elif defined (TARGET_MIPS) 
    68 #define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM) 
    69 #elif defined (TARGET_SPARC) 
    70 #define CPU_MEM_INDEX ((env->psrs) == 0) 
    71 #elif defined (TARGET_ARM) 
    72 #define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) 
    73 #elif defined (TARGET_SH4) 
    74 #define CPU_MEM_INDEX ((env->sr & SR_MD) == 0) 
    75 #else 
    76 #error unsupported CPU 
    77 #endif 
    78 #define MMUSUFFIX _mmu 
    79  
    80 #elif ACCESS_TYPE == 3 
    81  
    82 #ifdef TARGET_I386 
    83 #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) 
    84 #elif defined (TARGET_PPC) 
    85 #define CPU_MEM_INDEX (msr_pr) 
    86 #elif defined (TARGET_MIPS) 
    87 #define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM) 
    88 #elif defined (TARGET_SPARC) 
    89 #define CPU_MEM_INDEX ((env->psrs) == 0) 
    90 #elif defined (TARGET_ARM) 
    91 #define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) 
    92 #elif defined (TARGET_SH4) 
    93 #define CPU_MEM_INDEX ((env->sr & SR_MD) == 0) 
    94 #else 
    95 #error unsupported CPU 
    96 #endif 
     61#elif ACCESS_TYPE == (NB_MMU_MODES + 1) 
     62 
     63#define CPU_MMU_INDEX (cpu_mmu_index(env)) 
    9764#define MMUSUFFIX _cmmu 
    9865 
     
    10774#endif 
    10875 
    109 #if ACCESS_TYPE == 3 
     76#if ACCESS_TYPE == (NB_MMU_MODES + 1) 
    11077#define ADDR_READ addr_code 
    11178#else 
     
    11380#endif 
    11481 
    115 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 
    116                                                          int is_user); 
    117 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user); 
    118  
    11982#if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \ 
    120     (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU) && (!defined(VBOX) || !defined(REM_PHYS_ADDR_IN_TLB)) 
    121  
    122 #define CPU_TLB_ENTRY_BITS 4 
    123  
    124 static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) 
    125 
    126     int res; 
    127  
    128     asm volatile ("movl %1, %%edx\n" 
    129                   "movl %1, %%eax\n" 
    130                   "shrl %3, %%edx\n" 
    131                   "andl %4, %%eax\n" 
    132                   "andl %2, %%edx\n" 
    133                   "leal %5(%%edx, %%ebp), %%edx\n" 
    134                   "cmpl (%%edx), %%eax\n" 
    135                   "movl %1, %%eax\n" 
    136                   "je 1f\n" 
    137                   "pushl %6\n" 
    138                   "call %7\n" 
    139                   "popl %%edx\n" 
    140                   "movl %%eax, %0\n" 
    141                   "jmp 2f\n" 
    142                   "1:\n" 
    143                   "addl 12(%%edx), %%eax\n" 
    144 #if DATA_SIZE == 1 
    145                   "movzbl (%%eax), %0\n" 
    146 #elif DATA_SIZE == 2 
    147                   "movzwl (%%eax), %0\n" 
    148 #elif DATA_SIZE == 4 
    149                   "movl (%%eax), %0\n" 
    150 #else 
    151 #error unsupported size 
    152 #endif 
    153                   "2:\n" 
    154                   : "=r" (res) 
    155                   : "r" (ptr),  
    156                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),  
    157                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),  
    158                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), 
    159                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)), 
    160                   "i" (CPU_MEM_INDEX), 
    161                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) 
    162                   : "%eax", "%ecx", "%edx", "memory", "cc"); 
    163     return res; 
    164 
    165  
    166 #if DATA_SIZE <= 2 
    167 static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr) 
    168 
    169     int res; 
    170  
    171     asm volatile ("movl %1, %%edx\n" 
    172                   "movl %1, %%eax\n" 
    173                   "shrl %3, %%edx\n" 
    174                   "andl %4, %%eax\n" 
    175                   "andl %2, %%edx\n" 
    176                   "leal %5(%%edx, %%ebp), %%edx\n" 
    177                   "cmpl (%%edx), %%eax\n" 
    178                   "movl %1, %%eax\n" 
    179                   "je 1f\n" 
    180                   "pushl %6\n" 
    181                   "call %7\n" 
    182                   "popl %%edx\n" 
    183 #if DATA_SIZE == 1 
    184                   "movsbl %%al, %0\n" 
    185 #elif DATA_SIZE == 2 
    186                   "movswl %%ax, %0\n" 
    187 #else 
    188 #error unsupported size 
    189 #endif 
    190                   "jmp 2f\n" 
    191                   "1:\n" 
    192                   "addl 12(%%edx), %%eax\n" 
    193 #if DATA_SIZE == 1 
    194                   "movsbl (%%eax), %0\n" 
    195 #elif DATA_SIZE == 2 
    196                   "movswl (%%eax), %0\n" 
    197 #else 
    198 #error unsupported size 
    199 #endif 
    200                   "2:\n" 
    201                   : "=r" (res) 
    202                   : "r" (ptr),  
    203                   "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),  
    204                   "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),  
    205                   "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), 
    206                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)), 
    207                   "i" (CPU_MEM_INDEX), 
    208                   "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) 
    209                   : "%eax", "%ecx", "%edx", "memory", "cc"); 
    210     return res; 
    211 
    212 #endif 
     83    (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU) 
    21384 
    21485#ifdef VBOX 
     
    22495    addr = ptr; 
    22596    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 
    226     is_user = CPU_MEM_INDEX; 
     97    is_user = CPU_MMU_INDEX; 
    22798    if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=  
    22899                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 
     
    280151                  "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),  
    281152                  "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), 
    282                   "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)), 
    283                   "i" (CPU_MEM_INDEX), 
     153                  "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)), 
     154                  "i" (CPU_MMU_INDEX), 
    284155                  "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX)) 
    285156                  : "%eax", "%ecx", "%edx", "memory", "cc"); 
     
    301172    addr = ptr; 
    302173    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 
    303     is_user = CPU_MEM_INDEX; 
     174    is_user = CPU_MMU_INDEX; 
    304175    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=  
    305176                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 
     
    322193    addr = ptr; 
    323194    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 
    324     is_user = CPU_MEM_INDEX; 
     195    is_user = CPU_MMU_INDEX; 
    325196    if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ !=  
    326197                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 
     
    334205#endif 
    335206 
    336 #if ACCESS_TYPE != 3 
     207#if ACCESS_TYPE != (NB_MMU_MODES + 1) 
    337208 
    338209/* generic store macro */ 
     
    347218    addr = ptr; 
    348219    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 
    349     is_user = CPU_MEM_INDEX; 
     220    is_user = CPU_MMU_INDEX; 
    350221    if (__builtin_expect(env->tlb_table[is_user][index].addr_write !=  
    351222                         (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 
     
    357228} 
    358229 
    359 #endif /* ACCESS_TYPE != 3 */ 
     230#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */ 
    360231 
    361232#endif /* !asm */ 
    362233 
    363 #if ACCESS_TYPE != 3 
     234#if ACCESS_TYPE != (NB_MMU_MODES + 1) 
    364235 
    365236#if DATA_SIZE == 8 
     
    407278#endif /* DATA_SIZE == 4 */ 
    408279 
    409 #endif /* ACCESS_TYPE != 3 */ 
     280#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */ 
    410281 
    411282#undef RES_TYPE 
     
    415286#undef USUFFIX 
    416287#undef DATA_SIZE 
    417 #undef CPU_MEM_INDEX 
     288#undef CPU_MMU_INDEX 
    418289#undef MMUSUFFIX 
    419290#undef ADDR_READ 
  • trunk/src/recompiler_new/softmmu_template.h

    r11982 r13337  
    6161                                                        void *retaddr); 
    6262static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,  
    63                                               target_ulong tlb_addr) 
     63                                              target_ulong addr, 
     64                                              void *retaddr) 
    6465{ 
    6566    DATA_TYPE res; 
    6667    int index; 
    67  
    68     index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); 
     68    index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); 
     69    physaddr = (physaddr & TARGET_PAGE_MASK) + addr; 
     70    env->mem_io_pc = (unsigned long)retaddr; 
     71    if (index > (IO_MEM_NOTDIRTY >> IO_MEM_SHIFT) 
     72            && !can_do_io(env)) { 
     73        cpu_io_recompile(env, retaddr); 
     74    } 
     75 
    6976#if SHIFT <= 2 
    7077    res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr); 
     
    8592 
    8693/* handle all cases except unaligned access which span two pages */ 
    87 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 
    88                                                          int is_user
     94DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 
     95                                                      int mmu_idx
    8996{ 
    9097    DATA_TYPE res; 
    9198    int index; 
    9299    target_ulong tlb_addr; 
    93     target_phys_addr_t physaddr
     100    target_phys_addr_t addend
    94101    void *retaddr; 
    95      
     102 
    96103    /* test if there is match for unaligned or IO access */ 
    97104    /* XXX: could done more in memory macro in a non portable way */ 
    98105    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 
    99106 redo: 
    100     tlb_addr = env->tlb_table[is_user][index].ADDR_READ; 
     107    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; 
    101108    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 
    102         physaddr = addr + env->tlb_table[is_user][index].addend; 
    103109        if (tlb_addr & ~TARGET_PAGE_MASK) { 
    104110            /* IO access */ 
    105111            if ((addr & (DATA_SIZE - 1)) != 0) 
    106112                goto do_unaligned_access; 
    107             res = glue(io_read, SUFFIX)(physaddr, tlb_addr); 
     113            retaddr = GETPC(); 
     114            addend = env->iotlb[mmu_idx][index]; 
     115            res = glue(io_read, SUFFIX)(addend, addr, retaddr); 
    108116        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { 
    109117            /* slow unaligned access (it spans two pages or IO) */ 
     
    111119            retaddr = GETPC(); 
    112120#ifdef ALIGNED_ONLY 
    113             do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr); 
    114 #endif 
    115             res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,  
    116                                                          is_user, retaddr); 
     121            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); 
     122#endif 
     123            res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr, 
     124                                                         mmu_idx, retaddr); 
    117125        } else { 
    118126            /* unaligned/aligned access in the same page */ 
     
    120128            if ((addr & (DATA_SIZE - 1)) != 0) { 
    121129                retaddr = GETPC(); 
    122                 do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr); 
     130                do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); 
    123131            } 
    124132#endif 
    125             res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr); 
     133            addend = env->tlb_table[mmu_idx][index].addend; 
     134            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend)); 
    126135        } 
    127136    } else { 
     
    130139#ifdef ALIGNED_ONLY 
    131140        if ((addr & (DATA_SIZE - 1)) != 0) 
    132             do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr); 
    133 #endif 
    134         tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr); 
     141            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); 
     142#endif 
     143        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); 
    135144        goto redo; 
    136145    } 
     
    139148 
    140149/* handle all unaligned cases */ 
    141 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,  
    142                                                         int is_user
     150static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 
     151                                                        int mmu_idx
    143152                                                        void *retaddr) 
    144153{ 
    145154    DATA_TYPE res, res1, res2; 
    146155    int index, shift; 
    147     target_phys_addr_t physaddr
     156    target_phys_addr_t addend
    148157    target_ulong tlb_addr, addr1, addr2; 
    149158 
    150159    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 
    151160 redo: 
    152     tlb_addr = env->tlb_table[is_user][index].ADDR_READ; 
     161    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; 
    153162    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 
    154         physaddr = addr + env->tlb_table[is_user][index].addend; 
    155163        if (tlb_addr & ~TARGET_PAGE_MASK) { 
    156164            /* IO access */ 
    157165            if ((addr & (DATA_SIZE - 1)) != 0) 
    158166                goto do_unaligned_access; 
    159             res = glue(io_read, SUFFIX)(physaddr, tlb_addr); 
     167            ret