annotate src/fftw-3.3.8/simd-support/amd64-cpuid.h @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents d0c2a83c1364
children
rev   line source
Chris@82 1 /*
Chris@82 2 * Copyright (c) 2003, 2007-14 Matteo Frigo
Chris@82 3 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
Chris@82 4 *
Chris@82 5 * This program is free software; you can redistribute it and/or modify
Chris@82 6 * it under the terms of the GNU General Public License as published by
Chris@82 7 * the Free Software Foundation; either version 2 of the License, or
Chris@82 8 * (at your option) any later version.
Chris@82 9 *
Chris@82 10 * This program is distributed in the hope that it will be useful,
Chris@82 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@82 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@82 13 * GNU General Public License for more details.
Chris@82 14 *
Chris@82 15 * You should have received a copy of the GNU General Public License
Chris@82 16 * along with this program; if not, write to the Free Software
Chris@82 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@82 18 *
Chris@82 19 */
Chris@82 20
Chris@82 21
Chris@82 22 #ifdef _MSC_VER
Chris@82 23 #ifndef inline
Chris@82 24 #define inline __inline
Chris@82 25 #endif
Chris@82 26 #endif
Chris@82 27
Chris@82 28 #ifdef _MSC_VER
Chris@82 29 #include <intrin.h>
Chris@82 30 #if (_MSC_VER >= 1600) && !defined(__INTEL_COMPILER)
Chris@82 31 #include <immintrin.h>
Chris@82 32 #endif
Chris@82 33 #endif
Chris@82 34
Chris@82 35 /* cpuid version to get all registers. Donated by Erik Lindahl from Gromacs. */
Chris@82 36 static inline void
Chris@82 37 cpuid_all(int level, int ecxval, int *eax, int *ebx, int *ecx, int *edx)
Chris@82 38 {
Chris@82 39 # ifdef _MSC_VER
Chris@82 40 int CPUInfo[4];
Chris@82 41
Chris@82 42 #if (_MSC_VER > 1500) || (_MSC_VER == 1500 & _MSC_FULL_VER >= 150030729)
Chris@82 43 /* MSVC 9.0 SP1 or later */
Chris@82 44 __cpuidex(CPUInfo, level, ecxval);
Chris@82 45 #else
Chris@82 46 __cpuid(CPUInfo, level);
Chris@82 47 #endif
Chris@82 48 *eax = CPUInfo[0];
Chris@82 49 *ebx = CPUInfo[1];
Chris@82 50 *ecx = CPUInfo[2];
Chris@82 51 *edx = CPUInfo[3];
Chris@82 52
Chris@82 53 # else
Chris@82 54 /* Not MSVC */
Chris@82 55 *eax = level;
Chris@82 56 *ecx = ecxval;
Chris@82 57 *ebx = 0;
Chris@82 58 *edx = 0;
Chris@82 59 /* No need to save ebx if we are not in pic mode */
Chris@82 60 __asm__ ("cpuid \n\t"
Chris@82 61 : "+a" (*eax), "+b" (*ebx), "+c" (*ecx), "+d" (*edx));
Chris@82 62 # endif
Chris@82 63 }
Chris@82 64
Chris@82 65
Chris@82 66 static inline int cpuid_ecx(int op)
Chris@82 67 {
Chris@82 68 # ifdef _MSC_VER
Chris@82 69 # ifdef __INTEL_COMPILER
Chris@82 70 int result;
Chris@82 71 _asm {
Chris@82 72 push rbx
Chris@82 73 mov eax,op
Chris@82 74 cpuid
Chris@82 75 mov result,ecx
Chris@82 76 pop rbx
Chris@82 77 }
Chris@82 78 return result;
Chris@82 79 # else
Chris@82 80 int cpu_info[4];
Chris@82 81 __cpuid(cpu_info,op);
Chris@82 82 return cpu_info[2];
Chris@82 83 # endif
Chris@82 84 # else
Chris@82 85 int eax, ecx = 0, edx;
Chris@82 86
Chris@82 87 __asm__("pushq %%rbx\n\tcpuid\n\tpopq %%rbx"
Chris@82 88 : "=a" (eax), "+c" (ecx), "=d" (edx)
Chris@82 89 : "a" (op));
Chris@82 90 return ecx;
Chris@82 91 # endif
Chris@82 92 }
Chris@82 93
Chris@82 94 static inline int cpuid_ebx(int op)
Chris@82 95 {
Chris@82 96 # ifdef _MSC_VER
Chris@82 97 # ifdef __INTEL_COMPILER
Chris@82 98 int result;
Chris@82 99 _asm {
Chris@82 100 push rbx
Chris@82 101 mov eax,op
Chris@82 102 cpuid
Chris@82 103 mov result,ebx
Chris@82 104 pop rbx
Chris@82 105 }
Chris@82 106 return result;
Chris@82 107 # else
Chris@82 108 int cpu_info[4];
Chris@82 109 __cpuid(cpu_info,op);
Chris@82 110 return cpu_info[1];
Chris@82 111 # endif
Chris@82 112 # else
Chris@82 113 int eax, ecx = 0, edx;
Chris@82 114
Chris@82 115 __asm__("pushq %%rbx\n\tcpuid\nmov %%ebx,%%ecx\n\tpopq %%rbx"
Chris@82 116 : "=a" (eax), "+c" (ecx), "=d" (edx)
Chris@82 117 : "a" (op));
Chris@82 118 return ecx;
Chris@82 119 # endif
Chris@82 120 }
Chris@82 121
Chris@82 122 static inline int xgetbv_eax(int op)
Chris@82 123 {
Chris@82 124 # ifdef _MSC_VER
Chris@82 125 # ifdef __INTEL_COMPILER
Chris@82 126 int veax, vedx;
Chris@82 127 _asm {
Chris@82 128 mov ecx,op
Chris@82 129 xgetbv
Chris@82 130 mov veax,eax
Chris@82 131 mov vedx,edx
Chris@82 132 }
Chris@82 133 return veax;
Chris@82 134 # else
Chris@82 135 # if defined(_MSC_VER) && (_MSC_VER >= 1600)
Chris@82 136 unsigned __int64 result;
Chris@82 137 result = _xgetbv(op);
Chris@82 138 return (int)result;
Chris@82 139 # else
Chris@82 140 # error "Need at least Visual Studio 10 SP1 for AVX support"
Chris@82 141 # endif
Chris@82 142 # endif
Chris@82 143 # else
Chris@82 144 int eax, edx;
Chris@82 145 __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (op));
Chris@82 146 return eax;
Chris@82 147 #endif
Chris@82 148 }