media/libvpx/vpx_ports/x86.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libvpx/vpx_ports/x86.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,243 @@
     1.4 +/*
     1.5 + *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
     1.6 + *
     1.7 + *  Use of this source code is governed by a BSD-style license
     1.8 + *  that can be found in the LICENSE file in the root of the source
     1.9 + *  tree. An additional intellectual property rights grant can be found
    1.10 + *  in the file PATENTS.  All contributing project authors may
    1.11 + *  be found in the AUTHORS file in the root of the source tree.
    1.12 + */
    1.13 +
    1.14 +
    1.15 +#ifndef VPX_PORTS_X86_H
    1.16 +#define VPX_PORTS_X86_H
    1.17 +#include <stdlib.h>
    1.18 +#include "vpx_config.h"
    1.19 +
    1.20 +typedef enum {
    1.21 +  VPX_CPU_UNKNOWN = -1,
    1.22 +  VPX_CPU_AMD,
    1.23 +  VPX_CPU_AMD_OLD,
    1.24 +  VPX_CPU_CENTAUR,
    1.25 +  VPX_CPU_CYRIX,
    1.26 +  VPX_CPU_INTEL,
    1.27 +  VPX_CPU_NEXGEN,
    1.28 +  VPX_CPU_NSC,
    1.29 +  VPX_CPU_RISE,
    1.30 +  VPX_CPU_SIS,
    1.31 +  VPX_CPU_TRANSMETA,
    1.32 +  VPX_CPU_TRANSMETA_OLD,
    1.33 +  VPX_CPU_UMC,
    1.34 +  VPX_CPU_VIA,
    1.35 +
    1.36 +  VPX_CPU_LAST
    1.37 +}  vpx_cpu_t;
    1.38 +
    1.39 +#if defined(__GNUC__) && __GNUC__ || defined(__ANDROID__)
    1.40 +#if ARCH_X86_64
    1.41 +#define cpuid(func,ax,bx,cx,dx)\
    1.42 +  __asm__ __volatile__ (\
    1.43 +                        "cpuid           \n\t" \
    1.44 +                        : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) \
    1.45 +                        : "a"  (func));
    1.46 +#else
    1.47 +#define cpuid(func,ax,bx,cx,dx)\
    1.48 +  __asm__ __volatile__ (\
    1.49 +                        "mov %%ebx, %%edi   \n\t" \
    1.50 +                        "cpuid              \n\t" \
    1.51 +                        "xchg %%edi, %%ebx  \n\t" \
    1.52 +                        : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
    1.53 +                        : "a" (func));
    1.54 +#endif
    1.55 +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* end __GNUC__ or __ANDROID__*/
    1.56 +#if ARCH_X86_64
    1.57 +#define cpuid(func,ax,bx,cx,dx)\
    1.58 +  asm volatile (\
    1.59 +                "xchg %rsi, %rbx \n\t" \
    1.60 +                "cpuid           \n\t" \
    1.61 +                "movl %ebx, %edi \n\t" \
    1.62 +                "xchg %rsi, %rbx \n\t" \
    1.63 +                : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
    1.64 +                : "a"  (func));
    1.65 +#else
    1.66 +#define cpuid(func,ax,bx,cx,dx)\
    1.67 +  asm volatile (\
    1.68 +                "pushl %ebx       \n\t" \
    1.69 +                "cpuid            \n\t" \
    1.70 +                "movl %ebx, %edi  \n\t" \
    1.71 +                "popl %ebx        \n\t" \
    1.72 +                : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
    1.73 +                : "a" (func));
    1.74 +#endif
    1.75 +#else /* end __SUNPRO__ */
    1.76 +#if ARCH_X86_64
    1.77 +void __cpuid(int CPUInfo[4], int info_type);
    1.78 +#pragma intrinsic(__cpuid)
    1.79 +#define cpuid(func,a,b,c,d) do{\
    1.80 +    int regs[4];\
    1.81 +    __cpuid(regs,func); a=regs[0];  b=regs[1];  c=regs[2];  d=regs[3];\
    1.82 +  } while(0)
    1.83 +#else
    1.84 +#define cpuid(func,a,b,c,d)\
    1.85 +  __asm mov eax, func\
    1.86 +  __asm cpuid\
    1.87 +  __asm mov a, eax\
    1.88 +  __asm mov b, ebx\
    1.89 +  __asm mov c, ecx\
    1.90 +  __asm mov d, edx
    1.91 +#endif
    1.92 +#endif /* end others */
    1.93 +
    1.94 +#define HAS_MMX     0x01
    1.95 +#define HAS_SSE     0x02
    1.96 +#define HAS_SSE2    0x04
    1.97 +#define HAS_SSE3    0x08
    1.98 +#define HAS_SSSE3   0x10
    1.99 +#define HAS_SSE4_1  0x20
   1.100 +#define HAS_AVX     0x40
   1.101 +#define HAS_AVX2    0x80
   1.102 +#ifndef BIT
   1.103 +#define BIT(n) (1<<n)
   1.104 +#endif
   1.105 +
   1.106 +static int
   1.107 +x86_simd_caps(void) {
   1.108 +  unsigned int flags = 0;
   1.109 +  unsigned int mask = ~0;
   1.110 +  unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx;
   1.111 +  char *env;
   1.112 +  (void)reg_ebx;
   1.113 +
   1.114 +  /* See if the CPU capabilities are being overridden by the environment */
   1.115 +  env = getenv("VPX_SIMD_CAPS");
   1.116 +
   1.117 +  if (env && *env)
   1.118 +    return (int)strtol(env, NULL, 0);
   1.119 +
   1.120 +  env = getenv("VPX_SIMD_CAPS_MASK");
   1.121 +
   1.122 +  if (env && *env)
   1.123 +    mask = strtol(env, NULL, 0);
   1.124 +
   1.125 +  /* Ensure that the CPUID instruction supports extended features */
   1.126 +  cpuid(0, reg_eax, reg_ebx, reg_ecx, reg_edx);
   1.127 +
   1.128 +  if (reg_eax < 1)
   1.129 +    return 0;
   1.130 +
   1.131 +  /* Get the standard feature flags */
   1.132 +  cpuid(1, reg_eax, reg_ebx, reg_ecx, reg_edx);
   1.133 +
   1.134 +  if (reg_edx & BIT(23)) flags |= HAS_MMX;
   1.135 +
   1.136 +  if (reg_edx & BIT(25)) flags |= HAS_SSE; /* aka xmm */
   1.137 +
   1.138 +  if (reg_edx & BIT(26)) flags |= HAS_SSE2; /* aka wmt */
   1.139 +
   1.140 +  if (reg_ecx & BIT(0)) flags |= HAS_SSE3;
   1.141 +
   1.142 +  if (reg_ecx & BIT(9)) flags |= HAS_SSSE3;
   1.143 +
   1.144 +  if (reg_ecx & BIT(19)) flags |= HAS_SSE4_1;
   1.145 +
   1.146 +  if (reg_ecx & BIT(28)) flags |= HAS_AVX;
   1.147 +
   1.148 +  if (reg_ebx & BIT(5)) flags |= HAS_AVX2;
   1.149 +
   1.150 +  return flags & mask;
   1.151 +}
   1.152 +
   1.153 +vpx_cpu_t vpx_x86_vendor(void);
   1.154 +
   1.155 +#if ARCH_X86_64 && defined(_MSC_VER)
   1.156 +unsigned __int64 __rdtsc(void);
   1.157 +#pragma intrinsic(__rdtsc)
   1.158 +#endif
   1.159 +static unsigned int
   1.160 +x86_readtsc(void) {
   1.161 +#if defined(__GNUC__) && __GNUC__
   1.162 +  unsigned int tsc;
   1.163 +  __asm__ __volatile__("rdtsc\n\t":"=a"(tsc):);
   1.164 +  return tsc;
   1.165 +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
   1.166 +  unsigned int tsc;
   1.167 +  asm volatile("rdtsc\n\t":"=a"(tsc):);
   1.168 +  return tsc;
   1.169 +#else
   1.170 +#if ARCH_X86_64
   1.171 +  return (unsigned int)__rdtsc();
   1.172 +#else
   1.173 +  __asm  rdtsc;
   1.174 +#endif
   1.175 +#endif
   1.176 +}
   1.177 +
   1.178 +
   1.179 +#if defined(__GNUC__) && __GNUC__
   1.180 +#define x86_pause_hint()\
   1.181 +  __asm__ __volatile__ ("pause \n\t")
   1.182 +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
   1.183 +#define x86_pause_hint()\
   1.184 +  asm volatile ("pause \n\t")
   1.185 +#else
   1.186 +#if ARCH_X86_64
   1.187 +#define x86_pause_hint()\
   1.188 +  _mm_pause();
   1.189 +#else
   1.190 +#define x86_pause_hint()\
   1.191 +  __asm pause
   1.192 +#endif
   1.193 +#endif
   1.194 +
   1.195 +#if defined(__GNUC__) && __GNUC__
   1.196 +static void
   1.197 +x87_set_control_word(unsigned short mode) {
   1.198 +  __asm__ __volatile__("fldcw %0" : : "m"(*&mode));
   1.199 +}
   1.200 +static unsigned short
   1.201 +x87_get_control_word(void) {
   1.202 +  unsigned short mode;
   1.203 +  __asm__ __volatile__("fstcw %0\n\t":"=m"(*&mode):);
   1.204 +    return mode;
   1.205 +}
   1.206 +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
   1.207 +static void
   1.208 +x87_set_control_word(unsigned short mode) {
   1.209 +  asm volatile("fldcw %0" : : "m"(*&mode));
   1.210 +}
   1.211 +static unsigned short
   1.212 +x87_get_control_word(void) {
   1.213 +  unsigned short mode;
   1.214 +  asm volatile("fstcw %0\n\t":"=m"(*&mode):);
   1.215 +  return mode;
   1.216 +}
   1.217 +#elif ARCH_X86_64
   1.218 +/* No fldcw intrinsics on Windows x64, punt to external asm */
   1.219 +extern void           vpx_winx64_fldcw(unsigned short mode);
   1.220 +extern unsigned short vpx_winx64_fstcw(void);
   1.221 +#define x87_set_control_word vpx_winx64_fldcw
   1.222 +#define x87_get_control_word vpx_winx64_fstcw
   1.223 +#else
   1.224 +static void
   1.225 +x87_set_control_word(unsigned short mode) {
   1.226 +  __asm { fldcw mode }
   1.227 +}
   1.228 +static unsigned short
   1.229 +x87_get_control_word(void) {
   1.230 +  unsigned short mode;
   1.231 +  __asm { fstcw mode }
   1.232 +  return mode;
   1.233 +}
   1.234 +#endif
   1.235 +
   1.236 +static unsigned short
   1.237 +x87_set_double_precision(void) {
   1.238 +  unsigned short mode = x87_get_control_word();
   1.239 +  x87_set_control_word((mode&~0x300) | 0x200);
   1.240 +  return mode;
   1.241 +}
   1.242 +
   1.243 +
   1.244 +extern void vpx_reset_mmx_state(void);
   1.245 +#endif
   1.246 +

mercurial