/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


#ifndef VPX_PORTS_X86_H
#define VPX_PORTS_X86_H
#include <stdlib.h>
#include "config.h"

typedef enum
{
    VPX_CPU_UNKNOWN = -1,
    VPX_CPU_AMD,
    VPX_CPU_AMD_OLD,
    VPX_CPU_CENTAUR,
    VPX_CPU_CYRIX,
    VPX_CPU_INTEL,
    VPX_CPU_NEXGEN,
    VPX_CPU_NSC,
    VPX_CPU_RISE,
    VPX_CPU_SIS,
    VPX_CPU_TRANSMETA,
    VPX_CPU_TRANSMETA_OLD,
    VPX_CPU_UMC,
    VPX_CPU_VIA,

    VPX_CPU_LAST
}  vpx_cpu_t;

#if defined(__GNUC__) && __GNUC__
#if ARCH_X86_64
#define cpuid(func,ax,bx,cx,dx)\
    __asm__ __volatile__ (\
                          "cpuid           \n\t" \
                          : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) \
                          : "a"  (func));
#else
#define cpuid(func,ax,bx,cx,dx)\
    __asm__ __volatile__ (\
                          "mov %%ebx, %%edi   \n\t" \
                          "cpuid              \n\t" \
                          "xchg %%edi, %%ebx  \n\t" \
                          : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
                          : "a" (func));
#endif
#else
#if ARCH_X86_64
void __cpuid(int CPUInfo[4], int info_type);
#pragma intrinsic(__cpuid)
#define cpuid(func,a,b,c,d) do{\
        int regs[4];\
        __cpuid(regs,func); a=regs[0];  b=regs[1];  c=regs[2];  d=regs[3];\
    } while(0)
#else
#define cpuid(func,a,b,c,d)\
    __asm mov eax, func\
    __asm cpuid\
    __asm mov a, eax\
    __asm mov b, ebx\
    __asm mov c, ecx\
    __asm mov d, edx
#endif
#endif

#define HAS_MMX   0x01
#define HAS_SSE   0x02
#define HAS_SSE2  0x04
#define HAS_SSE3  0x08
#define HAS_SSSE3 0x10
#define HAS_SSE4_1 0x20
#ifndef BIT
#define BIT(n) (1<<n)
#endif

static int
x86_simd_caps(void)
{
    unsigned int flags = 0;
    unsigned int mask = ~0;
    unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx;
    char *env;
    (void)reg_ebx;

    /* See if the CPU capabilities are being overridden by the environment */
    env = getenv("VPX_SIMD_CAPS");

    if (env && *env)
        return (int)strtol(env, NULL, 0);

    env = getenv("VPX_SIMD_CAPS_MASK");

    if (env && *env)
        mask = strtol(env, NULL, 0);

    /* Ensure that the CPUID instruction supports extended features */
    cpuid(0, reg_eax, reg_ebx, reg_ecx, reg_edx);

    if (reg_eax < 1)
        return 0;

    /* Get the standard feature flags */
    cpuid(1, reg_eax, reg_ebx, reg_ecx, reg_edx);

    if (reg_edx & BIT(23)) flags |= HAS_MMX;

    if (reg_edx & BIT(25)) flags |= HAS_SSE; /* aka xmm */

    if (reg_edx & BIT(26)) flags |= HAS_SSE2; /* aka wmt */

    if (reg_ecx & BIT(0))  flags |= HAS_SSE3;

    if (reg_ecx & BIT(9))  flags |= HAS_SSSE3;

    if (reg_ecx & BIT(19)) flags |= HAS_SSE4_1;

    return flags & mask;
}

vpx_cpu_t vpx_x86_vendor(void);

#if ARCH_X86_64 && defined(_MSC_VER)
unsigned __int64 __rdtsc(void);
#pragma intrinsic(__rdtsc)
#endif
static unsigned int
x86_readtsc(void)
{
#if defined(__GNUC__) && __GNUC__
    unsigned int tsc;
    __asm__ __volatile__("rdtsc\n\t":"=a"(tsc):);
    return tsc;
#else
#if ARCH_X86_64
    return __rdtsc();
#else
    __asm  rdtsc;
#endif
#endif
}


#if defined(__GNUC__) && __GNUC__
#define x86_pause_hint()\
    __asm__ __volatile__ ("pause \n\t")
#else
#if ARCH_X86_64
#define x86_pause_hint()\
    _mm_pause();
#else
#define x86_pause_hint()\
    __asm pause
#endif
#endif

#if defined(__GNUC__) && __GNUC__
static void
x87_set_control_word(unsigned short mode)
{
    __asm__ __volatile__("fldcw %0" : : "m"(*&mode));
}
static unsigned short
x87_get_control_word(void)
{
    unsigned short mode;
    __asm__ __volatile__("fstcw %0\n\t":"=m"(*&mode):);
    return mode;
}
#elif ARCH_X86_64
/* No fldcw intrinsics on Windows x64, punt to external asm */
extern void           vpx_winx64_fldcw(unsigned short mode);
extern unsigned short vpx_winx64_fstcw(void);
#define x87_set_control_word vpx_winx64_fldcw
#define x87_get_control_word vpx_winx64_fstcw
#else
static void
x87_set_control_word(unsigned short mode)
{
    __asm { fldcw mode }
}
static unsigned short
x87_get_control_word(void)
{
    unsigned short mode;
    __asm { fstcw mode }
    return mode;
}
#endif

static unsigned short
x87_set_double_precision(void)
{
    unsigned short mode = x87_get_control_word();
    x87_set_control_word((mode&~0x300) | 0x200);
    return mode;
}


extern void vpx_reset_mmx_state(void);
#endif

