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 +