1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/*
2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *
4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Use of this source code is governed by a BSD-style license
5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  that can be found in the LICENSE file in the root of the source
6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  tree. An additional intellectual property rights grant can be found
7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  in the file PATENTS.  All contributing project authors may
8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  be found in the AUTHORS file in the root of the source tree.
9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */
10474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
11474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
128b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org#ifndef VPX_PORTS_X86_H_
138b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org#define VPX_PORTS_X86_H_
14474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <stdlib.h>
15167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org#include "vpx_config.h"
16474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
17dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#ifdef __cplusplus
18dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgextern "C" {
19dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
20dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgtypedef enum {
226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_UNKNOWN = -1,
236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_AMD,
246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_AMD_OLD,
256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_CENTAUR,
266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_CYRIX,
276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_INTEL,
286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_NEXGEN,
296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_NSC,
306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_RISE,
316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_SIS,
326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_TRANSMETA,
336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_TRANSMETA_OLD,
346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_UMC,
356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_VIA,
366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  VPX_CPU_LAST
38474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}  vpx_cpu_t;
39474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
4010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org#if defined(__GNUC__) && __GNUC__ || defined(__ANDROID__)
41474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if ARCH_X86_64
42d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define cpuid(func, func2, ax, bx, cx, dx)\
436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm__ __volatile__ (\
446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                        "cpuid           \n\t" \
456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                        : "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) \
46d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                        : "a" (func), "c" (func2));
47474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
48d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define cpuid(func, func2, ax, bx, cx, dx)\
496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm__ __volatile__ (\
506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                        "mov %%ebx, %%edi   \n\t" \
516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                        "cpuid              \n\t" \
526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                        "xchg %%edi, %%ebx  \n\t" \
536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                        : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
54d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                        : "a" (func), "c" (func2));
55474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
5610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* end __GNUC__ or __ANDROID__*/
575c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#if ARCH_X86_64
58d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define cpuid(func, func2, ax, bx, cx, dx)\
596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  asm volatile (\
606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                "xchg %rsi, %rbx \n\t" \
616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                "cpuid           \n\t" \
626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                "movl %ebx, %edi \n\t" \
636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                "xchg %rsi, %rbx \n\t" \
646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
65d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                : "a" (func), "c" (func2));
665c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#else
67d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define cpuid(func, func2, ax, bx, cx, dx)\
686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  asm volatile (\
696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                "pushl %ebx       \n\t" \
706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                "cpuid            \n\t" \
716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                "movl %ebx, %edi  \n\t" \
726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                "popl %ebx        \n\t" \
736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) \
74d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                : "a" (func), "c" (func2));
755c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#endif
7610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org#else /* end __SUNPRO__ */
77474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if ARCH_X86_64
78d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#if defined(_MSC_VER) && _MSC_VER > 1500
79d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid __cpuidex(int CPUInfo[4], int info_type, int ecxvalue);
80d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#pragma intrinsic(__cpuidex)
81d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define cpuid(func, func2, a, b, c, d) do {\
82d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    int regs[4];\
83d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    __cpuidex(regs, func, func2); \
84d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    a = regs[0];  b = regs[1];  c = regs[2];  d = regs[3];\
85d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  } while(0)
86d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#else
87474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid __cpuid(int CPUInfo[4], int info_type);
88474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#pragma intrinsic(__cpuid)
89d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define cpuid(func, func2, a, b, c, d) do {\
906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    int regs[4];\
91d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    __cpuid(regs, func); \
92d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    a = regs[0];  b = regs[1];  c = regs[2];  d = regs[3];\
93d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  } while (0)
94d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#endif
95474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
96d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define cpuid(func, func2, a, b, c, d)\
976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm mov eax, func\
98d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  __asm mov ecx, func2\
996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm cpuid\
1006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm mov a, eax\
1016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm mov b, ebx\
1026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm mov c, ecx\
1036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm mov d, edx
104474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
10510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org#endif /* end others */
106474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
107ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define HAS_MMX     0x01
108ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define HAS_SSE     0x02
109ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define HAS_SSE2    0x04
110ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define HAS_SSE3    0x08
111ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define HAS_SSSE3   0x10
112ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define HAS_SSE4_1  0x20
113ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define HAS_AVX     0x40
114ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#define HAS_AVX2    0x80
115474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#ifndef BIT
116474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define BIT(n) (1<<n)
117474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
118474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
119474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int
1206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgx86_simd_caps(void) {
1216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int flags = 0;
1226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int mask = ~0;
1236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int reg_eax, reg_ebx, reg_ecx, reg_edx;
1246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  char *env;
1256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  (void)reg_ebx;
126474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* See if the CPU capabilities are being overridden by the environment */
1286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  env = getenv("VPX_SIMD_CAPS");
129474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (env && *env)
1316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return (int)strtol(env, NULL, 0);
132474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  env = getenv("VPX_SIMD_CAPS_MASK");
134474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (env && *env)
1366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    mask = strtol(env, NULL, 0);
137474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Ensure that the CPUID instruction supports extended features */
139d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  cpuid(0, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
140474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (reg_eax < 1)
1426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return 0;
143474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Get the standard feature flags */
145d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  cpuid(1, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
146474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (reg_edx & BIT(23)) flags |= HAS_MMX;
148474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (reg_edx & BIT(25)) flags |= HAS_SSE; /* aka xmm */
150474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (reg_edx & BIT(26)) flags |= HAS_SSE2; /* aka wmt */
152474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
153ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  if (reg_ecx & BIT(0)) flags |= HAS_SSE3;
154474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
155ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  if (reg_ecx & BIT(9)) flags |= HAS_SSSE3;
156474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (reg_ecx & BIT(19)) flags |= HAS_SSE4_1;
158474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
159ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  if (reg_ecx & BIT(28)) flags |= HAS_AVX;
160ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org
161d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  /* Get the leaf 7 feature flags. Needed to check for AVX2 support */
162d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  reg_eax = 7;
163d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  reg_ecx = 0;
164d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  cpuid(7, 0, reg_eax, reg_ebx, reg_ecx, reg_edx);
165d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
166ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  if (reg_ebx & BIT(5)) flags |= HAS_AVX2;
167ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org
1686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return flags & mask;
169474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
170474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
171474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if ARCH_X86_64 && defined(_MSC_VER)
172474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgunsigned __int64 __rdtsc(void);
173474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#pragma intrinsic(__rdtsc)
174474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
175474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic unsigned int
1766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgx86_readtsc(void) {
177474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if defined(__GNUC__) && __GNUC__
1786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int tsc;
1796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm__ __volatile__("rdtsc\n\t":"=a"(tsc):);
1806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return tsc;
1815c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
1826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int tsc;
1836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  asm volatile("rdtsc\n\t":"=a"(tsc):);
1846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return tsc;
185474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
186474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if ARCH_X86_64
1876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return (unsigned int)__rdtsc();
188474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
1896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm  rdtsc;
190474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
191474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
192474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
193474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
194474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
195474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if defined(__GNUC__) && __GNUC__
196474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define x86_pause_hint()\
1976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm__ __volatile__ ("pause \n\t")
1985c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
1995c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#define x86_pause_hint()\
2006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  asm volatile ("pause \n\t")
201474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
202474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if ARCH_X86_64
203474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define x86_pause_hint()\
2046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  _mm_pause();
205474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
206474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define x86_pause_hint()\
2076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm pause
208474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
209474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
210474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
211474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if defined(__GNUC__) && __GNUC__
212474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void
2136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgx87_set_control_word(unsigned short mode) {
2146ffb5d8eaaa9cb68c354c46f375ccc5b9bc8b107jpet@google.com  __asm__ __volatile__("fldcw %0" : : "m"(*&mode));
215474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
216474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic unsigned short
2176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgx87_get_control_word(void) {
2186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned short mode;
2196ffb5d8eaaa9cb68c354c46f375ccc5b9bc8b107jpet@google.com  __asm__ __volatile__("fstcw %0\n\t":"=m"(*&mode):);
220474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return mode;
221474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
2225c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
2235c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.orgstatic void
2246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgx87_set_control_word(unsigned short mode) {
2256ffb5d8eaaa9cb68c354c46f375ccc5b9bc8b107jpet@google.com  asm volatile("fldcw %0" : : "m"(*&mode));
2266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
2276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic unsigned short
2286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgx87_get_control_word(void) {
2296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned short mode;
2306ffb5d8eaaa9cb68c354c46f375ccc5b9bc8b107jpet@google.com  asm volatile("fstcw %0\n\t":"=m"(*&mode):);
2316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return mode;
2325c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org}
233474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#elif ARCH_X86_64
234474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/* No fldcw intrinsics on Windows x64, punt to external asm */
235474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern void           vpx_winx64_fldcw(unsigned short mode);
236474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern unsigned short vpx_winx64_fstcw(void);
237474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define x87_set_control_word vpx_winx64_fldcw
238474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define x87_get_control_word vpx_winx64_fstcw
239474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
240474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void
2416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgx87_set_control_word(unsigned short mode) {
2426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm { fldcw mode }
243474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
244474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic unsigned short
2456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgx87_get_control_word(void) {
2466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned short mode;
2476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  __asm { fstcw mode }
2486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return mode;
249474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
250474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
251474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
252474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic unsigned short
2536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgx87_set_double_precision(void) {
2546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned short mode = x87_get_control_word();
2556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  x87_set_control_word((mode&~0x300) | 0x200);
2566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return mode;
257474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
258474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
259474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
260474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern void vpx_reset_mmx_state(void);
261474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
262dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#ifdef __cplusplus
263dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}  // extern "C"
264dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif
265dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
266dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#endif  // VPX_PORTS_X86_H_
267