VirtualBox

Changeset 13337 in vbox for trunk/src


Ignore:
Timestamp:
Oct 16, 2008 11:59:21 AM (16 years ago)
Author:
vboxsync
Message:

more recompiler work

Location:
trunk/src/recompiler_new
Files:
1 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/recompiler_new/Makefile.kmk

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

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

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

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

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

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

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

    r11982 r13337  
    6161                                                        void *retaddr);
    6262static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
    63                                               target_ulong tlb_addr)
     63                                              target_ulong addr,
     64                                              void *retaddr)
    6465{
    6566    DATA_TYPE res;
    6667    int index;
    67 
    68     index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     68    index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     69    physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
     70    env->mem_io_pc = (unsigned long)retaddr;
     71    if (index > (IO_MEM_NOTDIRTY >> IO_MEM_SHIFT)
     72            && !can_do_io(env)) {
     73        cpu_io_recompile(env, retaddr);
     74    }
     75
    6976#if SHIFT <= 2
    7077    res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
     
    8592
    8693/* handle all cases except unaligned access which span two pages */
    87 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
    88                                                          int is_user)
     94DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
     95                                                      int mmu_idx)
    8996{
    9097    DATA_TYPE res;
    9198    int index;
    9299    target_ulong tlb_addr;
    93     target_phys_addr_t physaddr;
     100    target_phys_addr_t addend;
    94101    void *retaddr;
    95    
     102
    96103    /* test if there is match for unaligned or IO access */
    97104    /* XXX: could done more in memory macro in a non portable way */
    98105    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    99106 redo:
    100     tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
     107    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
    101108    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
    102         physaddr = addr + env->tlb_table[is_user][index].addend;
    103109        if (tlb_addr & ~TARGET_PAGE_MASK) {
    104110            /* IO access */
    105111            if ((addr & (DATA_SIZE - 1)) != 0)
    106112                goto do_unaligned_access;
    107             res = glue(io_read, SUFFIX)(physaddr, tlb_addr);
     113            retaddr = GETPC();
     114            addend = env->iotlb[mmu_idx][index];
     115            res = glue(io_read, SUFFIX)(addend, addr, retaddr);
    108116        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
    109117            /* slow unaligned access (it spans two pages or IO) */
     
    111119            retaddr = GETPC();
    112120#ifdef ALIGNED_ONLY
    113             do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
    114 #endif
    115             res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr, 
    116                                                          is_user, retaddr);
     121            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
     122#endif
     123            res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
     124                                                         mmu_idx, retaddr);
    117125        } else {
    118126            /* unaligned/aligned access in the same page */
     
    120128            if ((addr & (DATA_SIZE - 1)) != 0) {
    121129                retaddr = GETPC();
    122                 do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
     130                do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
    123131            }
    124132#endif
    125             res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
     133            addend = env->tlb_table[mmu_idx][index].addend;
     134            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend));
    126135        }
    127136    } else {
     
    130139#ifdef ALIGNED_ONLY
    131140        if ((addr & (DATA_SIZE - 1)) != 0)
    132             do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr);
    133 #endif
    134         tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
     141            do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
     142#endif
     143        tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
    135144        goto redo;
    136145    }
     
    139148
    140149/* handle all unaligned cases */
    141 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 
    142                                                         int is_user,
     150static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
     151                                                        int mmu_idx,
    143152                                                        void *retaddr)
    144153{
    145154    DATA_TYPE res, res1, res2;
    146155    int index, shift;
    147     target_phys_addr_t physaddr;
     156    target_phys_addr_t addend;
    148157    target_ulong tlb_addr, addr1, addr2;
    149158
    150159    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    151160 redo:
    152     tlb_addr = env->tlb_table[is_user][index].ADDR_READ;
     161    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
    153162    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
    154         physaddr = addr + env->tlb_table[is_user][index].addend;
    155163        if (tlb_addr & ~TARGET_PAGE_MASK) {
    156164            /* IO access */
    157165            if ((addr & (DATA_SIZE - 1)) != 0)
    158166                goto do_unaligned_access;
    159             res = glue(io_read, SUFFIX)(physaddr, tlb_addr);
     167            retaddr = GETPC();
     168            addend = env->iotlb[mmu_idx][index];
     169            res = glue(io_read, SUFFIX)(addend, addr, retaddr);
    160170        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
    161171        do_unaligned_access:
     
    163173            addr1 = addr & ~(DATA_SIZE - 1);
    164174            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);
    169179            shift = (addr & (DATA_SIZE - 1)) * 8;
    170180#ifdef TARGET_WORDS_BIGENDIAN
     
    176186        } else {
    177187            /* 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));
    179190        }
    180191    } else {
    181192        /* 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);
    183194        goto redo;
    184195    }
     
    195206static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
    196207                                          DATA_TYPE val,
    197                                           target_ulong tlb_addr,
     208                                          target_ulong addr,
    198209                                          void *retaddr)
    199210{
    200211    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;
    205221#if SHIFT <= 2
    206222    io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val);
     
    219235}
    220236
    221 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
    222                                                     DATA_TYPE val,
    223                                                     int is_user)
    224 {
    225     target_phys_addr_t physaddr;
     237void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
     238                                                 DATA_TYPE val,
     239                                                 int mmu_idx)
     240{
     241    target_phys_addr_t addend;
    226242    target_ulong tlb_addr;
    227243    void *retaddr;
    228244    int index;
    229    
     245
    230246    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    231247 redo:
    232     tlb_addr = env->tlb_table[is_user][index].addr_write;
     248    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
    233249    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
    234         physaddr = addr + env->tlb_table[is_user][index].addend;
    235250        if (tlb_addr & ~TARGET_PAGE_MASK) {
    236251            /* IO access */
     
    238253                goto do_unaligned_access;
    239254            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);
    241257        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
    242258        do_unaligned_access:
    243259            retaddr = GETPC();
    244260#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);
    249265        } else {
    250266            /* aligned/unaligned access in the same page */
     
    252268            if ((addr & (DATA_SIZE - 1)) != 0) {
    253269                retaddr = GETPC();
    254                 do_unaligned_access(addr, 1, is_user, retaddr);
     270                do_unaligned_access(addr, 1, mmu_idx, retaddr);
    255271            }
    256272#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);
    258275        }
    259276    } else {
     
    262279#ifdef ALIGNED_ONLY
    263280        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);
    267284        goto redo;
    268285    }
     
    270287
    271288/* handles all unaligned cases */
    272 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
     289/* handles all unaligned cases */
     290static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
    273291                                                   DATA_TYPE val,
    274                                                    int is_user,
     292                                                   int mmu_idx,
    275293                                                   void *retaddr)
    276294{
    277     target_phys_addr_t physaddr;
     295    target_phys_addr_t addend;
    278296    target_ulong tlb_addr;
    279297    int index, i;
     
    281299    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
    282300 redo:
    283     tlb_addr = env->tlb_table[is_user][index].addr_write;
     301    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
    284302    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
    285         physaddr = addr + env->tlb_table[is_user][index].addend;
    286303        if (tlb_addr & ~TARGET_PAGE_MASK) {
    287304            /* IO access */
    288305            if ((addr & (DATA_SIZE - 1)) != 0)
    289306                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);
    291309        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
    292310        do_unaligned_access:
    293311            /* 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--) {
    295315#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);
    301321#endif
    302322            }
    303323        } else {
    304324            /* 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);
    306327        }
    307328    } else {
    308329        /* 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);
    310331        goto redo;
    311332    }
  • trunk/src/recompiler_new/target-i386/cpu.h

    r13230 r13337  
    267267#define MSR_MCG_CTL                     0x17b
    268268
     269#define MSR_IA32_PERF_STATUS            0x198
     270
    269271#define MSR_PAT                         0x277
    270272
     
    494496    uint16_t _w[2];
    495497    uint32_t _l[1];
     498    float32 _s[2];
    496499    uint64_t q;
    497500} MMXReg;
     
    508511#define MMX_W(n) _w[3 - (n)]
    509512#define MMX_L(n) _l[1 - (n)]
     513#define MMX_S(n) _s[1 - (n)]
    510514#else
    511515#define XMM_B(n) _b[n]
     
    519523#define MMX_W(n) _w[n]
    520524#define MMX_L(n) _l[n]
     525#define MMX_S(n) _s[n]
    521526#endif
    522527#define MMX_Q(n) q
     
    555560
    556561    target_ulong cr[5]; /* NOTE: cr1 is unused */
    557     uint32_t a20_mask;
     562    uint64_t a20_mask;
    558563
    559564    /* FPU state */
     
    657662    uint32_t cpuid_ext2_features;
    658663    uint32_t cpuid_ext3_features;
     664    uint32_t cpuid_apic_id;
    659665
    660666#ifndef VBOX
  • trunk/src/recompiler_new/target-i386/helper.c

    r13117 r13337  
    3030# include <VBox/err.h>
    3131#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"
    3347
    3448//#define DEBUG_PCALL
  • trunk/src/recompiler_new/target-i386/ops_sse.h

    r11982 r13337  
    11/*
    2  *  MMX/SSE/SSE2/PNI support
    3  * 
     2 *  MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI support
     3 *
    44 *  Copyright (c) 2005 Fabrice Bellard
     5 *  Copyright (c) 2008 Intel Corporation  <[email protected]>
    56 *
    67 * This library is free software; you can redistribute it and/or
     
    1819 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1920 */
    20 
    2121/*
    2222 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
     
    2727 * of the LGPL is applied is otherwise unspecified.
    2828 */
     29
    2930#if SHIFT == 0
    3031#define Reg MMXReg
     
    4546#endif
    4647
    47 void OPPROTO glue(op_psrlw, SUFFIX)(void)
    48 {
    49     Reg *d, *s;
     48void glue(helper_psrlw, SUFFIX)(Reg *d, Reg *s)
     49{
    5050    int shift;
    51 
    52     d = (Reg *)((char *)env + PARAM1);
    53     s = (Reg *)((char *)env + PARAM2);
    5451
    5552    if (s->Q(0) > 15) {
     
    7471}
    7572
    76 void OPPROTO glue(op_psraw, SUFFIX)(void)
    77 {
    78     Reg *d, *s;
     73void glue(helper_psraw, SUFFIX)(Reg *d, Reg *s)
     74{
    7975    int shift;
    80 
    81     d = (Reg *)((char *)env + PARAM1);
    82     s = (Reg *)((char *)env + PARAM2);
    8376
    8477    if (s->Q(0) > 15) {
     
    9992}
    10093
    101 void OPPROTO glue(op_psllw, SUFFIX)(void)
    102 {
    103     Reg *d, *s;
     94void glue(helper_psllw, SUFFIX)(Reg *d, Reg *s)
     95{
    10496    int shift;
    105 
    106     d = (Reg *)((char *)env + PARAM1);
    107     s = (Reg *)((char *)env + PARAM2);
    10897
    10998    if (s->Q(0) > 15) {
     
    128117}
    129118
    130 void OPPROTO glue(op_psrld, SUFFIX)(void)
    131 {
    132     Reg *d, *s;
     119void glue(helper_psrld, SUFFIX)(Reg *d, Reg *s)
     120{
    133121    int shift;
    134 
    135     d = (Reg *)((char *)env + PARAM1);
    136     s = (Reg *)((char *)env + PARAM2);
    137122
    138123    if (s->Q(0) > 31) {
     
    153138}
    154139
    155 void OPPROTO glue(op_psrad, SUFFIX)(void)
    156 {
    157     Reg *d, *s;
     140void glue(helper_psrad, SUFFIX)(Reg *d, Reg *s)
     141{
    158142    int shift;
    159 
    160     d = (Reg *)((char *)env + PARAM1);
    161     s = (Reg *)((char *)env + PARAM2);
    162143
    163144    if (s->Q(0) > 31) {
     
    174155}
    175156
    176 void OPPROTO glue(op_pslld, SUFFIX)(void)
    177 {
    178     Reg *d, *s;
     157void glue(helper_pslld, SUFFIX)(Reg *d, Reg *s)
     158{
    179159    int shift;
    180 
    181     d = (Reg *)((char *)env + PARAM1);
    182     s = (Reg *)((char *)env + PARAM2);
    183160
    184161    if (s->Q(0) > 31) {
     
    199176}
    200177
    201 void OPPROTO glue(op_psrlq, SUFFIX)(void)
    202 {
    203     Reg *d, *s;
     178void glue(helper_psrlq, SUFFIX)(Reg *d, Reg *s)
     179{
    204180    int shift;
    205 
    206     d = (Reg *)((char *)env + PARAM1);
    207     s = (Reg *)((char *)env + PARAM2);
    208181
    209182    if (s->Q(0) > 63) {
     
    222195}
    223196
    224 void OPPROTO glue(op_psllq, SUFFIX)(void)
    225 {
    226     Reg *d, *s;
     197void glue(helper_psllq, SUFFIX)(Reg *d, Reg *s)
     198{
    227199    int shift;
    228 
    229     d = (Reg *)((char *)env + PARAM1);
    230     s = (Reg *)((char *)env + PARAM2);
    231200
    232201    if (s->Q(0) > 63) {
     
    246215
    247216#if SHIFT == 1
    248 void OPPROTO glue(op_psrldq, SUFFIX)(void)
    249 {
    250     Reg *d, *s;
     217void glue(helper_psrldq, SUFFIX)(Reg *d, Reg *s)
     218{
    251219    int shift, i;
    252220
    253     d = (Reg *)((char *)env + PARAM1);
    254     s = (Reg *)((char *)env + PARAM2);
    255221    shift = s->L(0);
    256222    if (shift > 16)
     
    263229}
    264230
    265 void OPPROTO glue(op_pslldq, SUFFIX)(void)
    266 {
    267     Reg *d, *s;
     231void glue(helper_pslldq, SUFFIX)(Reg *d, Reg *s)
     232{
    268233    int shift, i;
    269234
    270     d = (Reg *)((char *)env + PARAM1);
    271     s = (Reg *)((char *)env + PARAM2);
    272235    shift = s->L(0);
    273236    if (shift > 16)
     
    281244#endif
    282245
    283 #define SSE_OP_B(name, F)\
    284 void OPPROTO glue(name, SUFFIX) (void)\
     246#define SSE_HELPER_B(name, F)\
     247void glue(name, SUFFIX) (Reg *d, Reg *s)\
    285248{\
    286     Reg *d, *s;\
    287     d = (Reg *)((char *)env + PARAM1);\
    288     s = (Reg *)((char *)env + PARAM2);\
    289249    d->B(0) = F(d->B(0), s->B(0));\
    290250    d->B(1) = F(d->B(1), s->B(1));\
     
    307267}
    308268
    309 #define SSE_OP_W(name, F)\
    310 void OPPROTO glue(name, SUFFIX) (void)\
     269#define SSE_HELPER_W(name, F)\
     270void glue(name, SUFFIX) (Reg *d, Reg *s)\
    311271{\
    312     Reg *d, *s;\
    313     d = (Reg *)((char *)env + PARAM1);\
    314     s = (Reg *)((char *)env + PARAM2);\
    315272    d->W(0) = F(d->W(0), s->W(0));\
    316273    d->W(1) = F(d->W(1), s->W(1));\
     
    325282}
    326283
    327 #define SSE_OP_L(name, F)\
    328 void OPPROTO glue(name, SUFFIX) (void)\
     284#define SSE_HELPER_L(name, F)\
     285void glue(name, SUFFIX) (Reg *d, Reg *s)\
    329286{\
    330     Reg *d, *s;\
    331     d = (Reg *)((char *)env + PARAM1);\
    332     s = (Reg *)((char *)env + PARAM2);\
    333287    d->L(0) = F(d->L(0), s->L(0));\
    334288    d->L(1) = F(d->L(1), s->L(1));\
     
    339293}
    340294
    341 #define SSE_OP_Q(name, F)\
    342 void OPPROTO glue(name, SUFFIX) (void)\
     295#define SSE_HELPER_Q(name, F)\
     296void glue(name, SUFFIX) (Reg *d, Reg *s)\
    343297{\
    344     Reg *d, *s;\
    345     d = (Reg *)((char *)env + PARAM1);\
    346     s = (Reg *)((char *)env + PARAM2);\
    347298    d->Q(0) = F(d->Q(0), s->Q(0));\
    348299    XMM_ONLY(\
     
    419370
    420371#define FMULLW(a, b) (a) * (b)
     372#define FMULHRW(a, b) ((int16_t)(a) * (int16_t)(b) + 0x8000) >> 16
    421373#define FMULHUW(a, b) (a) * (b) >> 16
    422374#define FMULHW(a, b) (int16_t)(a) * (int16_t)(b) >> 16
     
    425377#endif
    426378
    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 
     379SSE_HELPER_B(helper_paddb, FADD)
     380SSE_HELPER_W(helper_paddw, FADD)
     381SSE_HELPER_L(helper_paddl, FADD)
     382SSE_HELPER_Q(helper_paddq, FADD)
     383
     384SSE_HELPER_B(helper_psubb, FSUB)
     385SSE_HELPER_W(helper_psubw, FSUB)
     386SSE_HELPER_L(helper_psubl, FSUB)
     387SSE_HELPER_Q(helper_psubq, FSUB)
     388
     389SSE_HELPER_B(helper_paddusb, FADDUB)
     390SSE_HELPER_B(helper_paddsb, FADDSB)
     391SSE_HELPER_B(helper_psubusb, FSUBUB)
     392SSE_HELPER_B(helper_psubsb, FSUBSB)
     393
     394SSE_HELPER_W(helper_paddusw, FADDUW)
     395SSE_HELPER_W(helper_paddsw, FADDSW)
     396SSE_HELPER_W(helper_psubusw, FSUBUW)
     397SSE_HELPER_W(helper_psubsw, FSUBSW)
     398
     399SSE_HELPER_B(helper_pminub, FMINUB)
     400SSE_HELPER_B(helper_pmaxub, FMAXUB)
     401
     402SSE_HELPER_W(helper_pminsw, FMINSW)
     403SSE_HELPER_W(helper_pmaxsw, FMAXSW)
     404
     405SSE_HELPER_Q(helper_pand, FAND)
     406SSE_HELPER_Q(helper_pandn, FANDN)
     407SSE_HELPER_Q(helper_por, FOR)
     408SSE_HELPER_Q(helper_pxor, FXOR)
     409
     410SSE_HELPER_B(helper_pcmpgtb, FCMPGTB)
     411SSE_HELPER_W(helper_pcmpgtw, FCMPGTW)
     412SSE_HELPER_L(helper_pcmpgtl, FCMPGTL)
     413
     414SSE_HELPER_B(helper_pcmpeqb, FCMPEQ)
     415SSE_HELPER_W(helper_pcmpeqw, FCMPEQ)
     416SSE_HELPER_L(helper_pcmpeql, FCMPEQ)
     417
     418SSE_HELPER_W(helper_pmullw, FMULLW)
     419#if SHIFT == 0
     420SSE_HELPER_W(helper_pmulhrw, FMULHRW)
     421#endif
     422SSE_HELPER_W(helper_pmulhuw, FMULHUW)
     423SSE_HELPER_W(helper_pmulhw, FMULHW)
     424
     425SSE_HELPER_B(helper_pavgb, FAVG)
     426SSE_HELPER_W(helper_pavgw, FAVG)
     427
     428void glue(helper_pmuludq, SUFFIX) (Reg *d, Reg *s)
     429{
    479430    d->Q(0) = (uint64_t)s->L(0) * (uint64_t)d->L(0);
    480431#if SHIFT == 1
     
    483434}
    484435
    485 void OPPROTO glue(op_pmaddwd, SUFFIX) (void)
     436void glue(helper_pmaddwd, SUFFIX) (Reg *d, Reg *s)
    486437{
    487438    int i;
    488     Reg *d, *s;
    489     d = (Reg *)((char *)env + PARAM1);
    490     s = (Reg *)((char *)env + PARAM2);
    491439
    492440    for(i = 0; i < (2 << SHIFT); i++) {
     
    506454}
    507455#endif
    508 void OPPROTO glue(op_psadbw, SUFFIX) (void)
     456void glue(helper_psadbw, SUFFIX) (Reg *d, Reg *s)
    509457{
    510458    unsigned int val;
    511     Reg *d, *s;
    512     d = (Reg *)((char *)env + PARAM1);
    513     s = (Reg *)((char *)env + PARAM2);
    514459
    515460    val = 0;
     
    537482}
    538483
    539 void OPPROTO glue(op_maskmov, SUFFIX) (void)
     484void glue(helper_maskmov, SUFFIX) (Reg *d, Reg *s, target_ulong a0)
    540485{
    541486    int i;
    542     Reg *d, *s;
    543     d = (Reg *)((char *)env + PARAM1);
    544     s = (Reg *)((char *)env + PARAM2);
    545487    for(i = 0; i < (8 << SHIFT); i++) {
    546488        if (s->B(i) & 0x80)
    547             stb(A0 + i, d->B(i));
     489            stb(a0 + i, d->B(i));
    548490    }
    549491    FORCE_RET();
    550492}
    551493
    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;
     494void glue(helper_movl_mm_T0, SUFFIX) (Reg *d, uint32_t val)
     495{
     496    d->L(0) = val;
    557497    d->L(1) = 0;
    558498#if SHIFT == 1
     
    561501}
    562502
    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 
    570503#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;
     504void glue(helper_movq_mm_T0, SUFFIX) (Reg *d, uint64_t val)
     505{
     506    d->Q(0) = val;
    576507#if SHIFT == 1
    577508    d->Q(1) = 0;
    578509#endif
    579510}
    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 }
    587511#endif
    588512
    589513#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;
     514void glue(helper_pshufw, SUFFIX) (Reg *d, Reg *s, int order)
     515{
     516    Reg r;
    598517    r.W(0) = s->W(order & 3);
    599518    r.W(1) = s->W((order >> 2) & 3);
     
    601520    r.W(3) = s->W((order >> 6) & 3);
    602521    *d = r;
     522}
    603523#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;
     524void helper_shufps(Reg *d, Reg *s, int order)
     525{
     526    Reg r;
    627527    r.L(0) = d->L(order & 3);
    628528    r.L(1) = d->L((order >> 2) & 3);
     
    632532}
    633533
    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;
     534void helper_shufpd(Reg *d, Reg *s, int order)
     535{
     536    Reg r;
    641537    r.Q(0) = d->Q(order & 1);
    642538    r.Q(1) = s->Q((order >> 1) & 1);
     
    644540}
    645541
    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;
     542void glue(helper_pshufd, SUFFIX) (Reg *d, Reg *s, int order)
     543{
     544    Reg r;
    653545    r.L(0) = s->L(order & 3);
    654546    r.L(1) = s->L((order >> 2) & 3);
     
    658550}
    659551
    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;
     552void glue(helper_pshuflw, SUFFIX) (Reg *d, Reg *s, int order)
     553{
     554    Reg r;
    667555    r.W(0) = s->W(order & 3);
    668556    r.W(1) = s->W((order >> 2) & 3);
     
    673561}
    674562
    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;
     563void glue(helper_pshufhw, SUFFIX) (Reg *d, Reg *s, int order)
     564{
     565    Reg r;
    682566    r.Q(0) = s->Q(0);
    683567    r.W(4) = s->W(4 + (order & 3));
     
    693577/* XXX: not accurate */
    694578
    695 #define SSE_OP_S(name, F)\
    696 void OPPROTO op_ ## name ## ps (void)\
     579#define SSE_HELPER_S(name, F)\
     580void helper_ ## name ## ps (Reg *d, Reg *s)\
    697581{\
    698     Reg *d, *s;\
    699     d = (Reg *)((char *)env + PARAM1);\
    700     s = (Reg *)((char *)env + PARAM2);\
    701582    d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
    702583    d->XMM_S(1) = F(32, d->XMM_S(1), s->XMM_S(1));\
     
    705586}\
    706587\
    707 void OPPROTO op_ ## name ## ss (void)\
     588void helper_ ## name ## ss (Reg *d, Reg *s)\
    708589{\
    709     Reg *d, *s;\
    710     d = (Reg *)((char *)env + PARAM1);\
    711     s = (Reg *)((char *)env + PARAM2);\
    712590    d->XMM_S(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
    713591}\
    714 void OPPROTO op_ ## name ## pd (void)\
     592void helper_ ## name ## pd (Reg *d, Reg *s)\
    715593{\
    716     Reg *d, *s;\
    717     d = (Reg *)((char *)env + PARAM1);\
    718     s = (Reg *)((char *)env + PARAM2);\
    719594    d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
    720595    d->XMM_D(1) = F(64, d->XMM_D(1), s->XMM_D(1));\
    721596}\
    722597\
    723 void OPPROTO op_ ## name ## sd (void)\
     598void helper_ ## name ## sd (Reg *d, Reg *s)\
    724599{\
    725     Reg *d, *s;\
    726     d = (Reg *)((char *)env + PARAM1);\
    727     s = (Reg *)((char *)env + PARAM2);\
    728600    d->XMM_D(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
    729601}
     
    737609#define FPU_SQRT(size, a, b) float ## size ## _sqrt(b, &env->sse_status)
    738610
    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)
     611SSE_HELPER_S(add, FPU_ADD)
     612SSE_HELPER_S(sub, FPU_SUB)
     613SSE_HELPER_S(mul, FPU_MUL)
     614SSE_HELPER_S(div, FPU_DIV)
     615SSE_HELPER_S(min, FPU_MIN)
     616SSE_HELPER_S(max, FPU_MAX)
     617SSE_HELPER_S(sqrt, FPU_SQRT)
    746618
    747619
    748620/* float to float conversions */
    749 void OPPROTO op_cvtps2pd(void)
     621void helper_cvtps2pd(Reg *d, Reg *s)
    750622{
    751623    float32 s0, s1;
    752     Reg *d, *s;
    753     d = (Reg *)((char *)env + PARAM1);
    754     s = (Reg *)((char *)env + PARAM2);
    755624    s0 = s->XMM_S(0);
    756625    s1 = s->XMM_S(1);
     
    759628}
    760629
    761 void OPPROTO op_cvtpd2ps(void)
    762 {
    763     Reg *d, *s;
    764     d = (Reg *)((char *)env + PARAM1);
    765     s = (Reg *)((char *)env + PARAM2);
     630void helper_cvtpd2ps(Reg *d, Reg *s)
     631{
    766632    d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
    767633    d->XMM_S(1) = float64_to_float32(s->XMM_D(1), &env->sse_status);
     
    769635}
    770636
    771 void OPPROTO op_cvtss2sd(void)
    772 {
    773     Reg *d, *s;
    774     d = (Reg *)((char *)env + PARAM1);
    775     s = (Reg *)((char *)env + PARAM2);
     637void helper_cvtss2sd(Reg *d, Reg *s)
     638{
    776639    d->XMM_D(0) = float32_to_float64(s->XMM_S(0), &env->sse_status);
    777640}
    778641
    779 void OPPROTO op_cvtsd2ss(void)
    780 {
    781     Reg *d, *s;
    782     d = (Reg *)((char *)env + PARAM1);
    783     s = (Reg *)((char *)env + PARAM2);
     642void helper_cvtsd2ss(Reg *d, Reg *s)
     643{
    784644    d->XMM_S(0) = float64_to_float32(s->XMM_D(0), &env->sse_status);
    785645}
    786646
    787647/* integer to float */
    788 void OPPROTO op_cvtdq2ps(void)
    789 {
    790     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    791     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     648void helper_cvtdq2ps(Reg *d, Reg *s)
     649{
    792650    d->XMM_S(0) = int32_to_float32(s->XMM_L(0), &env->sse_status);
    793651    d->XMM_S(1) = int32_to_float32(s->XMM_L(1), &env->sse_status);
     
    796654}
    797655
    798 void OPPROTO op_cvtdq2pd(void)
    799 {
    800     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    801     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     656void helper_cvtdq2pd(Reg *d, Reg *s)
     657{
    802658    int32_t l0, l1;
    803659    l0 = (int32_t)s->XMM_L(0);
     
    807663}
    808664
    809 void OPPROTO op_cvtpi2ps(void)
    810 {
    811     XMMReg *d = (Reg *)((char *)env + PARAM1);
    812     MMXReg *s = (MMXReg *)((char *)env + PARAM2);
     665void helper_cvtpi2ps(XMMReg *d, MMXReg *s)
     666{
    813667    d->XMM_S(0) = int32_to_float32(s->MMX_L(0), &env->sse_status);
    814668    d->XMM_S(1) = int32_to_float32(s->MMX_L(1), &env->sse_status);
    815669}
    816670
    817 void OPPROTO op_cvtpi2pd(void)
    818 {
    819     XMMReg *d = (Reg *)((char *)env + PARAM1);
    820     MMXReg *s = (MMXReg *)((char *)env + PARAM2);
     671void helper_cvtpi2pd(XMMReg *d, MMXReg *s)
     672{
    821673    d->XMM_D(0) = int32_to_float64(s->MMX_L(0), &env->sse_status);
    822674    d->XMM_D(1) = int32_to_float64(s->MMX_L(1), &env->sse_status);
    823675}
    824676
    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);
     677void helper_cvtsi2ss(XMMReg *d, uint32_t val)
     678{
     679    d->XMM_S(0) = int32_to_float32(val, &env->sse_status);
     680}
     681
     682void helper_cvtsi2sd(XMMReg *d, uint32_t val)
     683{
     684    d->XMM_D(0) = int32_to_float64(val, &env->sse_status);
    835685}
    836686
    837687#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);
     688void helper_cvtsq2ss(XMMReg *d, uint64_t val)
     689{
     690    d->XMM_S(0) = int64_to_float32(val, &env->sse_status);
     691}
     692
     693void helper_cvtsq2sd(XMMReg *d, uint64_t val)
     694{
     695    d->XMM_D(0) = int64_to_float64(val, &env->sse_status);
    848696}
    849697#endif
    850698
    851699/* float to integer */
    852 void OPPROTO op_cvtps2dq(void)
    853 {
    854     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    855     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     700void helper_cvtps2dq(XMMReg *d, XMMReg *s)
     701{
    856702    d->XMM_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
    857703    d->XMM_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
     
    860706}
    861707
    862 void OPPROTO op_cvtpd2dq(void)
    863 {
    864     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    865     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     708void helper_cvtpd2dq(XMMReg *d, XMMReg *s)
     709{
    866710    d->XMM_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
    867711    d->XMM_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
     
    869713}
    870714
    871 void OPPROTO op_cvtps2pi(void)
    872 {
    873     MMXReg *d = (MMXReg *)((char *)env + PARAM1);
    874     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     715void helper_cvtps2pi(MMXReg *d, XMMReg *s)
     716{
    875717    d->MMX_L(0) = float32_to_int32(s->XMM_S(0), &env->sse_status);
    876718    d->MMX_L(1) = float32_to_int32(s->XMM_S(1), &env->sse_status);
    877719}
    878720
    879 void OPPROTO op_cvtpd2pi(void)
    880 {
    881     MMXReg *d = (MMXReg *)((char *)env + PARAM1);
    882     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     721void helper_cvtpd2pi(MMXReg *d, XMMReg *s)
     722{
    883723    d->MMX_L(0) = float64_to_int32(s->XMM_D(0), &env->sse_status);
    884724    d->MMX_L(1) = float64_to_int32(s->XMM_D(1), &env->sse_status);
    885725}
    886726
    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);
     727int32_t helper_cvtss2si(XMMReg *s)
     728{
     729    return float32_to_int32(s->XMM_S(0), &env->sse_status);
     730}
     731
     732int32_t helper_cvtsd2si(XMMReg *s)
     733{
     734    return float64_to_int32(s->XMM_D(0), &env->sse_status);
    897735}
    898736
    899737#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);
     738int64_t helper_cvtss2sq(XMMReg *s)
     739{
     740    return float32_to_int64(s->XMM_S(0), &env->sse_status);
     741}
     742
     743int64_t helper_cvtsd2sq(XMMReg *s)
     744{
     745    return float64_to_int64(s->XMM_D(0), &env->sse_status);
    910746}
    911747#endif
    912748
    913749/* 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);
     750void helper_cvttps2dq(XMMReg *d, XMMReg *s)
     751{
    918752    d->XMM_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
    919753    d->XMM_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
     
    922756}
    923757
    924 void OPPROTO op_cvttpd2dq(void)
    925 {
    926     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    927     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     758void helper_cvttpd2dq(XMMReg *d, XMMReg *s)
     759{
    928760    d->XMM_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
    929761    d->XMM_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
     
    931763}
    932764
    933 void OPPROTO op_cvttps2pi(void)
    934 {
    935     MMXReg *d = (MMXReg *)((char *)env + PARAM1);
    936     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     765void helper_cvttps2pi(MMXReg *d, XMMReg *s)
     766{
    937767    d->MMX_L(0) = float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
    938768    d->MMX_L(1) = float32_to_int32_round_to_zero(s->XMM_S(1), &env->sse_status);
    939769}
    940770
    941 void OPPROTO op_cvttpd2pi(void)
    942 {
    943     MMXReg *d = (MMXReg *)((char *)env + PARAM1);
    944     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     771void helper_cvttpd2pi(MMXReg *d, XMMReg *s)
     772{
    945773    d->MMX_L(0) = float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
    946774    d->MMX_L(1) = float64_to_int32_round_to_zero(s->XMM_D(1), &env->sse_status);
    947775}
    948776
    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);
     777int32_t helper_cvttss2si(XMMReg *s)
     778{
     779    return float32_to_int32_round_to_zero(s->XMM_S(0), &env->sse_status);
     780}
     781
     782int32_t helper_cvttsd2si(XMMReg *s)
     783{
     784    return float64_to_int32_round_to_zero(s->XMM_D(0), &env->sse_status);
    959785}
    960786
    961787#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);
     788int64_t helper_cvttss2sq(XMMReg *s)
     789{
     790    return float32_to_int64_round_to_zero(s->XMM_S(0), &env->sse_status);
     791}
     792
     793int64_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
     799void helper_rsqrtps(XMMReg *d, XMMReg *s)
     800{
    979801    d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
    980802    d->XMM_S(1) = approx_rsqrt(s->XMM_S(1));
     
    983805}
    984806
    985 void OPPROTO op_rsqrtss(void)
    986 {
    987     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    988     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     807void helper_rsqrtss(XMMReg *d, XMMReg *s)
     808{
    989809    d->XMM_S(0) = approx_rsqrt(s->XMM_S(0));
    990810}
    991811
    992 void OPPROTO op_rcpps(void)
    993 {
    994     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    995     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     812void helper_rcpps(XMMReg *d, XMMReg *s)
     813{
    996814    d->XMM_S(0) = approx_rcp(s->XMM_S(0));
    997815    d->XMM_S(1) = approx_rcp(s->XMM_S(1));
     
    1000818}
    1001819
    1002 void OPPROTO op_rcpss(void)
    1003 {
    1004     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    1005     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     820void helper_rcpss(XMMReg *d, XMMReg *s)
     821{
    1006822    d->XMM_S(0) = approx_rcp(s->XMM_S(0));
    1007823}
    1008824
    1009 void OPPROTO op_haddps(void)
    1010 {
    1011     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    1012     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     825void helper_haddps(XMMReg *d, XMMReg *s)
     826{
    1013827    XMMReg r;
    1014828    r.XMM_S(0) = d->XMM_S(0) + d->XMM_S(1);
     
    1019833}
    1020834
    1021 void OPPROTO op_haddpd(void)
    1022 {
    1023     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    1024     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     835void helper_haddpd(XMMReg *d, XMMReg *s)
     836{
    1025837    XMMReg r;
    1026838    r.XMM_D(0) = d->XMM_D(0) + d->XMM_D(1);
     
    1029841}
    1030842
    1031 void OPPROTO op_hsubps(void)
    1032 {
    1033     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    1034     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     843void helper_hsubps(XMMReg *d, XMMReg *s)
     844{
    1035845    XMMReg r;
    1036846    r.XMM_S(0) = d->XMM_S(0) - d->XMM_S(1);
     
    1041851}
    1042852
    1043 void OPPROTO op_hsubpd(void)
    1044 {
    1045     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    1046     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     853void helper_hsubpd(XMMReg *d, XMMReg *s)
     854{
    1047855    XMMReg r;
    1048856    r.XMM_D(0) = d->XMM_D(0) - d->XMM_D(1);
     
    1051859}
    1052860
    1053 void OPPROTO op_addsubps(void)
    1054 {
    1055     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    1056     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     861void helper_addsubps(XMMReg *d, XMMReg *s)
     862{
    1057863    d->XMM_S(0) = d->XMM_S(0) - s->XMM_S(0);
    1058864    d->XMM_S(1) = d->XMM_S(1) + s->XMM_S(1);
     
    1061867}
    1062868
    1063 void OPPROTO op_addsubpd(void)
    1064 {
    1065     XMMReg *d = (XMMReg *)((char *)env + PARAM1);
    1066     XMMReg *s = (XMMReg *)((char *)env + PARAM2);
     869void helper_addsubpd(XMMReg *d, XMMReg *s)
     870{
    1067871    d->XMM_D(0) = d->XMM_D(0) - s->XMM_D(0);
    1068872    d->XMM_D(1) = d->XMM_D(1) + s->XMM_D(1);
     
    1070874
    1071875/* XXX: unordered */
    1072 #define SSE_OP_CMP(name, F)\
    1073 void OPPROTO op_ ## name ## ps (void)\
     876#define SSE_HELPER_CMP(name, F)\
     877void helper_ ## name ## ps (Reg *d, Reg *s)\
    1074878{\
    1075     Reg *d, *s;\
    1076     d = (Reg *)((char *)env + PARAM1);\
    1077     s = (Reg *)((char *)env + PARAM2);\
    1078879    d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
    1079880    d->XMM_L(1) = F(32, d->XMM_S(1), s->XMM_S(1));\
     
    1082883}\
    1083884\
    1084 void OPPROTO op_ ## name ## ss (void)\
     885void helper_ ## name ## ss (Reg *d, Reg *s)\
    1085886{\
    1086     Reg *d, *s;\
    1087     d = (Reg *)((char *)env + PARAM1);\
    1088     s = (Reg *)((char *)env + PARAM2);\
    1089887    d->XMM_L(0) = F(32, d->XMM_S(0), s->XMM_S(0));\
    1090888}\
    1091 void OPPROTO op_ ## name ## pd (void)\
     889void helper_ ## name ## pd (Reg *d, Reg *s)\
    1092890{\
    1093     Reg *d, *s;\
    1094     d = (Reg *)((char *)env + PARAM1);\
    1095     s = (Reg *)((char *)env + PARAM2);\
    1096891    d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
    1097892    d->XMM_Q(1) = F(64, d->XMM_D(1), s->XMM_D(1));\
    1098893}\
    1099894\
    1100 void OPPROTO op_ ## name ## sd (void)\
     895void helper_ ## name ## sd (Reg *d, Reg *s)\
    1101896{\
    1102     Reg *d, *s;\
    1103     d = (Reg *)((char *)env + PARAM1);\
    1104     s = (Reg *)((char *)env + PARAM2);\
    1105897    d->XMM_Q(0) = F(64, d->XMM_D(0), s->XMM_D(0));\
    1106898}
     
    1115907#define FPU_CMPORD(size, a, b) float ## size ## _unordered(a, b, &env->sse_status) ? 0 : -1
    1116908
    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)
     909SSE_HELPER_CMP(cmpeq, FPU_CMPEQ)
     910SSE_HELPER_CMP(cmplt, FPU_CMPLT)
     911SSE_HELPER_CMP(cmple, FPU_CMPLE)
     912SSE_HELPER_CMP(cmpunord, FPU_CMPUNORD)
     913SSE_HELPER_CMP(cmpneq, FPU_CMPNEQ)
     914SSE_HELPER_CMP(cmpnlt, FPU_CMPNLT)
     915SSE_HELPER_CMP(cmpnle, FPU_CMPNLE)
     916SSE_HELPER_CMP(cmpord, FPU_CMPORD)
    1125917
    1126918const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C};
    1127919
    1128 void OPPROTO op_ucomiss(void)
     920void helper_ucomiss(Reg *d, Reg *s)
    1129921{
    1130922    int ret;
    1131923    float32 s0, s1;
    1132     Reg *d, *s;
    1133     d = (Reg *)((char *)env + PARAM1);
    1134     s = (Reg *)((char *)env + PARAM2);
    1135924
    1136925    s0 = d->XMM_S(0);
     
    1141930}
    1142931
    1143 void OPPROTO op_comiss(void)
     932void helper_comiss(Reg *d, Reg *s)
    1144933{
    1145934    int ret;
    1146935    float32 s0, s1;
    1147     Reg *d, *s;
    1148     d = (Reg *)((char *)env + PARAM1);
    1149     s = (Reg *)((char *)env + PARAM2);
    1150936
    1151937    s0 = d->XMM_S(0);
     
    1156942}
    1157943
    1158 void OPPROTO op_ucomisd(void)
     944void helper_ucomisd(Reg *d, Reg *s)
    1159945{
    1160946    int ret;
    1161947    float64 d0, d1;
    1162     Reg *d, *s;
    1163     d = (Reg *)((char *)env + PARAM1);
    1164     s = (Reg *)((char *)env + PARAM2);
    1165948
    1166949    d0 = d->XMM_D(0);
     
    1171954}
    1172955
    1173 void OPPROTO op_comisd(void)
     956void helper_comisd(Reg *d, Reg *s)
    1174957{
    1175958    int ret;
    1176959    float64 d0, d1;
    1177     Reg *d, *s;
    1178     d = (Reg *)((char *)env + PARAM1);
    1179     s = (Reg *)((char *)env + PARAM2);
    1180960
    1181961    d0 = d->XMM_D(0);
     
    1186966}
    1187967
    1188 void OPPROTO op_movmskps(void)
     968uint32_t helper_movmskps(Reg *s)
    1189969{
    1190970    int b0, b1, b2, b3;
    1191     Reg *s;
    1192     s = (Reg *)((char *)env + PARAM1);
    1193971    b0 = s->XMM_L(0) >> 31;
    1194972    b1 = s->XMM_L(1) >> 31;
    1195973    b2 = s->XMM_L(2) >> 31;
    1196974    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
     978uint32_t helper_movmskpd(Reg *s)
    1201979{
    1202980    int b0, b1;
    1203     Reg *s;
    1204     s = (Reg *)((char *)env + PARAM1);
    1205981    b0 = s->XMM_L(1) >> 31;
    1206982    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
     988uint32_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
     1013void glue(helper_packsswb, SUFFIX) (Reg *d, Reg *s)
     1014{
     1015    Reg r;
    12581016
    12591017    r.B(0) = satsb((int16_t)d->W(0));
     
    12801038}
    12811039
    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);
     1040void glue(helper_packuswb, SUFFIX) (Reg *d, Reg *s)
     1041{
     1042    Reg r;
    12871043
    12881044    r.B(0) = satub((int16_t)d->W(0));
     
    13091065}
    13101066
    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);
     1067void glue(helper_packssdw, SUFFIX) (Reg *d, Reg *s)
     1068{
     1069    Reg r;
    13161070
    13171071    r.W(0) = satsw(d->L(0));
     
    13321086#define UNPCK_OP(base_name, base)                               \
    13331087                                                                \
    1334 void OPPROTO glue(op_punpck ## base_name ## bw, SUFFIX) (void)   \
     1088void glue(helper_punpck ## base_name ## bw, SUFFIX) (Reg *d, Reg *s)   \
    13351089{                                                               \
    1336     Reg r, *d, *s;                                              \
    1337     d = (Reg *)((char *)env + PARAM1);                          \
    1338     s = (Reg *)((char *)env + PARAM2);                          \
     1090    Reg r;                                              \
    13391091                                                                \
    13401092    r.B(0) = d->B((base << (SHIFT + 2)) + 0);                   \
     
    13591111}                                                               \
    13601112                                                                \
    1361 void OPPROTO glue(op_punpck ## base_name ## wd, SUFFIX) (void)   \
     1113void glue(helper_punpck ## base_name ## wd, SUFFIX) (Reg *d, Reg *s)   \
    13621114{                                                               \
    1363     Reg r, *d, *s;                                              \
    1364     d = (Reg *)((char *)env + PARAM1);                          \
    1365     s = (Reg *)((char *)env + PARAM2);                          \
     1115    Reg r;                                              \
    13661116                                                                \
    13671117    r.W(0) = d->W((base << (SHIFT + 1)) + 0);                   \
     
    13781128}                                                               \
    13791129                                                                \
    1380 void OPPROTO glue(op_punpck ## base_name ## dq, SUFFIX) (void)   \
     1130void glue(helper_punpck ## base_name ## dq, SUFFIX) (Reg *d, Reg *s)   \
    13811131{                                                               \
    1382     Reg r, *d, *s;                                              \
    1383     d = (Reg *)((char *)env + PARAM1);                          \
    1384     s = (Reg *)((char *)env + PARAM2);                          \
     1132    Reg r;                                              \
    13851133                                                                \
    13861134    r.L(0) = d->L((base << SHIFT) + 0);                         \
     
    13941142                                                                \
    13951143XMM_ONLY(                                                       \
    1396 void OPPROTO glue(op_punpck ## base_name ## qdq, SUFFIX) (void)  \
     1144void glue(helper_punpck ## base_name ## qdq, SUFFIX) (Reg *d, Reg *s)  \
    13971145{                                                               \
    1398     Reg r, *d, *s;                                              \
    1399     d = (Reg *)((char *)env + PARAM1);                          \
    1400     s = (Reg *)((char *)env + PARAM2);                          \
     1146    Reg r;                                              \
    14011147                                                                \
    14021148    r.Q(0) = d->Q(base);                                        \
     
    14081154UNPCK_OP(l, 0)
    14091155UNPCK_OP(h, 1)
     1156
     1157/* 3DNow! float ops */
     1158#if SHIFT == 0
     1159void 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
     1165void 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
     1171void 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
     1177void 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
     1183void 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
     1191void 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
     1197void 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
     1203void 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
     1209void 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
     1215void 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
     1223void 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
     1231void 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
     1237void 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
     1245void 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
     1253void 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
     1259void 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
     1267void 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
     1273void 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
     1279void 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 */
     1289void 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
     1300void 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
     1312void 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
     1320void 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
     1332void 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
     1354void 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
     1366void 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
     1374void 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
     1389SSE_HELPER_B(helper_pabsb, FABSB)
     1390SSE_HELPER_W(helper_pabsw, FABSW)
     1391SSE_HELPER_L(helper_pabsd, FABSL)
     1392
     1393#define FMULHRSW(d, s) ((int16_t) d * (int16_t) s + 0x4000) >> 15
     1394SSE_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
     1399SSE_HELPER_B(helper_psignb, FSIGNB)
     1400SSE_HELPER_W(helper_psignw, FSIGNW)
     1401SSE_HELPER_L(helper_psignd, FSIGNL)
     1402
     1403void 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)\
     1437void 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)\
     1464void 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
     1494SSE_HELPER_V(helper_pblendvb, B, 16, FBLENDVB)
     1495SSE_HELPER_V(helper_blendvps, L, 4, FBLENDVPS)
     1496SSE_HELPER_V(helper_blendvpd, Q, 2, FBLENDVPD)
     1497
     1498void 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)\
     1507void 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
     1523SSE_HELPER_F(helper_pmovsxbw, W, 8, (int8_t) s->B)
     1524SSE_HELPER_F(helper_pmovsxbd, L, 4, (int8_t) s->B)
     1525SSE_HELPER_F(helper_pmovsxbq, Q, 2, (int8_t) s->B)
     1526SSE_HELPER_F(helper_pmovsxwd, L, 4, (int16_t) s->W)
     1527SSE_HELPER_F(helper_pmovsxwq, Q, 2, (int16_t) s->W)
     1528SSE_HELPER_F(helper_pmovsxdq, Q, 2, (int32_t) s->L)
     1529SSE_HELPER_F(helper_pmovzxbw, W, 8, s->B)
     1530SSE_HELPER_F(helper_pmovzxbd, L, 4, s->B)
     1531SSE_HELPER_F(helper_pmovzxbq, Q, 2, s->B)
     1532SSE_HELPER_F(helper_pmovzxwd, L, 4, s->W)
     1533SSE_HELPER_F(helper_pmovzxwq, Q, 2, s->W)
     1534SSE_HELPER_F(helper_pmovzxdq, Q, 2, s->L)
     1535
     1536void 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
     1543SSE_HELPER_Q(helper_pcmpeqq, FCMPEQQ)
     1544
     1545void 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)
     1561SSE_HELPER_B(helper_pminsb, FMINSB)
     1562SSE_HELPER_L(helper_pminsd, FMINSD)
     1563SSE_HELPER_W(helper_pminuw, MIN)
     1564SSE_HELPER_L(helper_pminud, MIN)
     1565SSE_HELPER_B(helper_pmaxsb, FMAXSB)
     1566SSE_HELPER_L(helper_pmaxsd, FMAXSD)
     1567SSE_HELPER_W(helper_pmaxuw, MAX)
     1568SSE_HELPER_L(helper_pmaxud, MAX)
     1569
     1570#define FMULLD(d, s) (int32_t) d * (int32_t) s
     1571SSE_HELPER_L(helper_pmulld, FMULLD)
     1572
     1573void 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
     1598void 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
     1634void 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
     1668void 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
     1701void 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
     1735SSE_HELPER_I(helper_blendps, L, 4, FBLENDP)
     1736SSE_HELPER_I(helper_blendpd, Q, 2, FBLENDP)
     1737SSE_HELPER_I(helper_pblendw, W, 8, FBLENDP)
     1738
     1739void 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
     1765void 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
     1781void 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
     1802SSE_HELPER_Q(helper_pcmpgtq, FCMPGTQ)
     1803
     1804static 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
     1824static 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
     1838static 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
     1853static 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
     1920static 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
     1933static 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
     1946void 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
     1958void 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
     1978void 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
     1990void 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
     2012target_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))
     2025target_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
    14102047
    14112048#undef SHIFT
  • trunk/src/recompiler_new/translate-all.c

    r13230 r13337  
    4141#include "tcg.h"
    4242
    43 #ifndef VBOX
    4443/* code generation context */
    4544TCGContext tcg_ctx;
    46 #else
    47 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 #endif
    5545
    5646uint16_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;
     47TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
    6048
    6149target_ulong gen_opc_pc[OPC_BUF_SIZE];
     50uint16_t gen_opc_icount[OPC_BUF_SIZE];
    6251uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
    6352#if defined(TARGET_I386)
     
    8675}
    8776
    88 #ifndef VBOX
    8977void cpu_gen_init()
    9078{
     
    9381                  CPU_TEMP_BUF_NLONGS * sizeof(long));
    9482}
    95 #else
    96 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 #endif
    10483
    10584/* return non zero if the very first instruction is invalid so that
     
    11089*/
    11190int 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{
    11793    TCGContext *s = &tcg_ctx;
    118 #endif
    11994    uint8_t *gen_code_buf;
    12095    int gen_code_size;
     
    133108    tcg_func_start(s);
    134109
    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);
    140111#else /* !VBOX */
    141112    tcg_func_start(s);
    142113
    143     if (gen_intermediate_code(env, tb) < 0)
    144         return -1;
     114    gen_intermediate_code(env, tb);
    145115#endif /* !VBOX */
    146116
     
    196166                      void *puc)
    197167{
    198 #ifndef VBOX
    199168    TCGContext *s = &tcg_ctx;
    200 #else
    201     TCGContext *s = getCompilerCtx(env);
    202 #endif
    203169    int j;
    204170    unsigned long tc_ptr;
     
    213179
    214180#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);
    218182#else
    219183    gen_intermediate_code_pc(env, tb);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette