Changeset 13337
- Timestamp:
- 10/16/08 13:59:21 (3 months ago)
- Files:
-
- trunk/src/recompiler_new/Makefile.kmk (modified) (1 diff)
- trunk/src/recompiler_new/VBoxRecompiler.c (modified) (1 diff)
- trunk/src/recompiler_new/dyngen-exec.h (modified) (3 diffs)
- trunk/src/recompiler_new/exec-all.h (modified) (6 diffs)
- trunk/src/recompiler_new/exec.c (modified) (10 diffs)
- trunk/src/recompiler_new/osdep.h (modified) (2 diffs)
- trunk/src/recompiler_new/softmmu_header.h (modified) (12 diffs)
- trunk/src/recompiler_new/softmmu_template.h (modified) (15 diffs)
- trunk/src/recompiler_new/target-i386/cpu.h (modified) (6 diffs)
- trunk/src/recompiler_new/target-i386/helper.c (modified) (1 diff)
- trunk/src/recompiler_new/target-i386/ops_sse.h (modified) (60 diffs)
- trunk/src/recompiler_new/translate-all.c (modified) (7 diffs)
- trunk/src/recompiler_new/translate-op.c (deleted)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/recompiler_new/Makefile.kmk
r13230 r13337 92 92 exec.c \ 93 93 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 \ 99 100 target-i386/helper.c \ 100 101 target-i386/helper2.c \ trunk/src/recompiler_new/VBoxRecompiler.c
r13230 r13337 26 26 #define LOG_GROUP LOG_GROUP_REM 27 27 #include "vl.h" 28 #include "osdep.h" 28 29 #include "exec-all.h" 29 30 trunk/src/recompiler_new/dyngen-exec.h
r11982 r13337 90 90 #define UINT64_MAX ((uint64_t)(18446744073709551615)) 91 91 92 #ifdef _BSD 93 typedef struct __sFILE FILE; 94 #else 92 95 typedef struct FILE FILE; 96 #endif 93 97 extern int fprintf(FILE *, const char *, ...); 98 extern int fputs(const char *, FILE *); 94 99 extern int printf(const char *, ...); 95 100 #undef NULL … … 234 239 #define tostring(s) #s 235 240 236 #if def __alpha__241 #if defined(__alpha__) || defined(__s390__) 237 242 /* the symbols are considered non exported so a br immediate is generated */ 238 243 #define __hidden __attribute__((visibility("hidden"))) … … 308 313 #endif 309 314 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 310 327 #endif /* !defined(__DYNGEN_EXEC_H__) */ trunk/src/recompiler_new/exec-all.h
r13230 r13337 44 44 #endif /* VBOX */ 45 45 46 #ifndef glue47 #define xglue(x, y) x ## y48 #define glue(x, y) xglue(x, y)49 #define stringify(s) tostring(s)50 #define tostring(s) #s51 #endif52 53 #if __GNUC__ < 354 #define __builtin_expect(x, n) (x)55 #endif56 57 #ifdef __i386__58 #define REGPARM(n) __attribute((regparm(n)))59 #else60 #define REGPARM(n)61 #endif62 63 46 /* is_jmp field values */ 64 47 #define DISAS_NEXT 0 /* next instruction can be analyzed */ … … 97 80 typedef void (GenOpFunc3)(long, long, long); 98 81 99 #ifndef VBOX 100 extern FILE *logfile; 101 extern int loglevel; 102 #endif 82 #include "qemu-log.h" 103 83 104 84 void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); … … 171 151 target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */ 172 152 target_ulong cs_base; /* CS base for this block */ 173 u nsigned int flags; /* flags defining in which context the code was generated */153 uint64_t flags; /* flags defining in which context the code was generated */ 174 154 uint16_t size; /* size of target code for this block (1 <= 175 155 size <= TARGET_PAGE_SIZE) */ … … 199 179 # error "First 4GB aren't reachable. jmp dword [tb_next] wont work." 200 180 # endif 201 u int32_ttb_next[2]; /* address of jump generated code */181 unsigned long tb_next[2]; /* address of jump generated code */ 202 182 #endif 203 183 /* list of TBs jumping to this one. This is a circular list using … … 331 311 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; 332 312 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" 490 314 491 315 extern spinlock_t tb_lock; … … 497 321 void tlb_fill(target_ulong addr, int is_write, int is_user, 498 322 void *retaddr); 323 324 #include "softmmu_defs.h" 499 325 500 326 #define ACCESS_TYPE (NB_MMU_MODES + 1) trunk/src/recompiler_new/exec.c
r13301 r13337 212 212 FILE *logfile; 213 213 int loglevel; 214 #ifndef VBOX 214 215 static int log_append = 0; 216 #endif 215 217 216 218 /* statistics */ … … 1829 1831 { 1830 1832 int i; 1831 TranslationBlock *tb;1832 1833 1833 1834 #if defined(DEBUG_TLB) … … 1954 1955 } 1955 1956 1957 #ifndef VBOX 1956 1958 int cpu_physical_memory_set_dirty_tracking(int enable) 1957 1959 { … … 1964 1966 return in_migration; 1965 1967 } 1966 1968 #endif 1967 1969 1968 1970 static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry) … … 2036 2038 int tlb_set_page_exec(CPUState *env, target_ulong vaddr, 2037 2039 target_phys_addr_t paddr, int prot, 2038 int is_user, int is_softmmu)2040 int mmu_idx, int is_softmmu) 2039 2041 { 2040 2042 PhysPageDesc *p; … … 2042 2044 unsigned int index; 2043 2045 target_ulong address; 2046 target_ulong code_address; 2044 2047 target_phys_addr_t addend; 2045 2048 int ret; 2046 2049 CPUTLBEntry *te; 2050 int i; 2051 target_phys_addr_t iotlb; 2047 2052 2048 2053 p = phys_page_find(paddr >> TARGET_PAGE_BITS); … … 2053 2058 } 2054 2059 #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); 2057 2062 #endif 2058 2063 2059 2064 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; 2068 2129 } 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 } 2109 2135 #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); 2155 2138 #endif 2156 2139 return ret; … … 2484 2467 flushed */ 2485 2468 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); 2487 2470 } 2488 2471 … … 2529 2512 flushed */ 2530 2513 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); 2532 2515 } 2533 2516 … … 2574 2557 flushed */ 2575 2558 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); 2577 2560 } 2578 2561 trunk/src/recompiler_new/osdep.h
r13230 r13337 26 26 #endif 27 27 28 #define unlikely(cond) RT_UNLIKELY(cond)29 30 28 #else /* !VBOX */ 31 29 … … 50 48 #endif /* !VBOX */ 51 49 50 #ifdef __OpenBSD__ 51 #include <sys/types.h> 52 #include <sys/signal.h> 52 53 #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 120 void *qemu_memalign(size_t alignment, size_t size); 121 void *qemu_vmalloc(size_t size); 122 void qemu_vfree(void *ptr); 123 124 #ifndef VBOX 125 int qemu_create_pidfile(const char *filename); 126 127 #ifdef _WIN32 128 int ffs(int i); 129 130 typedef struct { 131 long tv_sec; 132 long tv_usec; 133 } qemu_timeval; 134 int qemu_gettimeofday(qemu_timeval *tp); 135 #else 136 typedef 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 49 49 #endif 50 50 51 #if ACCESS_TYPE == 052 53 #define CPU_M EM_INDEX 051 #if ACCESS_TYPE < (NB_MMU_MODES) 52 53 #define CPU_MMU_INDEX ACCESS_TYPE 54 54 #define MMUSUFFIX _mmu 55 55 56 #elif ACCESS_TYPE == 157 58 #define CPU_M EM_INDEX 156 #elif ACCESS_TYPE == (NB_MMU_MODES) 57 58 #define CPU_MMU_INDEX (cpu_mmu_index(env)) 59 59 #define MMUSUFFIX _mmu 60 60 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)) 97 64 #define MMUSUFFIX _cmmu 98 65 … … 107 74 #endif 108 75 109 #if ACCESS_TYPE == 376 #if ACCESS_TYPE == (NB_MMU_MODES + 1) 110 77 #define ADDR_READ addr_code 111 78 #else … … 113 80 #endif 114 81 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 119 82 #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) 213 84 214 85 #ifdef VBOX … … 224 95 addr = ptr; 225 96 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 226 is_user = CPU_M EM_INDEX;97 is_user = CPU_MMU_INDEX; 227 98 if (__builtin_expect(env->tlb_table[is_user][index].addr_write != 228 99 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { … … 280 151 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), 281 152 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), 282 "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_M EM_INDEX][0].addr_write)),283 "i" (CPU_M EM_INDEX),153 "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)), 154 "i" (CPU_MMU_INDEX), 284 155 "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX)) 285 156 : "%eax", "%ecx", "%edx", "memory", "cc"); … … 301 172 addr = ptr; 302 173 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 303 is_user = CPU_M EM_INDEX;174 is_user = CPU_MMU_INDEX; 304 175 if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ != 305 176 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { … … 322 193 addr = ptr; 323 194 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 324 is_user = CPU_M EM_INDEX;195 is_user = CPU_MMU_INDEX; 325 196 if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ != 326 197 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { … … 334 205 #endif 335 206 336 #if ACCESS_TYPE != 3207 #if ACCESS_TYPE != (NB_MMU_MODES + 1) 337 208 338 209 /* generic store macro */ … … 347 218 addr = ptr; 348 219 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 349 is_user = CPU_M EM_INDEX;220 is_user = CPU_MMU_INDEX; 350 221 if (__builtin_expect(env->tlb_table[is_user][index].addr_write != 351 222 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { … … 357 228 } 358 229 359 #endif /* ACCESS_TYPE != 3*/230 #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */ 360 231 361 232 #endif /* !asm */ 362 233 363 #if ACCESS_TYPE != 3234 #if ACCESS_TYPE != (NB_MMU_MODES + 1) 364 235 365 236 #if DATA_SIZE == 8 … … 407 278 #endif /* DATA_SIZE == 4 */ 408 279 409 #endif /* ACCESS_TYPE != 3*/280 #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */ 410 281 411 282 #undef RES_TYPE … … 415 286 #undef USUFFIX 416 287 #undef DATA_SIZE 417 #undef CPU_M EM_INDEX288 #undef CPU_MMU_INDEX 418 289 #undef MMUSUFFIX 419 290 #undef ADDR_READ trunk/src/recompiler_new/softmmu_template.h
r11982 r13337 61 61 void *retaddr); 62 62 static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, 63 target_ulong tlb_addr) 63 target_ulong addr, 64 void *retaddr) 64 65 { 65 66 DATA_TYPE res; 66 67 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 69 76 #if SHIFT <= 2 70 77 res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr); … … 85 92 86 93 /* 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)94 DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 95 int mmu_idx) 89 96 { 90 97 DATA_TYPE res; 91 98 int index; 92 99 target_ulong tlb_addr; 93 target_phys_addr_t physaddr;100 target_phys_addr_t addend; 94 101 void *retaddr; 95 102 96 103 /* test if there is match for unaligned or IO access */ 97 104 /* XXX: could done more in memory macro in a non portable way */ 98 105 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 99 106 redo: 100 tlb_addr = env->tlb_table[ is_user][index].ADDR_READ;107 tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; 101 108 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 102 physaddr = addr + env->tlb_table[is_user][index].addend;103 109 if (tlb_addr & ~TARGET_PAGE_MASK) { 104 110 /* IO access */ 105 111 if ((addr & (DATA_SIZE - 1)) != 0) 106 112 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); 108 116 } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { 109 117 /* slow unaligned access (it spans two pages or IO) */ … … 111 119 retaddr = GETPC(); 112 120 #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); 117 125 } else { 118 126 /* unaligned/aligned access in the same page */ … … 120 128 if ((addr & (DATA_SIZE - 1)) != 0) { 121 129 retaddr = GETPC(); 122 do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);130 do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); 123 131 } 124 132 #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)); 126 135 } 127 136 } else { … … 130 139 #ifdef ALIGNED_ONLY 131 140 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); 135 144 goto redo; 136 145 } … … 139 148 140 149 /* handle all unaligned cases */ 141 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 142 int is_user,150 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 151 int mmu_idx, 143 152 void *retaddr) 144 153 { 145 154 DATA_TYPE res, res1, res2; 146 155 int index, shift; 147 target_phys_addr_t physaddr;156 target_phys_addr_t addend; 148 157 target_ulong tlb_addr, addr1, addr2; 149 158 150 159 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 151 160 redo: 152 tlb_addr = env->tlb_table[ is_user][index].ADDR_READ;161 tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; 153 162 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 154 physaddr = addr + env->tlb_table[is_user][index].addend;155 163 if (tlb_addr & ~TARGET_PAGE_MASK) { 156 164 /* IO access */ 157 165 if ((addr & (DATA_SIZE - 1)) != 0) 158 166 goto do_unaligned_access; 159 res = glue(io_read, SUFFIX)(physaddr, tlb_addr); 167 ret

