2 * Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
12 #ifndef VPX_PORTS_X86_H
13 #define VPX_PORTS_X86_H
17 #if defined(__GNUC__) && __GNUC__
19 #define cpuid(func,ax,bx,cx,dx)\
20 __asm__ __volatile__ (\
22 : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) \
25 #define cpuid(func,ax,bx,cx,dx)\
26 __asm__ __volatile__ (\
29 "movl %%ebx, %1 \n\t" \
31 : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx) \
36 void __cpuid(int CPUInfo[4], int info_type);
37 #pragma intrinsic(__cpuid)
38 #define cpuid(func,a,b,c,d) do{\
40 __cpuid(regs,func); a=regs[0]; b=regs[1]; c=regs[2]; d=regs[3];\
43 #define cpuid(func,a,b,c,d)\
57 #define HAS_SSSE3 0x10
65 unsigned int flags = 0;
66 unsigned int mask = ~0;
67 unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx;
71 /* See if the CPU capabilities are being overridden by the environment */
72 env = getenv("VPX_SIMD_CAPS");
75 return (int)strtol(env, NULL, 0);
77 env = getenv("VPX_SIMD_CAPS_MASK");
80 mask = strtol(env, NULL, 0);
82 /* Ensure that the CPUID instruction supports extended features */
83 cpuid(0, reg_eax, reg_ebx, reg_ecx, reg_edx);
88 /* Get the standard feature flags */
89 cpuid(1, reg_eax, reg_ebx, reg_ecx, reg_edx);
91 if (reg_edx & BIT(23)) flags |= HAS_MMX;
93 if (reg_edx & BIT(25)) flags |= HAS_SSE; /* aka xmm */
95 if (reg_edx & BIT(26)) flags |= HAS_SSE2; /* aka wmt */
97 if (reg_ecx & BIT(0)) flags |= HAS_SSE3;
99 if (reg_ecx & BIT(9)) flags |= HAS_SSSE3;
105 #if ARCH_X86_64 && defined(_MSC_VER)
106 unsigned __int64 __rdtsc(void);
107 #pragma intrinsic(__rdtsc)
112 #if defined(__GNUC__) && __GNUC__
114 __asm__ __volatile__("rdtsc\n\t":"=a"(tsc):);
126 #if defined(__GNUC__) && __GNUC__
127 #define x86_pause_hint()\
128 __asm__ __volatile__ ("pause \n\t")
131 /* No pause intrinsic for windows x64 */
132 #define x86_pause_hint()
134 #define x86_pause_hint()\
139 #if defined(__GNUC__) && __GNUC__
141 x87_set_control_word(unsigned short mode)
143 __asm__ __volatile__("fldcw %0" : : "m"(*&mode));
145 static unsigned short
146 x87_get_control_word(void)
149 __asm__ __volatile__("fstcw %0\n\t":"=m"(*&mode):);
153 /* No fldcw intrinsics on Windows x64, punt to external asm */
154 extern void vpx_winx64_fldcw(unsigned short mode);
155 extern unsigned short vpx_winx64_fstcw(void);
156 #define x87_set_control_word vpx_winx64_fldcw
157 #define x87_get_control_word vpx_winx64_fstcw
160 x87_set_control_word(unsigned short mode)
164 static unsigned short
165 x87_get_control_word(void)
173 static unsigned short
174 x87_set_double_precision(void)
176 unsigned short mode = x87_get_control_word();
177 x87_set_control_word((mode&~0x300) | 0x200);
182 extern void vpx_reset_mmx_state(void);