- Timestamp:
- Oct 16, 2008 11:59:21 AM (16 years ago)
- Location:
- trunk/src/recompiler_new
- Files:
-
- 1 deleted
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
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 retaddr = GETPC(); 168 addend = env->iotlb[mmu_idx][index]; 169 res = glue(io_read, SUFFIX)(addend, addr, retaddr); 160 170 } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { 161 171 do_unaligned_access: … … 163 173 addr1 = addr & ~(DATA_SIZE - 1); 164 174 addr2 = addr1 + DATA_SIZE; 165 res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1, 166 is_user, retaddr);167 res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2, 168 is_user, retaddr);175 res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1, 176 mmu_idx, retaddr); 177 res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2, 178 mmu_idx, retaddr); 169 179 shift = (addr & (DATA_SIZE - 1)) * 8; 170 180 #ifdef TARGET_WORDS_BIGENDIAN … … 176 186 } else { 177 187 /* unaligned/aligned access in the same page */ 178 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr); 188 addend = env->tlb_table[mmu_idx][index].addend; 189 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend)); 179 190 } 180 191 } else { 181 192 /* the page is not in the TLB : fill it */ 182 tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);193 tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); 183 194 goto redo; 184 195 } … … 195 206 static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, 196 207 DATA_TYPE val, 197 target_ulong tlb_addr,208 target_ulong addr, 198 209 void *retaddr) 199 210 { 200 211 int index; 201 202 index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); 203 env->mem_write_vaddr = tlb_addr; 204 env->mem_write_pc = (unsigned long)retaddr; 212 index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); 213 physaddr = (physaddr & TARGET_PAGE_MASK) + addr; 214 if (index > (IO_MEM_NOTDIRTY >> IO_MEM_SHIFT) 215 && !can_do_io(env)) { 216 cpu_io_recompile(env, retaddr); 217 } 218 219 env->mem_io_vaddr = addr; 220 env->mem_io_pc = (unsigned long)retaddr; 205 221 #if SHIFT <= 2 206 222 io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val); … … 219 235 } 220 236 221 void REGPARM (2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,222 223 int is_user)224 { 225 target_phys_addr_t physaddr;237 void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, 238 DATA_TYPE val, 239 int mmu_idx) 240 { 241 target_phys_addr_t addend; 226 242 target_ulong tlb_addr; 227 243 void *retaddr; 228 244 int index; 229 245 230 246 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 231 247 redo: 232 tlb_addr = env->tlb_table[ is_user][index].addr_write;248 tlb_addr = env->tlb_table[mmu_idx][index].addr_write; 233 249 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 234 physaddr = addr + env->tlb_table[is_user][index].addend;235 250 if (tlb_addr & ~TARGET_PAGE_MASK) { 236 251 /* IO access */ … … 238 253 goto do_unaligned_access; 239 254 retaddr = GETPC(); 240 glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr); 255 addend = env->iotlb[mmu_idx][index]; 256 glue(io_write, SUFFIX)(addend, val, addr, retaddr); 241 257 } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { 242 258 do_unaligned_access: 243 259 retaddr = GETPC(); 244 260 #ifdef ALIGNED_ONLY 245 do_unaligned_access(addr, 1, is_user, retaddr);246 #endif 247 glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val, 248 is_user, retaddr);261 do_unaligned_access(addr, 1, mmu_idx, retaddr); 262 #endif 263 glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val, 264 mmu_idx, retaddr); 249 265 } else { 250 266 /* aligned/unaligned access in the same page */ … … 252 268 if ((addr & (DATA_SIZE - 1)) != 0) { 253 269 retaddr = GETPC(); 254 do_unaligned_access(addr, 1, is_user, retaddr);270 do_unaligned_access(addr, 1, mmu_idx, retaddr); 255 271 } 256 272 #endif 257 glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val); 273 addend = env->tlb_table[mmu_idx][index].addend; 274 glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val); 258 275 } 259 276 } else { … … 262 279 #ifdef ALIGNED_ONLY 263 280 if ((addr & (DATA_SIZE - 1)) != 0) 264 do_unaligned_access(addr, 1, is_user, retaddr);265 #endif 266 tlb_fill(addr, 1, is_user, retaddr);281 do_unaligned_access(addr, 1, mmu_idx, retaddr); 282 #endif 283 tlb_fill(addr, 1, mmu_idx, retaddr); 267 284 goto redo; 268 285 } … … 270 287 271 288 /* handles all unaligned cases */ 272 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, 289 /* handles all unaligned cases */ 290 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, 273 291 DATA_TYPE val, 274 int is_user,292 int mmu_idx, 275 293 void *retaddr) 276 294 { 277 target_phys_addr_t physaddr;295 target_phys_addr_t addend; 278 296 target_ulong tlb_addr; 279 297 int index, i; … … 281 299 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 282 300 redo: 283 tlb_addr = env->tlb_table[ is_user][index].addr_write;301 tlb_addr = env->tlb_table[mmu_idx][index].addr_write; 284 302 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 285 physaddr = addr + env->tlb_table[is_user][index].addend;286 303 if (tlb_addr & ~TARGET_PAGE_MASK) { 287 304 /* IO access */ 288 305 if ((addr & (DATA_SIZE - 1)) != 0) 289 306 goto do_unaligned_access; 290 glue(io_write, SUFFIX)(physaddr, val, tlb_addr, retaddr); 307 addend = env->iotlb[mmu_idx][index]; 308 glue(io_write, SUFFIX)(addend, val, addr, retaddr); 291 309 } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { 292 310 do_unaligned_access: 293 311 /* XXX: not efficient, but simple */ 294 for(i = 0;i < DATA_SIZE; i++) { 312 /* Note: relies on the fact that tlb_fill() does not remove the 313 * previous page from the TLB cache. */ 314 for(i = DATA_SIZE - 1; i >= 0; i--) { 295 315 #ifdef TARGET_WORDS_BIGENDIAN 296 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), 297 is_user, retaddr);298 #else 299 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8), 300 is_user, retaddr);316 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), 317 mmu_idx, retaddr); 318 #else 319 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8), 320 mmu_idx, retaddr); 301 321 #endif 302 322 } 303 323 } else { 304 324 /* aligned/unaligned access in the same page */ 305 glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val); 325 addend = env->tlb_table[mmu_idx][index].addend; 326 glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val); 306 327 } 307 328 } else { 308 329 /* the page is not in the TLB : fill it */ 309 tlb_fill(addr, 1, is_user, retaddr);330 tlb_fill(addr, 1, mmu_idx, retaddr); 310 331 goto redo; 311 332 } -
trunk/src/recompiler_new/target-i386/cpu.h
r13230 r13337 267 267 #define MSR_MCG_CTL 0x17b 268 268 269 #define MSR_IA32_PERF_STATUS 0x198 270 269 271 #define MSR_PAT 0x277 270 272 … … 494 496 uint16_t _w[2]; 495 497 uint32_t _l[1]; 498 float32 _s[2]; 496 499 uint64_t q; 497 500 } MMXReg; … … 508 511 #define MMX_W(n) _w[3 - (n)] 509 512 #define MMX_L(n) _l[1 - (n)] 513 #define MMX_S(n) _s[1 - (n)] 510 514 #else 511 515 #define XMM_B(n) _b[n] … … 519 523 #define MMX_W(n) _w[n] 520 524 #define MMX_L(n) _l[n] 525 #define MMX_S(n) _s[n] 521 526 #endif 522 527 #define MMX_Q(n) q … … 555 560 556 561 target_ulong cr[5]; /* NOTE: cr1 is unused */ 557 uint 32_t a20_mask;562 uint64_t a20_mask; 558 563 559 564 /* FPU state */ … … 657 662 uint32_t cpuid_ext2_features; 658 663 uint32_t cpuid_ext3_features; 664 uint32_t cpuid_apic_id; 659 665 660 666 #ifndef VBOX -
trunk/src/recompiler_new/target-i386/helper.c
r13117 r13337 30 30 # include <VBox/err.h> 31 31 #endif 32 #include "exec.h" 32 33 #ifndef VBOX 34 #include <stdarg.h> 35 #include <stdlib.h> 36 #include <stdio.h> 37 #include <string.h> 38 #include <inttypes.h> 39 #include <signal.h> 40 #include <assert.h> 41 #endif 42 43 #include "cpu.h" 44 #include "exec-all.h" 45 #include "svm.h" 46 #include "qemu-common.h" 33 47 34 48 //#define DEBUG_PCALL -
trunk/src/recompiler_new/target-i386/ops_sse.h
r11982 r13337 1 1 /* 2 * MMX/ SSE/SSE2/PNI support3 * 2 * MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI support 3 * 4 4 * Copyright (c) 2005 Fabrice Bellard 5 * Copyright (c) 2008 Intel Corporation <[email protected]> 5 6 * 6 7 * This library is free software; you can redistribute it and/or … … 18 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 20 */ 20 21 21 /* 22 22 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice … … 27 27 * of the LGPL is applied is otherwise unspecified. 28 28 */ 29 29 30 #if SHIFT == 0 30 31 #define Reg MMXReg … … 45 46 #endif 46 47 47 void OPPROTO glue(op_psrlw, SUFFIX)(void) 48 { 49 Reg *d, *s; 48 void glue(helper_psrlw, SUFFIX)(Reg *d, Reg *s) 49 { 50 50 int shift; 51 52 d = (Reg *)((char *)env + PARAM1);53 s = (Reg *)((char *)env + PARAM2);54 51 55 52 if (s->Q(0) > 15) { … … 74 71 } 75 72 76 void OPPROTO glue(op_psraw, SUFFIX)(void) 77 { 78 Reg *d, *s; 73 void glue(helper_psraw, SUFFIX)(Reg *d, Reg *s) 74 { 79 75 int shift; 80 81 d = (Reg *)((char *)env + PARAM1);82 s = (Reg *)((char *)env + PARAM2);83 76 84 77 if (s->Q(0) > 15) { … … 99 92 } 100 93 101 void OPPROTO glue(op_psllw, SUFFIX)(void) 102 { 103 Reg *d, *s; 94 void glue(helper_psllw, SUFFIX)(Reg *d, Reg *s) 95 { 104 96 int shift; 105 106 d = (Reg *)((char *)env + PARAM1);107 s = (Reg *)((char *)env + PARAM2);108 97 109 98 if (s->Q(0) > 15) { … … 128 117 } 129 118 130 void OPPROTO glue(op_psrld, SUFFIX)(void) 131 { 132 Reg *d, *s; 119 void glue(helper_psrld, SUFFIX)(Reg *d, Reg *s) 120 { 133 121 int shift; 134 135 d = (Reg *)((char *)env + PARAM1);136 s = (Reg *)((char *)env + PARAM2);137 122 138 123 if (s->Q(0) > 31) { … … 153 138 } 154 139 155 void OPPROTO glue(op_psrad, SUFFIX)(void) 156 { 157 Reg *d, *s; 140 void glue(helper_psrad, SUFFIX)(Reg *d, Reg *s) 141 { 158 142 int shift; 159 160 d = (Reg *)((char *)env + PARAM1);161 s = (Reg *)((char *)env + PARAM2);162 143 163 144 if (s->Q(0) > 31) { … … 174 155 } 175 156 176 void OPPROTO glue(op_pslld, SUFFIX)(void) 177 { 178 Reg *d, *s; 157 void glue(helper_pslld, SUFFIX)(Reg *d, Reg *s) 158 { 179 159 int shift; 180 181 d = (Reg *)((char *)env + PARAM1);182 s = (Reg *)((char *)env + PARAM2);183 160 184 161 if (s->Q(0) > 31) { … … 199 176 } 200 177 201 void OPPROTO glue(op_psrlq, SUFFIX)(void) 202 { 203 Reg *d, *s; 178 void glue(helper_psrlq, SUFFIX)(Reg *d, Reg *s) 179 { 204 180 int shift; 205 206 d = (Reg *)((char *)env + PARAM1);207 s = (Reg *)((char *)env + PARAM2);208 181 209 182 if (s->Q(0) > 63) { … … 222 195 } 223 196 224 void OPPROTO glue(op_psllq, SUFFIX)(void) 225 { 226 Reg *d, *s; 197 void glue(helper_psllq, SUFFIX)(Reg *d, Reg *s) 198 { 227 199 int shift; 228 229 d = (Reg *)((char *)env + PARAM1);230 s = (Reg *)((char *)env + PARAM2);231 200 232 201 if (s->Q(0) > 63) { … … 246 215 247 216 #if SHIFT == 1 248 void OPPROTO glue(op_psrldq, SUFFIX)(void) 249 { 250 Reg *d, *s; 217 void glue(helper_psrldq, SUFFIX)(Reg *d, Reg *s) 218 { 251 219 int shift, i; 252 220 253 d = (Reg *)((char *)env + PARAM1);254 s = (Reg *)((char *)env + PARAM2);255 221 shift = s->L(0); 256 222 if (shift > 16) … … 263 229 } 264 230 265 void OPPROTO glue(op_pslldq, SUFFIX)(void) 266 { 267 Reg *d, *s; 231 void glue(helper_pslldq, SUFFIX)(Reg *d, Reg *s) 232 { 268 233 int shift, i; 269 234 270 d = (Reg *)((char *)env + PARAM1);271 s = (Reg *)((char *)env + PARAM2);272 235 shift = s->L(0); 273 236 if (shift > 16) … … 281 244 #endif 282 245 283 #define SSE_ OP_B(name, F)\284 void OPPROTO glue(name, SUFFIX) (void)\246 #define SSE_HELPER_B(name, F)\ 247 void glue(name, SUFFIX) (Reg *d, Reg *s)\ 285 248 {\ 286 Reg *d, *s;\287 d = (Reg *)((char *)env + PARAM1);\288 s = (Reg *)((char *)env + PARAM2);\289 249 d->B(0) = F(d->B(0), s->B(0));\ 290 250 d->B(1) = F(d->B(1), s->B(1));\ … … 307 267 } 308 268 309 #define SSE_ OP_W(name, F)\310 void OPPROTO glue(name, SUFFIX) (void)\269 #define SSE_HELPER_W(name, F)\ 270 void glue(name, SUFFIX) (Reg *d, Reg *s)\ 311 271 {\ 312 Reg *d, *s;\313 d = (Reg *)((char *)env + PARAM1);\314 s = (Reg *)((char *)env + PARAM2);\315 272 d->W(0) = F(d->W(0), s->W(0));\ 316 273 d->W(1) = F(d->W(1), s->W(1));\ … … 325 282 } 326 283 327 #define SSE_ OP_L(name, F)\328 void OPPROTO glue(name, SUFFIX) (void)\284 #define SSE_HELPER_L(name, F)\ 285 void glue(name, SUFFIX) (Reg *d, Reg *s)\ 329 286 {\ 330 Reg *d, *s;\331 d = (Reg *)((char *)env + PARAM1);\332 s = (Reg *)((char *)env + PARAM2);\333 287 d->L(0) = F(d->L(0), s->L(0));\ 334 288 d->L(1) = F(d->L(1), s->L(1));\ … … 339 293 } 340 294 341 #define SSE_ OP_Q(name, F)\342 void OPPROTO glue(name, SUFFIX) (void)\295 #define SSE_HELPER_Q(name, F)\ 296 void glue(name, SUFFIX) (Reg *d, Reg *s)\ 343 297 {\ 344 Reg *d, *s;\345 d = (Reg *)((char *)env + PARAM1);\346 s = (Reg *)((char *)env + PARAM2);\347 298 d->Q(0) = F(d->Q(0), s->Q(0));\ 348 299 XMM_ONLY(\ … … 419 370 420 371 #define FMULLW(a, b) (a) * (b) 372 #define FMULHRW(a, b) ((int16_t)(a) * (int16_t)(b) + 0x8000) >> 16 421 373 #define FMULHUW(a, b) (a) * (b) >> 16 422 374 #define FMULHW(a, b) (int16_t)(a) * (int16_t)(b) >> 16 … … 425 377 #endif 426 378 427 SSE_OP_B(op_paddb, FADD) 428 SSE_OP_W(op_paddw, FADD) 429 SSE_OP_L(op_paddl, FADD) 430 SSE_OP_Q(op_paddq, FADD) 431 432 SSE_OP_B(op_psubb, FSUB) 433 SSE_OP_W(op_psubw, FSUB) 434 SSE_OP_L(op_psubl, FSUB) 435 SSE_OP_Q(op_psubq, FSUB) 436 437 SSE_OP_B(op_paddusb, FADDUB) 438 SSE_OP_B(op_paddsb, FADDSB) 439 SSE_OP_B(op_psubusb, FSUBUB) 440 SSE_OP_B(op_psubsb, FSUBSB) 441 442 SSE_OP_W(op_paddusw, FADDUW) 443 SSE_OP_W(op_paddsw, FADDSW) 444 SSE_OP_W(op_psubusw, FSUBUW) 445 SSE_OP_W(op_psubsw, FSUBSW) 446 447 SSE_OP_B(op_pminub, FMINUB) 448 SSE_OP_B(op_pmaxub, FMAXUB) 449 450 SSE_OP_W(op_pminsw, FMINSW) 451 SSE_OP_W(op_pmaxsw, FMAXSW) 452 453 SSE_OP_Q(op_pand, FAND) 454 SSE_OP_Q(op_pandn, FANDN) 455 SSE_OP_Q(op_por, FOR) 456 SSE_OP_Q(op_pxor, FXOR) 457 458 SSE_OP_B(op_pcmpgtb, FCMPGTB) 459 SSE_OP_W(op_pcmpgtw, FCMPGTW) 460 SSE_OP_L(op_pcmpgtl, FCMPGTL) 461 462 SSE_OP_B(op_pcmpeqb, FCMPEQ) 463 SSE_OP_W(op_pcmpeqw, FCMPEQ) 464 SSE_OP_L(op_pcmpeql, FCMPEQ) 465 466 SSE_OP_W(op_pmullw, FMULLW) 467 SSE_OP_W(op_pmulhuw, FMULHUW) 468 SSE_OP_W(op_pmulhw, FMULHW) 469 470 SSE_OP_B(op_pavgb, FAVG) 471 SSE_OP_W(op_pavgw, FAVG) 472 473 void OPPROTO glue(op_pmuludq, SUFFIX) (void) 474 { 475 Reg *d, *s; 476 d = (Reg *)((char *)env + PARAM1); 477 s = (Reg *)((char *)env + PARAM2); 478 379 SSE_HELPER_B(helper_paddb, FADD) 380 SSE_HELPER_W(helper_paddw, FADD) 381 SSE_HELPER_L(helper_paddl, FADD) 382 SSE_HELPER_Q(helper_paddq, FADD) 383 384 SSE_HELPER_B(helper_psubb, FSUB) 385 SSE_HELPER_W(helper_psubw, FSUB) 386 SSE_HELPER_L(helper_psubl, FSUB) 387 SSE_HELPER_Q(helper_psubq, FSUB) 388 389 SSE_HELPER_B(helper_paddusb, FADDUB) 390 SSE_HELPER_B(helper_paddsb, FADDSB) 391 SSE_HELPER_B(helper_psubusb, FSUBUB) 392 SSE_HELPER_B(helper_psubsb, FSUBSB) 393 394 SSE_HELPER_W(helper_paddusw, FADDUW) 395 SSE_HELPER_W(helper_paddsw, FADDSW) 396 SSE_HELPER_W(helper_psubusw, FSUBUW) 397 SSE_HELPER_W(helper_psubsw, FSUBSW) 398 399 SSE_HELPER_B(helper_pminub, FMINUB) 400 SSE_HELPER_B(helper_pmaxub, FMAXUB) 401 402 SSE_HELPER_W(helper_pminsw, FMINSW) 403 SSE_HELPER_W(helper_pmaxsw, FMAXSW) 404 405 SSE_HELPER_Q(helper_pand, FAND) 406 SSE_HELPER_Q(helper_pandn, FANDN) 407 SSE_HELPER_Q(helper_por, FOR) 408 SSE_HELPER_Q(helper_pxor, FXOR) 409 410 SSE_HELPER_B(helper_pcmpgtb, FCMPGTB) 411 SSE_HELPER_W(helper_pcmpgtw, FCMPGTW) 412 SSE_HELPER_L(helper_pcmpgtl, FCMPGTL) 413 414 SSE_HELPER_B(helper_pcmpeqb, FCMPEQ) 415 SSE_HELPER_W(helper_pcmpeqw, FCMPEQ) 416 SSE_HELPER_L(helper_pcmpeql, FCMPEQ) 417 418 SSE_HELPER_W(helper_pmullw, FMULLW) 419 #if SHIFT == 0 420 SSE_HELPER_W(helper_pmulhrw, FMULHRW) 421 #endif 422 SSE_HELPER_W(helper_pmulhuw, FMULHUW) 423 SSE_HELPER_W(helper_pmulhw, FMULHW) 424 425 SSE_HELPER_B(helper_pavgb, FAVG) 426 SSE_HELPER_W(helper_pavgw, FAVG) 427 428 void glue(helper_pmuludq, SUFFIX) (Reg *d, Reg *s) 429 { 479 430 d->Q(0) = (uint64_t)s->L(0) * (uint64_t)d->L(0); 480 431 #if SHIFT == 1 … … 483 434 } 484 435 485 void OPPROTO glue(op_pmaddwd, SUFFIX) (void)436 void glue(helper_pmaddwd, SUFFIX) (Reg *d, Reg *s) 486 437 { 487 438 int i; 488 Reg *d, *s;489 d = (Reg *)((char *)env + PARAM1);490 s = (Reg *)((char *)env + PARAM2);491 439 492 440 for(i = 0; i < (2 << SHIFT); i++) { … … 506 454 } 507 455 #endif 508 void OPPROTO glue(op_psadbw, SUFFIX) (void)456 void glue(helper_psadbw, SUFFIX) (Reg *d, Reg *s) 509 457 { 510 458 unsigned int val; 511 Reg *d, *s;512 d = (Reg *)((char *)env + PARAM1);513 s = (Reg *)((char *)env + PARAM2);514 459 515 460 val = 0; … … 537 482 } 538 483 539 void OPPROTO glue(op_maskmov, SUFFIX) (void)484 void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s, target_ulong a0) 540 485 { 541 486 int i; 542 Reg *d, *s;543 d = (Reg *)((char *)env + PARAM1);544 s = (Reg *)((char *)env + PARAM2);545 487 for(i = 0; i < (8 << SHIFT); i++) { 546 488 if (s->B(i) & 0x80) 547 stb( A0 + i, d->B(i));489 stb(a0 + i, d->B(i)); 548 490 } 549 491 FORCE_RET(); 550 492 } 551 493 552 void OPPROTO glue(op_movl_mm_T0, SUFFIX) (void) 553 { 554 Reg *d; 555 d = (Reg *)((char *)env + PARAM1); 556 d->L(0) = T0; 494 void glue(helper_movl_mm_T0, SUFFIX) (Reg *d, uint32_t val) 495 { 496 d->L(0) = val; 557 497 d->L(1) = 0; 558 498 #if SHIFT == 1 … … 561 501 } 562 502 563 void OPPROTO glue(op_movl_T0_mm, SUFFIX) (void)564 {565 Reg *s;566 s = (Reg *)((char *)env + PARAM1);567 T0 = s->L(0);568 }569 570 503 #ifdef TARGET_X86_64 571 void OPPROTO glue(op_movq_mm_T0, SUFFIX) (void) 572 { 573 Reg *d; 574 d = (Reg *)((char *)env + PARAM1); 575 d->Q(0) = T0; 504 void glue(helper_movq_mm_T0, SUFFIX) (Reg *d, uint64_t val) 505 { 506 d->Q(0) = val; 576 507 #if SHIFT == 1 577 508 d->Q(1) = 0; 578 509 #endif 579 510 } 580 581 void OPPROTO glue(op_movq_T0_mm, SUFFIX) (void)582 {583 Reg *s;584 s = (Reg *)((char *)env + PARAM1);585 T0 = s->Q(0);586 }587 511 #endif 588 512 589 513 #if SHIFT == 0 590 void OPPROTO glue(op_pshufw, SUFFIX) (void) 591 { 592 #if __GCC__ == 3 || defined(RT_ARCH_AMD64) /* VBOX hack in #else */ 593 Reg r, *d, *s; 594 int order; 595 d = (Reg *)((char *)env + PARAM1); 596 s = (Reg *)((char *)env + PARAM2); 597 order = PARAM3; 514 void glue(helper_pshufw, SUFFIX) (Reg *d, Reg *s, int order) 515 { 516 Reg r; 598 517 r.W(0) = s->W(order & 3); 599 518 r.W(1) = s->W((order >> 2) & 3); … … 601 520 r.W(3) = s->W((order >> 6) & 3); 602 521 *d = r; 522 } 603 523 #else 604 Reg *s; 605 int order; 606 uint32_t l0, l1; 607 s = (Reg *)((char *)env + PARAM2); 608 order = PARAM3; 609 l0 = s->W(order & 3); 610 l0 |= (uint32_t)s->W((order >> 2) & 3) << 16; 611 l1 = s->W((order >> 4) & 3); 612 l1 |= (uint32_t)s->W((order >> 6) & 3) << 16; 613 614 s = (Reg *)((char *)env + PARAM1); 615 s->_l[0] = l0; 616 s->_l[1] = l1; 617 #endif 618 } 619 #else 620 void OPPROTO op_shufps(void) 621 { 622 Reg r, *d, *s; 623 int order; 624 d = (Reg *)((char *)env + PARAM1); 625 s = (Reg *)((char *)env + PARAM2); 626 order = PARAM3; 524 void helper_shufps(Reg *d, Reg *s, int order) 525 { 526 Reg r; 627 527 r.L(0) = d->L(order & 3); 628 528 r.L(1) = d->L((order >> 2) & 3); … … 632 532 } 633 533 634 void OPPROTO op_shufpd(void) 635 { 636 Reg r, *d, *s; 637 int order; 638 d = (Reg *)((char *)env + PARAM1); 639 s = (Reg *)((char *)env + PARAM2); 640 order = PARAM3; 534 void helper_shufpd(Reg *d, Reg *s, int order) 535 { 536 Reg r; 641 537 r.Q(0) = d->Q(order & 1); 642 538 r.Q(1) = s->Q((order >> 1) & 1); … … 644 540 } 645 541 646 void OPPROTO glue(op_pshufd, SUFFIX) (void) 647 { 648 Reg r, *d, *s; 649 int order; 650 d = (Reg *)((char *)env + PARAM1); 651 s = (Reg *)((char *)env + PARAM2); 652 order = PARAM3; 542 void glue(helper_pshufd, SUFFIX) (Reg *d, Reg *s, int order) 543 { 544 Reg r; 653 545 r.L(0) = s->L(order & 3); 654 546 r.L(1) = s->L((order >> 2) & 3); … … 658 550 } 659 551 660 void OPPROTO glue(op_pshuflw, SUFFIX) (void) 661 { 662 Reg r, *d, *s; 663 int order; 664 d = (Reg *)((char *)env + PARAM1); 665 s = (Reg *)((char *)env + PARAM2); 666 order = PARAM3; 552 void glue(helper_pshuflw, SUFFIX) (Reg *d, Reg *s, int order) 553 { 554 Reg r; 667 555 r.W(0) = s->W(order & 3); 668 556 r.W(1) = s->W((order >> 2) & 3); … … 673 561 } 674 562 675 void OPPROTO glue(op_pshufhw, SUFFIX) (void) 676 { 677 Reg r, *d, *s; 678 int order; 679 d = (Reg *)((char *)env + PARAM1); 680 s = (Reg *)((char *)env + PARAM2); 681 order = PARAM3; 563 void glue(helper_pshufhw, SUFFIX) (Reg *d, Reg *s, int order) 564 { 565 Reg r; 682 566 r.Q(0) = s->Q(0); 683 567 r.W(4) = s->W(4 + (order & 3)); … … 693 577 /* XXX: not accurate */ 694 578 695 #define SSE_ OP_S(name, F)\696 void OPPROTO op_ ## name ## ps (void)\579 #define SSE_HELPER_S(name, F)\ 580 void helper_ ## name ## ps (Reg *d, Reg *s)\ 697 581 {\ 698 Reg *d, *s;\699 d = (Reg *)((char *)env + PARAM1);\700 s = (Reg *)((char *)env + PARAM2);\701 582 d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\ 702 583 d->XMM_S(1) = F(32, d->XMM_S(1), s->XMM_S(1));\ … … 705 586 }\ 706 587 \ 707 void OPPROTO op_ ## name ## ss (void)\588 void helper_ ## name ## ss (Reg *d, Reg *s)\ 708 589 {\ 709 Reg *d, *s;\710 d = (Reg *)((char *)env + PARAM1);\711 s = (Reg *)((char *)env + PARAM2);\712 590 d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\ 713 591 }\ 714 void OPPROTO op_ ## name ## pd (void)\592 void helper_ ## name ## pd (Reg *d, Reg *s)\ 715 593 {\ 716 Reg *d, *s;\717 d = (Reg *)((char *)env + PARAM1);\718 s = (Reg *)((char *)env + PARAM2);\719 594 d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\ 720 595 d->XMM_D(1) = F(64, d->XMM_D(1), s->XMM_D(1));\ 721 596 }\ 722 597 \ 723 void OPPROTO op_ ## name ## sd (void)\598 void helper_ ## name ## sd (Reg *d, Reg *s)\ 724 599 {\ 725 Reg *d, *s;\726 d = (Reg *)((char *)env + PARAM1);\727 s = (Reg *)((char *)env + PARAM2);\728 600 d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\ 729 601 } … … 737 609 #define FPU_SQRT(size, a, b) float ## size ## _sqrt(b, &env->sse_status) 738 610 739 SSE_ OP_S(add, FPU_ADD)740 SSE_ OP_S(sub, FPU_SUB)741 SSE_ OP_S(mul, FPU_MUL)742 SSE_ OP_S(div, FPU_DIV)743 SSE_ OP_S(min, FPU_MIN)744 SSE_ OP_S(max, FPU_MAX)745 SSE_ OP_S(sqrt, FPU_SQRT)611 SSE_HELPER_S(add, FPU_ADD) 612 SSE_HELPER_S(sub, FPU_SUB) 613 SSE_HELPER_S(mul, FPU_MUL) 614 SSE_HELPER_S(div, FPU_DIV) 615 SSE_HELPER_S(min, FPU_MIN) 616 SSE_HELPER_S(max, FPU_MAX) 617 SSE_HELPER_S(sqrt, FPU_SQRT) 746 618 747 619 748 620 /* float to float conversions */ 749 void OPPROTO op_cvtps2pd(void)621 void helper_cvtps2pd(Reg *d, Reg *s) 750 622 { 751 623 float32 s0, s1; 752 Reg *d, *s;753 d = (Reg *)((char *)env + PARAM1);754 s = (Reg *)((char *)env + PARAM2);755 624 s0 = s->XMM_S(0); 756 625 s1 = s->XMM_S(1); … … 759 628 } 760 629 761 void OPPROTO op_cvtpd2ps(void) 762 { 763 Reg *d, *s; 764 d = (Reg *)((char *)env + PARAM1); 765 s = (Reg *)((char *)env + PARAM2); 630 void helper_cvtpd2ps(Reg *d, Reg *s) 631 { 766 632 d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status); 767 633 d->XMM_S(1) = float64_to_float32(s->XMM_D(1), &env->sse_status); … … 769 635 } 770 636 771 void OPPROTO op_cvtss2sd(void) 772 { 773 Reg *d, *s; 774 d = (Reg *)((char *)env + PARAM1); 775 s = (Reg *)((char *)env + PARAM2); 637 void helper_cvtss2sd(Reg *d, Reg *s) 638 { 776 639 d->XMM_D(0) = float32_to_float64(s->XMM_S(0), &env->sse_status); 777 640 } 778 641 779 void OPPROTO op_cvtsd2ss(void) 780 { 781 Reg *d, *s; 782 d = (Reg *)((char *)env + PARAM1); 783 s = (Reg *)((char *)env + PARAM2); 642 void helper_cvtsd2ss(Reg *d, Reg *s) 643 { 784 644 d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status); 785 645 } 786 646 787 647 /* integer to float */ 788 void OPPROTO op_cvtdq2ps(void) 789 { 790 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 791 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 648 void helper_cvtdq2ps(Reg *d, Reg *s) 649 { 792 650 d->XMM_S(0) = int32_to_float32(s->XMM_L(0), &env->sse_status); 793 651 d->XMM_S(1) = int32_to_float32(s->XMM_L(1), &env->sse_status); … … 796 654 } 797 655 798 void OPPROTO op_cvtdq2pd(void) 799 { 800 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 801 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 656 void helper_cvtdq2pd(Reg *d, Reg *s) 657 { 802 658 int32_t l0, l1; 803 659 l0 = (int32_t)s->XMM_L(0); … … 807 663 } 808 664 809 void OPPROTO op_cvtpi2ps(void) 810 { 811 XMMReg *d = (Reg *)((char *)env + PARAM1); 812 MMXReg *s = (MMXReg *)((char *)env + PARAM2); 665 void helper_cvtpi2ps(XMMReg *d, MMXReg *s) 666 { 813 667 d->XMM_S(0) = int32_to_float32(s->MMX_L(0), &env->sse_status); 814 668 d->XMM_S(1) = int32_to_float32(s->MMX_L(1), &env->sse_status); 815 669 } 816 670 817 void OPPROTO op_cvtpi2pd(void) 818 { 819 XMMReg *d = (Reg *)((char *)env + PARAM1); 820 MMXReg *s = (MMXReg *)((char *)env + PARAM2); 671 void helper_cvtpi2pd(XMMReg *d, MMXReg *s) 672 { 821 673 d->XMM_D(0) = int32_to_float64(s->MMX_L(0), &env->sse_status); 822 674 d->XMM_D(1) = int32_to_float64(s->MMX_L(1), &env->sse_status); 823 675 } 824 676 825 void OPPROTO op_cvtsi2ss(void) 826 { 827 XMMReg *d = (Reg *)((char *)env + PARAM1); 828 d->XMM_S(0) = int32_to_float32(T0, &env->sse_status); 829 } 830 831 void OPPROTO op_cvtsi2sd(void) 832 { 833 XMMReg *d = (Reg *)((char *)env + PARAM1); 834 d->XMM_D(0) = int32_to_float64(T0, &env->sse_status); 677 void helper_cvtsi2ss(XMMReg *d, uint32_t val) 678 { 679 d->XMM_S(0) = int32_to_float32(val, &env->sse_status); 680 } 681 682 void helper_cvtsi2sd(XMMReg *d, uint32_t val) 683 { 684 d->XMM_D(0) = int32_to_float64(val, &env->sse_status); 835 685 } 836 686 837 687 #ifdef TARGET_X86_64 838 void OPPROTO op_cvtsq2ss(void) 839 { 840 XMMReg *d = (Reg *)((char *)env + PARAM1); 841 d->XMM_S(0) = int64_to_float32(T0, &env->sse_status); 842 } 843 844 void OPPROTO op_cvtsq2sd(void) 845 { 846 XMMReg *d = (Reg *)((char *)env + PARAM1); 847 d->XMM_D(0) = int64_to_float64(T0, &env->sse_status); 688 void helper_cvtsq2ss(XMMReg *d, uint64_t val) 689 { 690 d->XMM_S(0) = int64_to_float32(val, &env->sse_status); 691 } 692 693 void helper_cvtsq2sd(XMMReg *d, uint64_t val) 694 { 695 d->XMM_D(0) = int64_to_float64(val, &env->sse_status); 848 696 } 849 697 #endif 850 698 851 699 /* float to integer */ 852 void OPPROTO op_cvtps2dq(void) 853 { 854 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 855 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 700 void helper_cvtps2dq(XMMReg *d, XMMReg *s) 701 { 856 702 d->XMM_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status); 857 703 d->XMM_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status); … … 860 706 } 861 707 862 void OPPROTO op_cvtpd2dq(void) 863 { 864 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 865 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 708 void helper_cvtpd2dq(XMMReg *d, XMMReg *s) 709 { 866 710 d->XMM_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status); 867 711 d->XMM_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status); … … 869 713 } 870 714 871 void OPPROTO op_cvtps2pi(void) 872 { 873 MMXReg *d = (MMXReg *)((char *)env + PARAM1); 874 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 715 void helper_cvtps2pi(MMXReg *d, XMMReg *s) 716 { 875 717 d->MMX_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status); 876 718 d->MMX_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status); 877 719 } 878 720 879 void OPPROTO op_cvtpd2pi(void) 880 { 881 MMXReg *d = (MMXReg *)((char *)env + PARAM1); 882 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 721 void helper_cvtpd2pi(MMXReg *d, XMMReg *s) 722 { 883 723 d->MMX_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status); 884 724 d->MMX_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status); 885 725 } 886 726 887 void OPPROTO op_cvtss2si(void) 888 { 889 XMMReg *s = (XMMReg *)((char *)env + PARAM1); 890 T0 = float32_to_int32(s->XMM_S(0), &env->sse_status); 891 } 892 893 void OPPROTO op_cvtsd2si(void) 894 { 895 XMMReg *s = (XMMReg *)((char *)env + PARAM1); 896 T0 = float64_to_int32(s->XMM_D(0), &env->sse_status); 727 int32_t helper_cvtss2si(XMMReg *s) 728 { 729 return float32_to_int32(s->XMM_S(0), &env->sse_status); 730 } 731 732 int32_t helper_cvtsd2si(XMMReg *s) 733 { 734 return float64_to_int32(s->XMM_D(0), &env->sse_status); 897 735 } 898 736 899 737 #ifdef TARGET_X86_64 900 void OPPROTO op_cvtss2sq(void) 901 { 902 XMMReg *s = (XMMReg *)((char *)env + PARAM1); 903 T0 = float32_to_int64(s->XMM_S(0), &env->sse_status); 904 } 905 906 void OPPROTO op_cvtsd2sq(void) 907 { 908 XMMReg *s = (XMMReg *)((char *)env + PARAM1); 909 T0 = float64_to_int64(s->XMM_D(0), &env->sse_status); 738 int64_t helper_cvtss2sq(XMMReg *s) 739 { 740 return float32_to_int64(s->XMM_S(0), &env->sse_status); 741 } 742 743 int64_t helper_cvtsd2sq(XMMReg *s) 744 { 745 return float64_to_int64(s->XMM_D(0), &env->sse_status); 910 746 } 911 747 #endif 912 748 913 749 /* float to integer truncated */ 914 void OPPROTO op_cvttps2dq(void) 915 { 916 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 917 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 750 void helper_cvttps2dq(XMMReg *d, XMMReg *s) 751 { 918 752 d->XMM_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); 919 753 d->XMM_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status); … … 922 756 } 923 757 924 void OPPROTO op_cvttpd2dq(void) 925 { 926 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 927 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 758 void helper_cvttpd2dq(XMMReg *d, XMMReg *s) 759 { 928 760 d->XMM_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); 929 761 d->XMM_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status); … … 931 763 } 932 764 933 void OPPROTO op_cvttps2pi(void) 934 { 935 MMXReg *d = (MMXReg *)((char *)env + PARAM1); 936 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 765 void helper_cvttps2pi(MMXReg *d, XMMReg *s) 766 { 937 767 d->MMX_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); 938 768 d->MMX_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status); 939 769 } 940 770 941 void OPPROTO op_cvttpd2pi(void) 942 { 943 MMXReg *d = (MMXReg *)((char *)env + PARAM1); 944 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 771 void helper_cvttpd2pi(MMXReg *d, XMMReg *s) 772 { 945 773 d->MMX_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); 946 774 d->MMX_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status); 947 775 } 948 776 949 void OPPROTO op_cvttss2si(void) 950 { 951 XMMReg *s = (XMMReg *)((char *)env + PARAM1); 952 T0 = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); 953 } 954 955 void OPPROTO op_cvttsd2si(void) 956 { 957 XMMReg *s = (XMMReg *)((char *)env + PARAM1); 958 T0 = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); 777 int32_t helper_cvttss2si(XMMReg *s) 778 { 779 return float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status); 780 } 781 782 int32_t helper_cvttsd2si(XMMReg *s) 783 { 784 return float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status); 959 785 } 960 786 961 787 #ifdef TARGET_X86_64 962 void OPPROTO op_cvttss2sq(void) 963 { 964 XMMReg *s = (XMMReg *)((char *)env + PARAM1); 965 T0 = float32_to_int64_round_to_zero(s->XMM_S(0), &env->sse_status); 966 } 967 968 void OPPROTO op_cvttsd2sq(void) 969 { 970 XMMReg *s = (XMMReg *)((char *)env + PARAM1); 971 T0 = float64_to_int64_round_to_zero(s->XMM_D(0), &env->sse_status); 972 } 973 #endif 974 975 void OPPROTO op_rsqrtps(void) 976 { 977 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 978 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 788 int64_t helper_cvttss2sq(XMMReg *s) 789 { 790 return float32_to_int64_round_to_zero(s->XMM_S(0), &env->sse_status); 791 } 792 793 int64_t helper_cvttsd2sq(XMMReg *s) 794 { 795 return float64_to_int64_round_to_zero(s->XMM_D(0), &env->sse_status); 796 } 797 #endif 798 799 void helper_rsqrtps(XMMReg *d, XMMReg *s) 800 { 979 801 d->XMM_S(0) = approx_rsqrt(s->XMM_S(0)); 980 802 d->XMM_S(1) = approx_rsqrt(s->XMM_S(1)); … … 983 805 } 984 806 985 void OPPROTO op_rsqrtss(void) 986 { 987 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 988 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 807 void helper_rsqrtss(XMMReg *d, XMMReg *s) 808 { 989 809 d->XMM_S(0) = approx_rsqrt(s->XMM_S(0)); 990 810 } 991 811 992 void OPPROTO op_rcpps(void) 993 { 994 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 995 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 812 void helper_rcpps(XMMReg *d, XMMReg *s) 813 { 996 814 d->XMM_S(0) = approx_rcp(s->XMM_S(0)); 997 815 d->XMM_S(1) = approx_rcp(s->XMM_S(1)); … … 1000 818 } 1001 819 1002 void OPPROTO op_rcpss(void) 1003 { 1004 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 1005 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 820 void helper_rcpss(XMMReg *d, XMMReg *s) 821 { 1006 822 d->XMM_S(0) = approx_rcp(s->XMM_S(0)); 1007 823 } 1008 824 1009 void OPPROTO op_haddps(void) 1010 { 1011 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 1012 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 825 void helper_haddps(XMMReg *d, XMMReg *s) 826 { 1013 827 XMMReg r; 1014 828 r.XMM_S(0) = d->XMM_S(0) + d->XMM_S(1); … … 1019 833 } 1020 834 1021 void OPPROTO op_haddpd(void) 1022 { 1023 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 1024 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 835 void helper_haddpd(XMMReg *d, XMMReg *s) 836 { 1025 837 XMMReg r; 1026 838 r.XMM_D(0) = d->XMM_D(0) + d->XMM_D(1); … … 1029 841 } 1030 842 1031 void OPPROTO op_hsubps(void) 1032 { 1033 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 1034 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 843 void helper_hsubps(XMMReg *d, XMMReg *s) 844 { 1035 845 XMMReg r; 1036 846 r.XMM_S(0) = d->XMM_S(0) - d->XMM_S(1); … … 1041 851 } 1042 852 1043 void OPPROTO op_hsubpd(void) 1044 { 1045 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 1046 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 853 void helper_hsubpd(XMMReg *d, XMMReg *s) 854 { 1047 855 XMMReg r; 1048 856 r.XMM_D(0) = d->XMM_D(0) - d->XMM_D(1); … … 1051 859 } 1052 860 1053 void OPPROTO op_addsubps(void) 1054 { 1055 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 1056 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 861 void helper_addsubps(XMMReg *d, XMMReg *s) 862 { 1057 863 d->XMM_S(0) = d->XMM_S(0) - s->XMM_S(0); 1058 864 d->XMM_S(1) = d->XMM_S(1) + s->XMM_S(1); … … 1061 867 } 1062 868 1063 void OPPROTO op_addsubpd(void) 1064 { 1065 XMMReg *d = (XMMReg *)((char *)env + PARAM1); 1066 XMMReg *s = (XMMReg *)((char *)env + PARAM2); 869 void helper_addsubpd(XMMReg *d, XMMReg *s) 870 { 1067 871 d->XMM_D(0) = d->XMM_D(0) - s->XMM_D(0); 1068 872 d->XMM_D(1) = d->XMM_D(1) + s->XMM_D(1); … … 1070 874 1071 875 /* XXX: unordered */ 1072 #define SSE_ OP_CMP(name, F)\1073 void OPPROTO op_ ## name ## ps (void)\876 #define SSE_HELPER_CMP(name, F)\ 877 void helper_ ## name ## ps (Reg *d, Reg *s)\ 1074 878 {\ 1075 Reg *d, *s;\1076 d = (Reg *)((char *)env + PARAM1);\1077 s = (Reg *)((char *)env + PARAM2);\1078 879 d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\ 1079 880 d->XMM_L(1) = F(32, d->XMM_S(1), s->XMM_S(1));\ … … 1082 883 }\ 1083 884 \ 1084 void OPPROTO op_ ## name ## ss (void)\885 void helper_ ## name ## ss (Reg *d, Reg *s)\ 1085 886 {\ 1086 Reg *d, *s;\1087 d = (Reg *)((char *)env + PARAM1);\1088 s = (Reg *)((char *)env + PARAM2);\1089 887 d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\ 1090 888 }\ 1091 void OPPROTO op_ ## name ## pd (void)\889 void helper_ ## name ## pd (Reg *d, Reg *s)\ 1092 890 {\ 1093 Reg *d, *s;\1094 d = (Reg *)((char *)env + PARAM1);\1095 s = (Reg *)((char *)env + PARAM2);\1096 891 d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\ 1097 892 d->XMM_Q(1) = F(64, d->XMM_D(1), s->XMM_D(1));\ 1098 893 }\ 1099 894 \ 1100 void OPPROTO op_ ## name ## sd (void)\895 void helper_ ## name ## sd (Reg *d, Reg *s)\ 1101 896 {\ 1102 Reg *d, *s;\1103 d = (Reg *)((char *)env + PARAM1);\1104 s = (Reg *)((char *)env + PARAM2);\1105 897 d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\ 1106 898 } … … 1115 907 #define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1 1116 908 1117 SSE_ OP_CMP(cmpeq, FPU_CMPEQ)1118 SSE_ OP_CMP(cmplt, FPU_CMPLT)1119 SSE_ OP_CMP(cmple, FPU_CMPLE)1120 SSE_ OP_CMP(cmpunord, FPU_CMPUNORD)1121 SSE_ OP_CMP(cmpneq, FPU_CMPNEQ)1122 SSE_ OP_CMP(cmpnlt, FPU_CMPNLT)1123 SSE_ OP_CMP(cmpnle, FPU_CMPNLE)1124 SSE_ OP_CMP(cmpord, FPU_CMPORD)909 SSE_HELPER_CMP(cmpeq, FPU_CMPEQ) 910 SSE_HELPER_CMP(cmplt, FPU_CMPLT) 911 SSE_HELPER_CMP(cmple, FPU_CMPLE) 912 SSE_HELPER_CMP(cmpunord, FPU_CMPUNORD) 913 SSE_HELPER_CMP(cmpneq, FPU_CMPNEQ) 914 SSE_HELPER_CMP(cmpnlt, FPU_CMPNLT) 915 SSE_HELPER_CMP(cmpnle, FPU_CMPNLE) 916 SSE_HELPER_CMP(cmpord, FPU_CMPORD) 1125 917 1126 918 const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; 1127 919 1128 void OPPROTO op_ucomiss(void)920 void helper_ucomiss(Reg *d, Reg *s) 1129 921 { 1130 922 int ret; 1131 923 float32 s0, s1; 1132 Reg *d, *s;1133 d = (Reg *)((char *)env + PARAM1);1134 s = (Reg *)((char *)env + PARAM2);1135 924 1136 925 s0 = d->XMM_S(0); … … 1141 930 } 1142 931 1143 void OPPROTO op_comiss(void)932 void helper_comiss(Reg *d, Reg *s) 1144 933 { 1145 934 int ret; 1146 935 float32 s0, s1; 1147 Reg *d, *s;1148 d = (Reg *)((char *)env + PARAM1);1149 s = (Reg *)((char *)env + PARAM2);1150 936 1151 937 s0 = d->XMM_S(0); … … 1156 942 } 1157 943 1158 void OPPROTO op_ucomisd(void)944 void helper_ucomisd(Reg *d, Reg *s) 1159 945 { 1160 946 int ret; 1161 947 float64 d0, d1; 1162 Reg *d, *s;1163 d = (Reg *)((char *)env + PARAM1);1164 s = (Reg *)((char *)env + PARAM2);1165 948 1166 949 d0 = d->XMM_D(0); … … 1171 954 } 1172 955 1173 void OPPROTO op_comisd(void)956 void helper_comisd(Reg *d, Reg *s) 1174 957 { 1175 958 int ret; 1176 959 float64 d0, d1; 1177 Reg *d, *s;1178 d = (Reg *)((char *)env + PARAM1);1179 s = (Reg *)((char *)env + PARAM2);1180 960 1181 961 d0 = d->XMM_D(0); … … 1186 966 } 1187 967 1188 void OPPROTO op_movmskps(void)968 uint32_t helper_movmskps(Reg *s) 1189 969 { 1190 970 int b0, b1, b2, b3; 1191 Reg *s;1192 s = (Reg *)((char *)env + PARAM1);1193 971 b0 = s->XMM_L(0) >> 31; 1194 972 b1 = s->XMM_L(1) >> 31; 1195 973 b2 = s->XMM_L(2) >> 31; 1196 974 b3 = s->XMM_L(3) >> 31; 1197 T0 =b0 | (b1 << 1) | (b2 << 2) | (b3 << 3);1198 } 1199 1200 void OPPROTO op_movmskpd(void)975 return b0 | (b1 << 1) | (b2 << 2) | (b3 << 3); 976 } 977 978 uint32_t helper_movmskpd(Reg *s) 1201 979 { 1202 980 int b0, b1; 1203 Reg *s;1204 s = (Reg *)((char *)env + PARAM1);1205 981 b0 = s->XMM_L(1) >> 31; 1206 982 b1 = s->XMM_L(3) >> 31; 1207 T0 = b0 | (b1 << 1); 1208 } 1209 1210 #endif 1211 1212 void OPPROTO glue(op_pmovmskb, SUFFIX)(void) 1213 { 1214 Reg *s; 1215 s = (Reg *)((char *)env + PARAM1); 1216 T0 = 0; 1217 T0 |= (s->XMM_B(0) >> 7); 1218 T0 |= (s->XMM_B(1) >> 6) & 0x02; 1219 T0 |= (s->XMM_B(2) >> 5) & 0x04; 1220 T0 |= (s->XMM_B(3) >> 4) & 0x08; 1221 T0 |= (s->XMM_B(4) >> 3) & 0x10; 1222 T0 |= (s->XMM_B(5) >> 2) & 0x20; 1223 T0 |= (s->XMM_B(6) >> 1) & 0x40; 1224 T0 |= (s->XMM_B(7)) & 0x80; 1225 #if SHIFT == 1 1226 T0 |= (s->XMM_B(8) << 1) & 0x0100; 1227 T0 |= (s->XMM_B(9) << 2) & 0x0200; 1228 T0 |= (s->XMM_B(10) << 3) & 0x0400; 1229 T0 |= (s->XMM_B(11) << 4) & 0x0800; 1230 T0 |= (s->XMM_B(12) << 5) & 0x1000; 1231 T0 |= (s->XMM_B(13) << 6) & 0x2000; 1232 T0 |= (s->XMM_B(14) << 7) & 0x4000; 1233 T0 |= (s->XMM_B(15) << 8) & 0x8000; 1234 #endif 1235 } 1236 1237 void OPPROTO glue(op_pinsrw, SUFFIX) (void) 1238 { 1239 Reg *d = (Reg *)((char *)env + PARAM1); 1240 int pos = PARAM2; 1241 1242 d->W(pos) = T0; 1243 } 1244 1245 void OPPROTO glue(op_pextrw, SUFFIX) (void) 1246 { 1247 Reg *s = (Reg *)((char *)env + PARAM1); 1248 int pos = PARAM2; 1249 1250 T0 = s->W(pos); 1251 } 1252 1253 void OPPROTO glue(op_packsswb, SUFFIX) (void) 1254 { 1255 Reg r, *d, *s; 1256 d = (Reg *)((char *)env + PARAM1); 1257 s = (Reg *)((char *)env + PARAM2); 983 return b0 | (b1 << 1); 984 } 985 986 #endif 987 988 uint32_t glue(helper_pmovmskb, SUFFIX)(Reg *s) 989 { 990 uint32_t val; 991 val = 0; 992 val |= (s->XMM_B(0) >> 7); 993 val |= (s->XMM_B(1) >> 6) & 0x02; 994 val |= (s->XMM_B(2) >> 5) & 0x04; 995 val |= (s->XMM_B(3) >> 4) & 0x08; 996 val |= (s->XMM_B(4) >> 3) & 0x10; 997 val |= (s->XMM_B(5) >> 2) & 0x20; 998 val |= (s->XMM_B(6) >> 1) & 0x40; 999 val |= (s->XMM_B(7)) & 0x80; 1000 #if SHIFT == 1 1001 val |= (s->XMM_B(8) << 1) & 0x0100; 1002 val |= (s->XMM_B(9) << 2) & 0x0200; 1003 val |= (s->XMM_B(10) << 3) & 0x0400; 1004 val |= (s->XMM_B(11) << 4) & 0x0800; 1005 val |= (s->XMM_B(12) << 5) & 0x1000; 1006 val |= (s->XMM_B(13) << 6) & 0x2000; 1007 val |= (s->XMM_B(14) << 7) & 0x4000; 1008 val |= (s->XMM_B(15) << 8) & 0x8000; 1009 #endif 1010 return val; 1011 } 1012 1013 void glue(helper_packsswb, SUFFIX) (Reg *d, Reg *s) 1014 { 1015 Reg r; 1258 1016 1259 1017 r.B(0) = satsb((int16_t)d->W(0)); … … 1280 1038 } 1281 1039 1282 void OPPROTO glue(op_packuswb, SUFFIX) (void) 1283 { 1284 Reg r, *d, *s; 1285 d = (Reg *)((char *)env + PARAM1); 1286 s = (Reg *)((char *)env + PARAM2); 1040 void glue(helper_packuswb, SUFFIX) (Reg *d, Reg *s) 1041 { 1042 Reg r; 1287 1043 1288 1044 r.B(0) = satub((int16_t)d->W(0)); … … 1309 1065 } 1310 1066 1311 void OPPROTO glue(op_packssdw, SUFFIX) (void) 1312 { 1313 Reg r, *d, *s; 1314 d = (Reg *)((char *)env + PARAM1); 1315 s = (Reg *)((char *)env + PARAM2); 1067 void glue(helper_packssdw, SUFFIX) (Reg *d, Reg *s) 1068 { 1069 Reg r; 1316 1070 1317 1071 r.W(0) = satsw(d->L(0)); … … 1332 1086 #define UNPCK_OP(base_name, base) \ 1333 1087 \ 1334 void OPPROTO glue(op_punpck ## base_name ## bw, SUFFIX) (void) \1088 void glue(helper_punpck ## base_name ## bw, SUFFIX) (Reg *d, Reg *s) \ 1335 1089 { \ 1336 Reg r, *d, *s; \ 1337 d = (Reg *)((char *)env + PARAM1); \ 1338 s = (Reg *)((char *)env + PARAM2); \ 1090 Reg r; \ 1339 1091 \ 1340 1092 r.B(0) = d->B((base << (SHIFT + 2)) + 0); \ … … 1359 1111 } \ 1360 1112 \ 1361 void OPPROTO glue(op_punpck ## base_name ## wd, SUFFIX) (void) \1113 void glue(helper_punpck ## base_name ## wd, SUFFIX) (Reg *d, Reg *s) \ 1362 1114 { \ 1363 Reg r, *d, *s; \ 1364 d = (Reg *)((char *)env + PARAM1); \ 1365 s = (Reg *)((char *)env + PARAM2); \ 1115 Reg r; \ 1366 1116 \ 1367 1117 r.W(0) = d->W((base << (SHIFT + 1)) + 0); \ … … 1378 1128 } \ 1379 1129 \ 1380 void OPPROTO glue(op_punpck ## base_name ## dq, SUFFIX) (void) \1130 void glue(helper_punpck ## base_name ## dq, SUFFIX) (Reg *d, Reg *s) \ 1381 1131 { \ 1382 Reg r, *d, *s; \ 1383 d = (Reg *)((char *)env + PARAM1); \ 1384 s = (Reg *)((char *)env + PARAM2); \ 1132 Reg r; \ 1385 1133 \ 1386 1134 r.L(0) = d->L((base << SHIFT) + 0); \ … … 1394 1142 \ 1395 1143 XMM_ONLY( \ 1396 void OPPROTO glue(op_punpck ## base_name ## qdq, SUFFIX) (void) \1144 void glue(helper_punpck ## base_name ## qdq, SUFFIX) (Reg *d, Reg *s) \ 1397 1145 { \ 1398 Reg r, *d, *s; \ 1399 d = (Reg *)((char *)env + PARAM1); \ 1400 s = (Reg *)((char *)env + PARAM2); \ 1146 Reg r; \ 1401 1147 \ 1402 1148 r.Q(0) = d->Q(base); \ … … 1408 1154 UNPCK_OP(l, 0) 1409 1155 UNPCK_OP(h, 1) 1156 1157 /* 3DNow! float ops */ 1158 #if SHIFT == 0 1159 void helper_pi2fd(MMXReg *d, MMXReg *s) 1160 { 1161 d->MMX_S(0) = int32_to_float32(s->MMX_L(0), &env->mmx_status); 1162 d->MMX_S(1) = int32_to_float32(s->MMX_L(1), &env->mmx_status); 1163 } 1164 1165 void helper_pi2fw(MMXReg *d, MMXReg *s) 1166 { 1167 d->MMX_S(0) = int32_to_float32((int16_t)s->MMX_W(0), &env->mmx_status); 1168 d->MMX_S(1) = int32_to_float32((int16_t)s->MMX_W(2), &env->mmx_status); 1169 } 1170 1171 void helper_pf2id(MMXReg *d, MMXReg *s) 1172 { 1173 d->MMX_L(0) = float32_to_int32_round_to_zero(s->MMX_S(0), &env->mmx_status); 1174 d->MMX_L(1) = float32_to_int32_round_to_zero(s->MMX_S(1), &env->mmx_status); 1175 } 1176 1177 void helper_pf2iw(MMXReg *d, MMXReg *s) 1178 { 1179 d->MMX_L(0) = satsw(float32_to_int32_round_to_zero(s->MMX_S(0), &env->mmx_status)); 1180 d->MMX_L(1) = satsw(float32_to_int32_round_to_zero(s->MMX_S(1), &env->mmx_status)); 1181 } 1182 1183 void helper_pfacc(MMXReg *d, MMXReg *s) 1184 { 1185 MMXReg r; 1186 r.MMX_S(0) = float32_add(d->MMX_S(0), d->MMX_S(1), &env->mmx_status); 1187 r.MMX_S(1) = float32_add(s->MMX_S(0), s->MMX_S(1), &env->mmx_status); 1188 *d = r; 1189 } 1190 1191 void helper_pfadd(MMXReg *d, MMXReg *s) 1192 { 1193 d->MMX_S(0) = float32_add(d->MMX_S(0), s->MMX_S(0), &env->mmx_status); 1194 d->MMX_S(1) = float32_add(d->MMX_S(1), s->MMX_S(1), &env->mmx_status); 1195 } 1196 1197 void helper_pfcmpeq(MMXReg *d, MMXReg *s) 1198 { 1199 d->MMX_L(0) = float32_eq(d->MMX_S(0), s->MMX_S(0), &env->mmx_status) ? -1 : 0; 1200 d->MMX_L(1) = float32_eq(d->MMX_S(1), s->MMX_S(1), &env->mmx_status) ? -1 : 0; 1201 } 1202 1203 void helper_pfcmpge(MMXReg *d, MMXReg *s) 1204 { 1205 d->MMX_L(0) = float32_le(s->MMX_S(0), d->MMX_S(0), &env->mmx_status) ? -1 : 0; 1206 d->MMX_L(1) = float32_le(s->MMX_S(1), d->MMX_S(1), &env->mmx_status) ? -1 : 0; 1207 } 1208 1209 void helper_pfcmpgt(MMXReg *d, MMXReg *s) 1210 { 1211 d->MMX_L(0) = float32_lt(s->MMX_S(0), d->MMX_S(0), &env->mmx_status) ? -1 : 0; 1212 d->MMX_L(1) = float32_lt(s->MMX_S(1), d->MMX_S(1), &env->mmx_status) ? -1 : 0; 1213 } 1214 1215 void helper_pfmax(MMXReg *d, MMXReg *s) 1216 { 1217 if (float32_lt(d->MMX_S(0), s->MMX_S(0), &env->mmx_status)) 1218 d->MMX_S(0) = s->MMX_S(0); 1219 if (float32_lt(d->MMX_S(1), s->MMX_S(1), &env->mmx_status)) 1220 d->MMX_S(1) = s->MMX_S(1); 1221 } 1222 1223 void helper_pfmin(MMXReg *d, MMXReg *s) 1224 { 1225 if (float32_lt(s->MMX_S(0), d->MMX_S(0), &env->mmx_status)) 1226 d->MMX_S(0) = s->MMX_S(0); 1227 if (float32_lt(s->MMX_S(1), d->MMX_S(1), &env->mmx_status)) 1228 d->MMX_S(1) = s->MMX_S(1); 1229 } 1230 1231 void helper_pfmul(MMXReg *d, MMXReg *s) 1232 { 1233 d->MMX_S(0) = float32_mul(d->MMX_S(0), s->MMX_S(0), &env->mmx_status); 1234 d->MMX_S(1) = float32_mul(d->MMX_S(1), s->MMX_S(1), &env->mmx_status); 1235 } 1236 1237 void helper_pfnacc(MMXReg *d, MMXReg *s) 1238 { 1239 MMXReg r; 1240 r.MMX_S(0) = float32_sub(d->MMX_S(0), d->MMX_S(1), &env->mmx_status); 1241 r.MMX_S(1) = float32_sub(s->MMX_S(0), s->MMX_S(1), &env->mmx_status); 1242 *d = r; 1243 } 1244 1245 void helper_pfpnacc(MMXReg *d, MMXReg *s) 1246 { 1247 MMXReg r; 1248 r.MMX_S(0) = float32_sub(d->MMX_S(0), d->MMX_S(1), &env->mmx_status); 1249 r.MMX_S(1) = float32_add(s->MMX_S(0), s->MMX_S(1), &env->mmx_status); 1250 *d = r; 1251 } 1252 1253 void helper_pfrcp(MMXReg *d, MMXReg *s) 1254 { 1255 d->MMX_S(0) = approx_rcp(s->MMX_S(0)); 1256 d->MMX_S(1) = d->MMX_S(0); 1257 } 1258 1259 void helper_pfrsqrt(MMXReg *d, MMXReg *s) 1260 { 1261 d->MMX_L(1) = s->MMX_L(0) & 0x7fffffff; 1262 d->MMX_S(1) = approx_rsqrt(d->MMX_S(1)); 1263 d->MMX_L(1) |= s->MMX_L(0) & 0x80000000; 1264 d->MMX_L(0) = d->MMX_L(1); 1265 } 1266 1267 void helper_pfsub(MMXReg *d, MMXReg *s) 1268 { 1269 d->MMX_S(0) = float32_sub(d->MMX_S(0), s->MMX_S(0), &env->mmx_status); 1270 d->MMX_S(1) = float32_sub(d->MMX_S(1), s->MMX_S(1), &env->mmx_status); 1271 } 1272 1273 void helper_pfsubr(MMXReg *d, MMXReg *s) 1274 { 1275 d->MMX_S(0) = float32_sub(s->MMX_S(0), d->MMX_S(0), &env->mmx_status); 1276 d->MMX_S(1) = float32_sub(s->MMX_S(1), d->MMX_S(1), &env->mmx_status); 1277 } 1278 1279 void helper_pswapd(MMXReg *d, MMXReg *s) 1280 { 1281 MMXReg r; 1282 r.MMX_L(0) = s->MMX_L(1); 1283 r.MMX_L(1) = s->MMX_L(0); 1284 *d = r; 1285 } 1286 #endif 1287 1288 /* SSSE3 op helpers */ 1289 void glue(helper_pshufb, SUFFIX) (Reg *d, Reg *s) 1290 { 1291 int i; 1292 Reg r; 1293 1294 for (i = 0; i < (8 << SHIFT); i++) 1295 r.B(i) = (s->B(i) & 0x80) ? 0 : (d->B(s->B(i) & ((8 << SHIFT) - 1))); 1296 1297 *d = r; 1298 } 1299 1300 void glue(helper_phaddw, SUFFIX) (Reg *d, Reg *s) 1301 { 1302 d->W(0) = (int16_t)d->W(0) + (int16_t)d->W(1); 1303 d->W(1) = (int16_t)d->W(2) + (int16_t)d->W(3); 1304 XMM_ONLY(d->W(2) = (int16_t)d->W(4) + (int16_t)d->W(5)); 1305 XMM_ONLY(d->W(3) = (int16_t)d->W(6) + (int16_t)d->W(7)); 1306 d->W((2 << SHIFT) + 0) = (int16_t)s->W(0) + (int16_t)s->W(1); 1307 d->W((2 << SHIFT) + 1) = (int16_t)s->W(2) + (int16_t)s->W(3); 1308 XMM_ONLY(d->W(6) = (int16_t)s->W(4) + (int16_t)s->W(5)); 1309 XMM_ONLY(d->W(7) = (int16_t)s->W(6) + (int16_t)s->W(7)); 1310 } 1311 1312 void glue(helper_phaddd, SUFFIX) (Reg *d, Reg *s) 1313 { 1314 d->L(0) = (int32_t)d->L(0) + (int32_t)d->L(1); 1315 XMM_ONLY(d->L(1) = (int32_t)d->L(2) + (int32_t)d->L(3)); 1316 d->L((1 << SHIFT) + 0) = (int32_t)s->L(0) + (int32_t)s->L(1); 1317 XMM_ONLY(d->L(3) = (int32_t)s->L(2) + (int32_t)s->L(3)); 1318 } 1319 1320 void glue(helper_phaddsw, SUFFIX) (Reg *d, Reg *s) 1321 { 1322 d->W(0) = satsw((int16_t)d->W(0) + (int16_t)d->W(1)); 1323 d->W(1) = satsw((int16_t)d->W(2) + (int16_t)d->W(3)); 1324 XMM_ONLY(d->W(2) = satsw((int16_t)d->W(4) + (int16_t)d->W(5))); 1325 XMM_ONLY(d->W(3) = satsw((int16_t)d->W(6) + (int16_t)d->W(7))); 1326 d->W((2 << SHIFT) + 0) = satsw((int16_t)s->W(0) + (int16_t)s->W(1)); 1327 d->W((2 << SHIFT) + 1) = satsw((int16_t)s->W(2) + (int16_t)s->W(3)); 1328 XMM_ONLY(d->W(6) = satsw((int16_t)s->W(4) + (int16_t)s->W(5))); 1329 XMM_ONLY(d->W(7) = satsw((int16_t)s->W(6) + (int16_t)s->W(7))); 1330 } 1331 1332 void glue(helper_pmaddubsw, SUFFIX) (Reg *d, Reg *s) 1333 { 1334 d->W(0) = satsw((int8_t)s->B( 0) * (uint8_t)d->B( 0) + 1335 (int8_t)s->B( 1) * (uint8_t)d->B( 1)); 1336 d->W(1) = satsw((int8_t)s->B( 2) * (uint8_t)d->B( 2) + 1337 (int8_t)s->B( 3) * (uint8_t)d->B( 3)); 1338 d->W(2) = satsw((int8_t)s->B( 4) * (uint8_t)d->B( 4) + 1339 (int8_t)s->B( 5) * (uint8_t)d->B( 5)); 1340 d->W(3) = satsw((int8_t)s->B( 6) * (uint8_t)d->B( 6) + 1341 (int8_t)s->B( 7) * (uint8_t)d->B( 7)); 1342 #if SHIFT == 1 1343 d->W(4) = satsw((int8_t)s->B( 8) * (uint8_t)d->B( 8) + 1344 (int8_t)s->B( 9) * (uint8_t)d->B( 9)); 1345 d->W(5) = satsw((int8_t)s->B(10) * (uint8_t)d->B(10) + 1346 (int8_t)s->B(11) * (uint8_t)d->B(11)); 1347 d->W(6) = satsw((int8_t)s->B(12) * (uint8_t)d->B(12) + 1348 (int8_t)s->B(13) * (uint8_t)d->B(13)); 1349 d->W(7) = satsw((int8_t)s->B(14) * (uint8_t)d->B(14) + 1350 (int8_t)s->B(15) * (uint8_t)d->B(15)); 1351 #endif 1352 } 1353 1354 void glue(helper_phsubw, SUFFIX) (Reg *d, Reg *s) 1355 { 1356 d->W(0) = (int16_t)d->W(0) - (int16_t)d->W(1); 1357 d->W(1) = (int16_t)d->W(2) - (int16_t)d->W(3); 1358 XMM_ONLY(d->W(2) = (int16_t)d->W(4) - (int16_t)d->W(5)); 1359 XMM_ONLY(d->W(3) = (int16_t)d->W(6) - (int16_t)d->W(7)); 1360 d->W((2 << SHIFT) + 0) = (int16_t)s->W(0) - (int16_t)s->W(1); 1361 d->W((2 << SHIFT) + 1) = (int16_t)s->W(2) - (int16_t)s->W(3); 1362 XMM_ONLY(d->W(6) = (int16_t)s->W(4) - (int16_t)s->W(5)); 1363 XMM_ONLY(d->W(7) = (int16_t)s->W(6) - (int16_t)s->W(7)); 1364 } 1365 1366 void glue(helper_phsubd, SUFFIX) (Reg *d, Reg *s) 1367 { 1368 d->L(0) = (int32_t)d->L(0) - (int32_t)d->L(1); 1369 XMM_ONLY(d->L(1) = (int32_t)d->L(2) - (int32_t)d->L(3)); 1370 d->L((1 << SHIFT) + 0) = (int32_t)s->L(0) - (int32_t)s->L(1); 1371 XMM_ONLY(d->L(3) = (int32_t)s->L(2) - (int32_t)s->L(3)); 1372 } 1373 1374 void glue(helper_phsubsw, SUFFIX) (Reg *d, Reg *s) 1375 { 1376 d->W(0) = satsw((int16_t)d->W(0) - (int16_t)d->W(1)); 1377 d->W(1) = satsw((int16_t)d->W(2) - (int16_t)d->W(3)); 1378 XMM_ONLY(d->W(2) = satsw((int16_t)d->W(4) - (int16_t)d->W(5))); 1379 XMM_ONLY(d->W(3) = satsw((int16_t)d->W(6) - (int16_t)d->W(7))); 1380 d->W((2 << SHIFT) + 0) = satsw((int16_t)s->W(0) - (int16_t)s->W(1)); 1381 d->W((2 << SHIFT) + 1) = satsw((int16_t)s->W(2) - (int16_t)s->W(3)); 1382 XMM_ONLY(d->W(6) = satsw((int16_t)s->W(4) - (int16_t)s->W(5))); 1383 XMM_ONLY(d->W(7) = satsw((int16_t)s->W(6) - (int16_t)s->W(7))); 1384 } 1385 1386 #define FABSB(_, x) x > INT8_MAX ? -(int8_t ) x : x 1387 #define FABSW(_, x) x > INT16_MAX ? -(int16_t) x : x 1388 #define FABSL(_, x) x > INT32_MAX ? -(int32_t) x : x 1389 SSE_HELPER_B(helper_pabsb, FABSB) 1390 SSE_HELPER_W(helper_pabsw, FABSW) 1391 SSE_HELPER_L(helper_pabsd, FABSL) 1392 1393 #define FMULHRSW(d, s) ((int16_t) d * (int16_t) s + 0x4000) >> 15 1394 SSE_HELPER_W(helper_pmulhrsw, FMULHRSW) 1395 1396 #define FSIGNB(d, s) s <= INT8_MAX ? s ? d : 0 : -(int8_t ) d 1397 #define FSIGNW(d, s) s <= INT16_MAX ? s ? d : 0 : -(int16_t) d 1398 #define FSIGNL(d, s) s <= INT32_MAX ? s ? d : 0 : -(int32_t) d 1399 SSE_HELPER_B(helper_psignb, FSIGNB) 1400 SSE_HELPER_W(helper_psignw, FSIGNW) 1401 SSE_HELPER_L(helper_psignd, FSIGNL) 1402 1403 void glue(helper_palignr, SUFFIX) (Reg *d, Reg *s, int32_t shift) 1404 { 1405 Reg r; 1406 1407 /* XXX could be checked during translation */ 1408 if (shift >= (16 << SHIFT)) { 1409 r.Q(0) = 0; 1410 XMM_ONLY(r.Q(1) = 0); 1411 } else { 1412 shift <<= 3; 1413 #define SHR(v, i) (i < 64 && i > -64 ? i > 0 ? v >> (i) : (v << -(i)) : 0) 1414 #if SHIFT == 0 1415 r.Q(0) = SHR(s->Q(0), shift - 0) | 1416 SHR(d->Q(0), shift - 64); 1417 #else 1418 r.Q(0) = SHR(s->Q(0), shift - 0) | 1419 SHR(s->Q(1), shift - 64) | 1420 SHR(d->Q(0), shift - 128) | 1421 SHR(d->Q(1), shift - 192); 1422 r.Q(1) = SHR(s->Q(0), shift + 64) | 1423 SHR(s->Q(1), shift - 0) | 1424 SHR(d->Q(0), shift - 64) | 1425 SHR(d->Q(1), shift - 128); 1426 #endif 1427 #undef SHR 1428 } 1429 1430 *d = r; 1431 } 1432 1433 #define XMM0 env->xmm_regs[0] 1434 1435 #if SHIFT == 1 1436 #define SSE_HELPER_V(name, elem, num, F)\ 1437 void glue(name, SUFFIX) (Reg *d, Reg *s)\ 1438 {\ 1439 d->elem(0) = F(d->elem(0), s->elem(0), XMM0.elem(0));\ 1440 d->elem(1) = F(d->elem(1), s->elem(1), XMM0.elem(1));\ 1441 if (num > 2) {\ 1442 d->elem(2) = F(d->elem(2), s->elem(2), XMM0.elem(2));\ 1443 d->elem(3) = F(d->elem(3), s->elem(3), XMM0.elem(3));\ 1444 if (num > 4) {\ 1445 d->elem(4) = F(d->elem(4), s->elem(4), XMM0.elem(4));\ 1446 d->elem(5) = F(d->elem(5), s->elem(5), XMM0.elem(5));\ 1447 d->elem(6) = F(d->elem(6), s->elem(6), XMM0.elem(6));\ 1448 d->elem(7) = F(d->elem(7), s->elem(7), XMM0.elem(7));\ 1449 if (num > 8) {\ 1450 d->elem(8) = F(d->elem(8), s->elem(8), XMM0.elem(8));\ 1451 d->elem(9) = F(d->elem(9), s->elem(9), XMM0.elem(9));\ 1452 d->elem(10) = F(d->elem(10), s->elem(10), XMM0.elem(10));\ 1453 d->elem(11) = F(d->elem(11), s->elem(11), XMM0.elem(11));\ 1454 d->elem(12) = F(d->elem(12), s->elem(12), XMM0.elem(12));\ 1455 d->elem(13) = F(d->elem(13), s->elem(13), XMM0.elem(13));\ 1456 d->elem(14) = F(d->elem(14), s->elem(14), XMM0.elem(14));\ 1457 d->elem(15) = F(d->elem(15), s->elem(15), XMM0.elem(15));\ 1458 }\ 1459 }\ 1460 }\ 1461 } 1462 1463 #define SSE_HELPER_I(name, elem, num, F)\ 1464 void glue(name, SUFFIX) (Reg *d, Reg *s, uint32_t imm)\ 1465 {\ 1466 d->elem(0) = F(d->elem(0), s->elem(0), ((imm >> 0) & 1));\ 1467 d->elem(1) = F(d->elem(1), s->elem(1), ((imm >> 1) & 1));\ 1468 if (num > 2) {\ 1469 d->elem(2) = F(d->elem(2), s->elem(2), ((imm >> 2) & 1));\ 1470 d->elem(3) = F(d->elem(3), s->elem(3), ((imm >> 3) & 1));\ 1471 if (num > 4) {\ 1472 d->elem(4) = F(d->elem(4), s->elem(4), ((imm >> 4) & 1));\ 1473 d->elem(5) = F(d->elem(5), s->elem(5), ((imm >> 5) & 1));\ 1474 d->elem(6) = F(d->elem(6), s->elem(6), ((imm >> 6) & 1));\ 1475 d->elem(7) = F(d->elem(7), s->elem(7), ((imm >> 7) & 1));\ 1476 if (num > 8) {\ 1477 d->elem(8) = F(d->elem(8), s->elem(8), ((imm >> 8) & 1));\ 1478 d->elem(9) = F(d->elem(9), s->elem(9), ((imm >> 9) & 1));\ 1479 d->elem(10) = F(d->elem(10), s->elem(10), ((imm >> 10) & 1));\ 1480 d->elem(11) = F(d->elem(11), s->elem(11), ((imm >> 11) & 1));\ 1481 d->elem(12) = F(d->elem(12), s->elem(12), ((imm >> 12) & 1));\ 1482 d->elem(13) = F(d->elem(13), s->elem(13), ((imm >> 13) & 1));\ 1483 d->elem(14) = F(d->elem(14), s->elem(14), ((imm >> 14) & 1));\ 1484 d->elem(15) = F(d->elem(15), s->elem(15), ((imm >> 15) & 1));\ 1485 }\ 1486 }\ 1487 }\ 1488 } 1489 1490 /* SSE4.1 op helpers */ 1491 #define FBLENDVB(d, s, m) (m & 0x80) ? s : d 1492 #define FBLENDVPS(d, s, m) (m & 0x80000000) ? s : d 1493 #define FBLENDVPD(d, s, m) (m & 0x8000000000000000LL) ? s : d 1494 SSE_HELPER_V(helper_pblendvb, B, 16, FBLENDVB) 1495 SSE_HELPER_V(helper_blendvps, L, 4, FBLENDVPS) 1496 SSE_HELPER_V(helper_blendvpd, Q, 2, FBLENDVPD) 1497 1498 void glue(helper_ptest, SUFFIX) (Reg *d, Reg *s) 1499 { 1500 uint64_t zf = (s->Q(0) & d->Q(0)) | (s->Q(1) & d->Q(1)); 1501 uint64_t cf = (s->Q(0) & ~d->Q(0)) | (s->Q(1) & ~d->Q(1)); 1502 1503 CC_SRC = (zf ? 0 : CC_Z) | (cf ? 0 : CC_C); 1504 } 1505 1506 #define SSE_HELPER_F(name, elem, num, F)\ 1507 void glue(name, SUFFIX) (Reg *d, Reg *s)\ 1508 {\ 1509 d->elem(0) = F(0);\ 1510 d->elem(1) = F(1);\ 1511 d->elem(2) = F(2);\ 1512 d->elem(3) = F(3);\ 1513 if (num > 3) {\ 1514 d->elem(4) = F(4);\ 1515 d->elem(5) = F(5);\ 1516 if (num > 5) {\ 1517 d->elem(6) = F(6);\ 1518 d->elem(7) = F(7);\ 1519 }\ 1520 }\ 1521 } 1522 1523 SSE_HELPER_F(helper_pmovsxbw, W, 8, (int8_t) s->B) 1524 SSE_HELPER_F(helper_pmovsxbd, L, 4, (int8_t) s->B) 1525 SSE_HELPER_F(helper_pmovsxbq, Q, 2, (int8_t) s->B) 1526 SSE_HELPER_F(helper_pmovsxwd, L, 4, (int16_t) s->W) 1527 SSE_HELPER_F(helper_pmovsxwq, Q, 2, (int16_t) s->W) 1528 SSE_HELPER_F(helper_pmovsxdq, Q, 2, (int32_t) s->L) 1529 SSE_HELPER_F(helper_pmovzxbw, W, 8, s->B) 1530 SSE_HELPER_F(helper_pmovzxbd, L, 4, s->B) 1531 SSE_HELPER_F(helper_pmovzxbq, Q, 2, s->B) 1532 SSE_HELPER_F(helper_pmovzxwd, L, 4, s->W) 1533 SSE_HELPER_F(helper_pmovzxwq, Q, 2, s->W) 1534 SSE_HELPER_F(helper_pmovzxdq, Q, 2, s->L) 1535 1536 void glue(helper_pmuldq, SUFFIX) (Reg *d, Reg *s) 1537 { 1538 d->Q(0) = (int64_t) (int32_t) d->L(0) * (int32_t) s->L(0); 1539 d->Q(1) = (int64_t) (int32_t) d->L(2) * (int32_t) s->L(2); 1540 } 1541 1542 #define FCMPEQQ(d, s) d == s ? -1 : 0 1543 SSE_HELPER_Q(helper_pcmpeqq, FCMPEQQ) 1544 1545 void glue(helper_packusdw, SUFFIX) (Reg *d, Reg *s) 1546 { 1547 d->W(0) = satuw((int32_t) d->L(0)); 1548 d->W(1) = satuw((int32_t) d->L(1)); 1549 d->W(2) = satuw((int32_t) d->L(2)); 1550 d->W(3) = satuw((int32_t) d->L(3)); 1551 d->W(4) = satuw((int32_t) s->L(0)); 1552 d->W(5) = satuw((int32_t) s->L(1)); 1553 d->W(6) = satuw((int32_t) s->L(2)); 1554 d->W(7) = satuw((int32_t) s->L(3)); 1555 } 1556 1557 #define FMINSB(d, s) MIN((int8_t) d, (int8_t) s) 1558 #define FMINSD(d, s) MIN((int32_t) d, (int32_t) s) 1559 #define FMAXSB(d, s) MAX((int8_t) d, (int8_t) s) 1560 #define FMAXSD(d, s) MAX((int32_t) d, (int32_t) s) 1561 SSE_HELPER_B(helper_pminsb, FMINSB) 1562 SSE_HELPER_L(helper_pminsd, FMINSD) 1563 SSE_HELPER_W(helper_pminuw, MIN) 1564 SSE_HELPER_L(helper_pminud, MIN) 1565 SSE_HELPER_B(helper_pmaxsb, FMAXSB) 1566 SSE_HELPER_L(helper_pmaxsd, FMAXSD) 1567 SSE_HELPER_W(helper_pmaxuw, MAX) 1568 SSE_HELPER_L(helper_pmaxud, MAX) 1569 1570 #define FMULLD(d, s) (int32_t) d * (int32_t) s 1571 SSE_HELPER_L(helper_pmulld, FMULLD) 1572 1573 void glue(helper_phminposuw, SUFFIX) (Reg *d, Reg *s) 1574 { 1575 int idx = 0; 1576 1577 if (s->W(1) < s->W(idx)) 1578 idx = 1; 1579 if (s->W(2) < s->W(idx)) 1580 idx = 2; 1581 if (s->W(3) < s->W(idx)) 1582 idx = 3; 1583 if (s->W(4) < s->W(idx)) 1584 idx = 4; 1585 if (s->W(5) < s->W(idx)) 1586 idx = 5; 1587 if (s->W(6) < s->W(idx)) 1588 idx = 6; 1589 if (s->W(7) < s->W(idx)) 1590 idx = 7; 1591 1592 d->Q(1) = 0; 1593 d->L(1) = 0; 1594 d->W(1) = idx; 1595 d->W(0) = s->W(idx); 1596 } 1597 1598 void glue(helper_roundps, SUFFIX) (Reg *d, Reg *s, uint32_t mode) 1599 { 1600 signed char prev_rounding_mode; 1601 1602 prev_rounding_mode = env->sse_status.float_rounding_mode; 1603 if (!(mode & (1 << 2))) 1604 switch (mode & 3) { 1605 case 0: 1606 set_float_rounding_mode(float_round_nearest_even, &env->sse_status); 1607 break; 1608 case 1: 1609 set_float_rounding_mode(float_round_down, &env->sse_status); 1610 break; 1611 case 2: 1612 set_float_rounding_mode(float_round_up, &env->sse_status); 1613 break; 1614 case 3: 1615 set_float_rounding_mode(float_round_to_zero, &env->sse_status); 1616 break; 1617 } 1618 1619 d->L(0) = float64_round_to_int(s->L(0), &env->sse_status); 1620 d->L(1) = float64_round_to_int(s->L(1), &env->sse_status); 1621 d->L(2) = float64_round_to_int(s->L(2), &env->sse_status); 1622 d->L(3) = float64_round_to_int(s->L(3), &env->sse_status); 1623 1624 #if 0 /* TODO */ 1625 if (mode & (1 << 3)) 1626 set_float_exception_flags( 1627 get_float_exception_flags(&env->sse_status) & 1628 ~float_flag_inexact, 1629 &env->sse_status); 1630 #endif 1631 env->sse_status.float_rounding_mode = prev_rounding_mode; 1632 } 1633 1634 void glue(helper_roundpd, SUFFIX) (Reg *d, Reg *s, uint32_t mode) 1635 { 1636 signed char prev_rounding_mode; 1637 1638 prev_rounding_mode = env->sse_status.float_rounding_mode; 1639 if (!(mode & (1 << 2))) 1640 switch (mode & 3) { 1641 case 0: 1642 set_float_rounding_mode(float_round_nearest_even, &env->sse_status); 1643 break; 1644 case 1: 1645 set_float_rounding_mode(float_round_down, &env->sse_status); 1646 break; 1647 case 2: 1648 set_float_rounding_mode(float_round_up, &env->sse_status); 1649 break; 1650 case 3: 1651 set_float_rounding_mode(float_round_to_zero, &env->sse_status); 1652 break; 1653 } 1654 1655 d->Q(0) = float64_round_to_int(s->Q(0), &env->sse_status); 1656 d->Q(1) = float64_round_to_int(s->Q(1), &env->sse_status); 1657 1658 #if 0 /* TODO */ 1659 if (mode & (1 << 3)) 1660 set_float_exception_flags( 1661 get_float_exception_flags(&env->sse_status) & 1662 ~float_flag_inexact, 1663 &env->sse_status); 1664 #endif 1665 env->sse_status.float_rounding_mode = prev_rounding_mode; 1666 } 1667 1668 void glue(helper_roundss, SUFFIX) (Reg *d, Reg *s, uint32_t mode) 1669 { 1670 signed char prev_rounding_mode; 1671 1672 prev_rounding_mode = env->sse_status.float_rounding_mode; 1673 if (!(mode & (1 << 2))) 1674 switch (mode & 3) { 1675 case 0: 1676 set_float_rounding_mode(float_round_nearest_even, &env->sse_status); 1677 break; 1678 case 1: 1679 set_float_rounding_mode(float_round_down, &env->sse_status); 1680 break; 1681 case 2: 1682 set_float_rounding_mode(float_round_up, &env->sse_status); 1683 break; 1684 case 3: 1685 set_float_rounding_mode(float_round_to_zero, &env->sse_status); 1686 break; 1687 } 1688 1689 d->L(0) = float64_round_to_int(s->L(0), &env->sse_status); 1690 1691 #if 0 /* TODO */ 1692 if (mode & (1 << 3)) 1693 set_float_exception_flags( 1694 get_float_exception_flags(&env->sse_status) & 1695 ~float_flag_inexact, 1696 &env->sse_status); 1697 #endif 1698 env->sse_status.float_rounding_mode = prev_rounding_mode; 1699 } 1700 1701 void glue(helper_roundsd, SUFFIX) (Reg *d, Reg *s, uint32_t mode) 1702 { 1703 signed char prev_rounding_mode; 1704 1705 prev_rounding_mode = env->sse_status.float_rounding_mode; 1706 if (!(mode & (1 << 2))) 1707 switch (mode & 3) { 1708 case 0: 1709 set_float_rounding_mode(float_round_nearest_even, &env->sse_status); 1710 break; 1711 case 1: 1712 set_float_rounding_mode(float_round_down, &env->sse_status); 1713 break; 1714 case 2: 1715 set_float_rounding_mode(float_round_up, &env->sse_status); 1716 break; 1717 case 3: 1718 set_float_rounding_mode(float_round_to_zero, &env->sse_status); 1719 break; 1720 } 1721 1722 d->Q(0) = float64_round_to_int(s->Q(0), &env->sse_status); 1723 1724 #if 0 /* TODO */ 1725 if (mode & (1 << 3)) 1726 set_float_exception_flags( 1727 get_float_exception_flags(&env->sse_status) & 1728 ~float_flag_inexact, 1729 &env->sse_status); 1730 #endif 1731 env->sse_status.float_rounding_mode = prev_rounding_mode; 1732 } 1733 1734 #define FBLENDP(d, s, m) m ? s : d 1735 SSE_HELPER_I(helper_blendps, L, 4, FBLENDP) 1736 SSE_HELPER_I(helper_blendpd, Q, 2, FBLENDP) 1737 SSE_HELPER_I(helper_pblendw, W, 8, FBLENDP) 1738 1739 void glue(helper_dpps, SUFFIX) (Reg *d, Reg *s, uint32_t mask) 1740 { 1741 float32 iresult = 0 /*float32_zero*/; 1742 1743 if (mask & (1 << 4)) 1744 iresult = float32_add(iresult, 1745 float32_mul(d->L(0), s->L(0), &env->sse_status), 1746 &env->sse_status); 1747 if (mask & (1 << 5)) 1748 iresult = float32_add(iresult, 1749 float32_mul(d->L(1), s->L(1), &env->sse_status), 1750 &env->sse_status); 1751 if (mask & (1 << 6)) 1752 iresult = float32_add(iresult, 1753 float32_mul(d->L(2), s->L(2), &env->sse_status), 1754 &env->sse_status); 1755 if (mask & (1 << 7)) 1756 iresult = float32_add(iresult, 1757 float32_mul(d->L(3), s->L(3), &env->sse_status), 1758 &env->sse_status); 1759 d->L(0) = (mask & (1 << 0)) ? iresult : 0 /*float32_zero*/; 1760 d->L(1) = (mask & (1 << 1)) ? iresult : 0 /*float32_zero*/; 1761 d->L(2) = (mask & (1 << 2)) ? iresult : 0 /*float32_zero*/; 1762 d->L(3) = (mask & (1 << 3)) ? iresult : 0 /*float32_zero*/; 1763 } 1764 1765 void glue(helper_dppd, SUFFIX) (Reg *d, Reg *s, uint32_t mask) 1766 { 1767 float64 iresult = 0 /*float64_zero*/; 1768 1769 if (mask & (1 << 4)) 1770 iresult = float64_add(iresult, 1771 float64_mul(d->Q(0), s->Q(0), &env->sse_status), 1772 &env->sse_status); 1773 if (mask & (1 << 5)) 1774 iresult = float64_add(iresult, 1775 float64_mul(d->Q(1), s->Q(1), &env->sse_status), 1776 &env->sse_status); 1777 d->Q(0) = (mask & (1 << 0)) ? iresult : 0 /*float64_zero*/; 1778 d->Q(1) = (mask & (1 << 1)) ? iresult : 0 /*float64_zero*/; 1779 } 1780 1781 void glue(helper_mpsadbw, SUFFIX) (Reg *d, Reg *s, uint32_t offset) 1782 { 1783 int s0 = (offset & 3) << 2; 1784 int d0 = (offset & 4) << 0; 1785 int i; 1786 Reg r; 1787 1788 for (i = 0; i < 8; i++, d0++) { 1789 r.W(i) = 0; 1790 r.W(i) += abs1(d->B(d0 + 0) - s->B(s0 + 0)); 1791 r.W(i) += abs1(d->B(d0 + 1) - s->B(s0 + 1)); 1792 r.W(i) += abs1(d->B(d0 + 2) - s->B(s0 + 2)); 1793 r.W(i) += abs1(d->B(d0 + 3) - s->B(s0 + 3)); 1794 } 1795 1796 *d = r; 1797 } 1798 1799 /* SSE4.2 op helpers */ 1800 /* it's unclear whether signed or unsigned */ 1801 #define FCMPGTQ(d, s) d > s ? -1 : 0 1802 SSE_HELPER_Q(helper_pcmpgtq, FCMPGTQ) 1803 1804 static inline int pcmp_elen(int reg, uint32_t ctrl) 1805 { 1806 int val; 1807 1808 /* Presence of REX.W is indicated by a bit higher than 7 set */ 1809 if (ctrl >> 8) 1810 val = abs1((int64_t) env->regs[reg]); 1811 else 1812 val = abs1((int32_t) env->regs[reg]); 1813 1814 if (ctrl & 1) { 1815 if (val > 8) 1816 return 8; 1817 } else 1818 if (val > 16) 1819 return 16; 1820 1821 return val; 1822 } 1823 1824 static inline int pcmp_ilen(Reg *r, uint8_t ctrl) 1825 { 1826 int val = 0; 1827 1828 if (ctrl & 1) { 1829 while (val < 8 && r->W(val)) 1830 val++; 1831 } else 1832 while (val < 16 && r->B(val)) 1833 val++; 1834 1835 return val; 1836 } 1837 1838 static inline int pcmp_val(Reg *r, uint8_t ctrl, int i) 1839 { 1840 switch ((ctrl >> 0) & 3) { 1841 case 0: 1842 return r->B(i); 1843 case 1: 1844 return r->W(i); 1845 case 2: 1846 return (int8_t) r->B(i); 1847 case 3: 1848 default: 1849 return (int16_t) r->W(i); 1850 } 1851 } 1852 1853 static inline unsigned pcmpxstrx(Reg *d, Reg *s, 1854 int8_t ctrl, int valids, int validd) 1855 { 1856 unsigned int res = 0; 1857 int v; 1858 int j, i; 1859 int upper = (ctrl & 1) ? 7 : 15; 1860 1861 valids--; 1862 validd--; 1863 1864 CC_SRC = (valids < upper ? CC_Z : 0) | (validd < upper ? CC_S : 0); 1865 1866 switch ((ctrl >> 2) & 3) { 1867 case 0: 1868 for (j = valids; j >= 0; j--) { 1869 res <<= 1; 1870 v = pcmp_val(s, ctrl, j); 1871 for (i = validd; i >= 0; i--) 1872 res |= (v == pcmp_val(d, ctrl, i)); 1873 } 1874 break; 1875 case 1: 1876 for (j = valids; j >= 0; j--) { 1877 res <<= 1; 1878 v = pcmp_val(s, ctrl, j); 1879 for (i = ((validd - 1) | 1); i >= 0; i -= 2) 1880 res |= (pcmp_val(d, ctrl, i - 0) <= v && 1881 pcmp_val(d, ctrl, i - 1) >= v); 1882 } 1883 break; 1884 case 2: 1885 res = (2 << (upper - MAX(valids, validd))) - 1; 1886 res <<= MAX(valids, validd) - MIN(valids, validd); 1887 for (i = MIN(valids, validd); i >= 0; i--) { 1888 res <<= 1; 1889 v = pcmp_val(s, ctrl, i); 1890 res |= (v == pcmp_val(d, ctrl, i)); 1891 } 1892 break; 1893 case 3: 1894 for (j = valids - validd; j >= 0; j--) { 1895 res <<= 1; 1896 res |= 1; 1897 for (i = MIN(upper - j, validd); i >= 0; i--) 1898 res &= (pcmp_val(s, ctrl, i + j) == pcmp_val(d, ctrl, i)); 1899 } 1900 break; 1901 } 1902 1903 switch ((ctrl >> 4) & 3) { 1904 case 1: 1905 res ^= (2 << upper) - 1; 1906 break; 1907 case 3: 1908 res ^= (2 << valids) - 1; 1909 break; 1910 } 1911 1912 if (res) 1913 CC_SRC |= CC_C; 1914 if (res & 1) 1915 CC_SRC |= CC_O; 1916 1917 return res; 1918 } 1919 1920 static inline int rffs1(unsigned int val) 1921 { 1922 int ret = 1, hi; 1923 1924 for (hi = sizeof(val) * 4; hi; hi /= 2) 1925 if (val >> hi) { 1926 val >>= hi; 1927 ret += hi; 1928 } 1929 1930 return ret; 1931 } 1932 1933 static inline int ffs1(unsigned int val) 1934 { 1935 int ret = 1, hi; 1936 1937 for (hi = sizeof(val) * 4; hi; hi /= 2) 1938 if (val << hi) { 1939 val <<= hi; 1940 ret += hi; 1941 } 1942 1943 return ret; 1944 } 1945 1946 void glue(helper_pcmpestri, SUFFIX) (Reg *d, Reg *s, uint32_t ctrl) 1947 { 1948 unsigned int res = pcmpxstrx(d, s, ctrl, 1949 pcmp_elen(R_EDX, ctrl), 1950 pcmp_elen(R_EAX, ctrl)); 1951 1952 if (res) 1953 env->regs[R_ECX] = ((ctrl & (1 << 6)) ? rffs1 : ffs1)(res) - 1; 1954 else 1955 env->regs[R_ECX] = 16 >> (ctrl & (1 << 0)); 1956 } 1957 1958 void glue(helper_pcmpestrm, SUFFIX) (Reg *d, Reg *s, uint32_t ctrl) 1959 { 1960 int i; 1961 unsigned int res = pcmpxstrx(d, s, ctrl, 1962 pcmp_elen(R_EDX, ctrl), 1963 pcmp_elen(R_EAX, ctrl)); 1964 1965 if ((ctrl >> 6) & 1) { 1966 if (ctrl & 1) 1967 for (i = 0; i <= 8; i--, res >>= 1) 1968 d->W(i) = (res & 1) ? ~0 : 0; 1969 else 1970 for (i = 0; i <= 16; i--, res >>= 1) 1971 d->B(i) = (res & 1) ? ~0 : 0; 1972 } else { 1973 d->Q(1) = 0; 1974 d->Q(0) = res; 1975 } 1976 } 1977 1978 void glue(helper_pcmpistri, SUFFIX) (Reg *d, Reg *s, uint32_t ctrl) 1979 { 1980 unsigned int res = pcmpxstrx(d, s, ctrl, 1981 pcmp_ilen(s, ctrl), 1982 pcmp_ilen(d, ctrl)); 1983 1984 if (res) 1985 env->regs[R_ECX] = ((ctrl & (1 << 6)) ? rffs1 : ffs1)(res) - 1; 1986 else 1987 env->regs[R_ECX] = 16 >> (ctrl & (1 << 0)); 1988 } 1989 1990 void glue(helper_pcmpistrm, SUFFIX) (Reg *d, Reg *s, uint32_t ctrl) 1991 { 1992 int i; 1993 unsigned int res = pcmpxstrx(d, s, ctrl, 1994 pcmp_ilen(s, ctrl), 1995 pcmp_ilen(d, ctrl)); 1996 1997 if ((ctrl >> 6) & 1) { 1998 if (ctrl & 1) 1999 for (i = 0; i <= 8; i--, res >>= 1) 2000 d->W(i) = (res & 1) ? ~0 : 0; 2001 else 2002 for (i = 0; i <= 16; i--, res >>= 1) 2003 d->B(i) = (res & 1) ? ~0 : 0; 2004 } else { 2005 d->Q(1) = 0; 2006 d->Q(0) = res; 2007 } 2008 } 2009 2010 #define CRCPOLY 0x1edc6f41 2011 #define CRCPOLY_BITREV 0x82f63b78 2012 target_ulong helper_crc32(uint32_t crc1, target_ulong msg, uint32_t len) 2013 { 2014 target_ulong crc = (msg & ((target_ulong) -1 >> 2015 (TARGET_LONG_BITS - len))) ^ crc1; 2016 2017 while (len--) 2018 crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY_BITREV : 0); 2019 2020 return crc; 2021 } 2022 2023 #define POPMASK(i) ((target_ulong) -1 / ((1LL << (1 << i)) + 1)) 2024 #define POPCOUNT(n, i) (n & POPMASK(i)) + ((n >> (1 << i)) & POPMASK(i)) 2025 target_ulong helper_popcnt(target_ulong n, uint32_t type) 2026 { 2027 CC_SRC = n ? 0 : CC_Z; 2028 2029 n = POPCOUNT(n, 0); 2030 n = POPCOUNT(n, 1); 2031 n = POPCOUNT(n, 2); 2032 n = POPCOUNT(n, 3); 2033 if (type == 1) 2034 return n & 0xff; 2035 2036 n = POPCOUNT(n, 4); 2037 #ifndef TARGET_X86_64 2038 return n; 2039 #else 2040 if (type == 2) 2041 return n & 0xff; 2042 2043 return POPCOUNT(n, 5); 2044 #endif 2045 } 2046 #endif 1410 2047 1411 2048 #undef SHIFT -
trunk/src/recompiler_new/translate-all.c
r13230 r13337 41 41 #include "tcg.h" 42 42 43 #ifndef VBOX44 43 /* code generation context */ 45 44 TCGContext tcg_ctx; 46 #else47 TCGContext g_tcg_ctx;48 static TCGContext* getCompilerCtx(CPUState *env)49 {50 /** @todo nike: should be field in CPU env */51 //return env->tcg_context;52 return &g_tcg_ctx;53 }54 #endif55 45 56 46 uint16_t gen_opc_buf[OPC_BUF_SIZE]; 57 uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; 58 long gen_labels[OPC_BUF_SIZE]; 59 int nb_gen_labels; 47 TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE]; 60 48 61 49 target_ulong gen_opc_pc[OPC_BUF_SIZE]; 50 uint16_t gen_opc_icount[OPC_BUF_SIZE]; 62 51 uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; 63 52 #if defined(TARGET_I386) … … 86 75 } 87 76 88 #ifndef VBOX89 77 void cpu_gen_init() 90 78 { … … 93 81 CPU_TEMP_BUF_NLONGS * sizeof(long)); 94 82 } 95 #else96 void cpu_gen_init(CPUState *env)97 {98 TCGContext* tcg_ctx = getCompilerCtx(env);99 tcg_context_init(tcg_ctx);100 tcg_set_frame(tcg_ctx, TCG_AREG0, offsetof(CPUState, temp_buf),101 CPU_TEMP_BUF_NLONGS * sizeof(long));102 }103 #endif104 83 105 84 /* return non zero if the very first instruction is invalid so that … … 110 89 */ 111 90 int cpu_gen_code(CPUState *env, TranslationBlock *tb, 112 int max_code_size, int *gen_code_size_ptr) 113 { 114 #ifdef VBOX 115 TCGContext *s = getCompilerCtx(env); 116 #else 91 int *gen_code_size_ptr) 92 { 117 93 TCGContext *s = &tcg_ctx; 118 #endif119 94 uint8_t *gen_code_buf; 120 95 int gen_code_size; … … 133 108 tcg_func_start(s); 134 109 135 if (gen_intermediate_code(env, tb) < 0) 136 { 137 RAWEx_ProfileStop(env, STATS_QEMU_COMPILATION); 138 return -1; 139 } 110 gen_intermediate_code(env, tb); 140 111 #else /* !VBOX */ 141 112 tcg_func_start(s); 142 113 143 if (gen_intermediate_code(env, tb) < 0) 144 return -1; 114 gen_intermediate_code(env, tb); 145 115 #endif /* !VBOX */ 146 116 … … 196 166 void *puc) 197 167 { 198 #ifndef VBOX199 168 TCGContext *s = &tcg_ctx; 200 #else201 TCGContext *s = getCompilerCtx(env);202 #endif203 169 int j; 204 170 unsigned long tc_ptr; … … 213 179 214 180 #ifdef VBOX 215 /** @todo: what's right here? */ 216 if (gen_intermediate_code_pc(env, tb) < 0) 217 return -1; 181 gen_intermediate_code_pc(env, tb); 218 182 #else 219 183 gen_intermediate_code_pc(env, tb);
Note:
See TracChangeset
for help on using the changeset viewer.