2 * Copyright (c) 2010 The WebM 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
15 #include "vpx_config.h"
29 VPX_CPU_TRANSMETA_OLD,
36 #if defined(__GNUC__) && __GNUC__
38 #define cpuid(func,ax,bx,cx,dx)\
39 __asm__ __volatile__ (\
41 : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) \
44 #define cpuid(func,ax,bx,cx,dx)\
45 __asm__ __volatile__ (\
46 "mov %%ebx, %%edi \n\t" \
48 "xchg %%edi, %%ebx \n\t" \
49 : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
52 #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
54 #define cpuid(func,ax,bx,cx,dx)\
56 "xchg %rsi, %rbx \n\t" \
58 "movl %ebx, %edi \n\t" \
59 "xchg %rsi, %rbx \n\t" \
60 : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
63 #define cpuid(func,ax,bx,cx,dx)\
67 "movl %ebx, %edi \n\t" \
69 : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
74 void __cpuid(int CPUInfo[4], int info_type);
75 #pragma intrinsic(__cpuid)
76 #define cpuid(func,a,b,c,d) do{\
78 __cpuid(regs,func); a=regs[0]; b=regs[1]; c=regs[2]; d=regs[3];\
81 #define cpuid(func,a,b,c,d)\
95 #define HAS_SSSE3 0x10
96 #define HAS_SSE4_1 0x20
102 x86_simd_caps(void) {
103 unsigned int flags = 0;
104 unsigned int mask = ~0;
105 unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx;
109 /* See if the CPU capabilities are being overridden by the environment */
110 env = getenv("VPX_SIMD_CAPS");
113 return (int)strtol(env, NULL, 0);
115 env = getenv("VPX_SIMD_CAPS_MASK");
118 mask = strtol(env, NULL, 0);
120 /* Ensure that the CPUID instruction supports extended features */
121 cpuid(0, reg_eax, reg_ebx, reg_ecx, reg_edx);
126 /* Get the standard feature flags */
127 cpuid(1, reg_eax, reg_ebx, reg_ecx, reg_edx);
129 if (reg_edx & BIT(23)) flags |= HAS_MMX;
131 if (reg_edx & BIT(25)) flags |= HAS_SSE; /* aka xmm */
133 if (reg_edx & BIT(26)) flags |= HAS_SSE2; /* aka wmt */
135 if (reg_ecx & BIT(0)) flags |= HAS_SSE3;
137 if (reg_ecx & BIT(9)) flags |= HAS_SSSE3;
139 if (reg_ecx & BIT(19)) flags |= HAS_SSE4_1;
144 vpx_cpu_t vpx_x86_vendor(void);
146 #if ARCH_X86_64 && defined(_MSC_VER)
147 unsigned __int64 __rdtsc(void);
148 #pragma intrinsic(__rdtsc)
152 #if defined(__GNUC__) && __GNUC__
154 __asm__ __volatile__("rdtsc\n\t":"=a"(tsc):);
156 #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
158 asm volatile("rdtsc\n\t":"=a"(tsc):);
162 return (unsigned int)__rdtsc();
170 #if defined(__GNUC__) && __GNUC__
171 #define x86_pause_hint()\
172 __asm__ __volatile__ ("pause \n\t")
173 #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
174 #define x86_pause_hint()\
175 asm volatile ("pause \n\t")
178 #define x86_pause_hint()\
181 #define x86_pause_hint()\
186 #if defined(__GNUC__) && __GNUC__
188 x87_set_control_word(unsigned short mode) {
189 __asm__ __volatile__("fldcw %0" : : "m"( *&mode));
191 static unsigned short
192 x87_get_control_word(void) {
194 __asm__ __volatile__("fstcw %0\n\t":"=m"( *&mode):);
197 #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
199 x87_set_control_word(unsigned short mode)
201 asm volatile("fldcw %0" : : "m"(*&mode));
203 static unsigned short
204 x87_get_control_word(void)
207 asm volatile("fstcw %0\n\t":"=m"(*&mode):);
210 #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
212 x87_set_control_word(unsigned short mode) {
213 asm volatile("fldcw %0" : : "m"( *&mode));
215 static unsigned short
216 x87_get_control_word(void) {
218 asm volatile("fstcw %0\n\t":"=m"( *&mode):);
222 /* No fldcw intrinsics on Windows x64, punt to external asm */
223 extern void vpx_winx64_fldcw(unsigned short mode);
224 extern unsigned short vpx_winx64_fstcw(void);
225 #define x87_set_control_word vpx_winx64_fldcw
226 #define x87_get_control_word vpx_winx64_fstcw
229 x87_set_control_word(unsigned short mode) {
232 static unsigned short
233 x87_get_control_word(void) {
240 static unsigned short
241 x87_set_double_precision(void) {
242 unsigned short mode = x87_get_control_word();
243 x87_set_control_word((mode&~0x300) | 0x200);
248 extern void vpx_reset_mmx_state(void);