annotate src/fftw-3.3.5/simd-support/x86-cpuid.h @ 84:08ae793730bd

Add null config files
author Chris Cannam
date Mon, 02 Mar 2020 14:03:47 +0000
parents 2cd0e3b3e1fd
children
rev   line source
Chris@42 1 /*
Chris@42 2 * Copyright (c) 2003, 2007-14 Matteo Frigo
Chris@42 3 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
Chris@42 4 *
Chris@42 5 * This program is free software; you can redistribute it and/or modify
Chris@42 6 * it under the terms of the GNU General Public License as published by
Chris@42 7 * the Free Software Foundation; either version 2 of the License, or
Chris@42 8 * (at your option) any later version.
Chris@42 9 *
Chris@42 10 * This program is distributed in the hope that it will be useful,
Chris@42 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@42 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@42 13 * GNU General Public License for more details.
Chris@42 14 *
Chris@42 15 * You should have received a copy of the GNU General Public License
Chris@42 16 * along with this program; if not, write to the Free Software
Chris@42 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@42 18 *
Chris@42 19 */
Chris@42 20
Chris@42 21
Chris@42 22 /* this code was kindly donated by Eric J. Korpela */
Chris@42 23
Chris@42 24 #ifdef _MSC_VER
Chris@42 25 #ifndef inline
Chris@42 26 #define inline __inline
Chris@42 27 #endif
Chris@42 28 #endif
Chris@42 29
Chris@42 30 static inline int is_386()
Chris@42 31 {
Chris@42 32 #ifdef _MSC_VER
Chris@42 33 unsigned int result,tst;
Chris@42 34 _asm {
Chris@42 35 pushfd
Chris@42 36 pop eax
Chris@42 37 mov edx,eax
Chris@42 38 xor eax,40000h
Chris@42 39 push eax
Chris@42 40 popfd
Chris@42 41 pushfd
Chris@42 42 pop eax
Chris@42 43 push edx
Chris@42 44 popfd
Chris@42 45 mov tst,edx
Chris@42 46 mov result,eax
Chris@42 47 }
Chris@42 48 #else
Chris@42 49 register unsigned int result,tst;
Chris@42 50 __asm__ (
Chris@42 51 "pushfl\n\t"
Chris@42 52 "popl %0\n\t"
Chris@42 53 "movl %0,%1\n\t"
Chris@42 54 "xorl $0x40000,%0\n\t"
Chris@42 55 "pushl %0\n\t"
Chris@42 56 "popfl\n\t"
Chris@42 57 "pushfl\n\t"
Chris@42 58 "popl %0\n\t"
Chris@42 59 "pushl %1\n\t"
Chris@42 60 "popfl"
Chris@42 61 : "=r" (result), "=r" (tst) /* output */
Chris@42 62 : /* no inputs */
Chris@42 63 );
Chris@42 64 #endif
Chris@42 65 return (result == tst);
Chris@42 66 }
Chris@42 67
Chris@42 68 static inline int has_cpuid()
Chris@42 69 {
Chris@42 70 #ifdef _MSC_VER
Chris@42 71 unsigned int result,tst;
Chris@42 72 _asm {
Chris@42 73 pushfd
Chris@42 74 pop eax
Chris@42 75 mov edx,eax
Chris@42 76 xor eax,200000h
Chris@42 77 push eax
Chris@42 78 popfd
Chris@42 79 pushfd
Chris@42 80 pop eax
Chris@42 81 push edx
Chris@42 82 popfd
Chris@42 83 mov tst,edx
Chris@42 84 mov result,eax
Chris@42 85 }
Chris@42 86 #else
Chris@42 87 register unsigned int result,tst;
Chris@42 88 __asm__ (
Chris@42 89 "pushfl\n\t"
Chris@42 90 "pop %0\n\t"
Chris@42 91 "movl %0,%1\n\t"
Chris@42 92 "xorl $0x200000,%0\n\t"
Chris@42 93 "pushl %0\n\t"
Chris@42 94 "popfl\n\t"
Chris@42 95 "pushfl\n\t"
Chris@42 96 "popl %0\n\t"
Chris@42 97 "pushl %1\n\t"
Chris@42 98 "popfl"
Chris@42 99 : "=r" (result), "=r" (tst) /* output */
Chris@42 100 : /* no inputs */
Chris@42 101 );
Chris@42 102 #endif
Chris@42 103 return (result != tst);
Chris@42 104 }
Chris@42 105
Chris@42 106 /* cpuid version to get all registers. Donated by Erik Lindahl from Gromacs. */
Chris@42 107 static inline void
Chris@42 108 cpuid_all(int level, int ecxval, int *eax, int *ebx, int *ecx, int *edx)
Chris@42 109 {
Chris@42 110 #if (defined _MSC_VER)
Chris@42 111 int CPUInfo[4];
Chris@42 112
Chris@42 113 # if (_MSC_VER > 1500) || (_MSC_VER == 1500 & _MSC_FULL_VER >= 150030729)
Chris@42 114 /* MSVC 9.0 SP1 or later */
Chris@42 115 __cpuidex(CPUInfo, level, ecxval);
Chris@42 116 rc = 0;
Chris@42 117 # else
Chris@42 118 __cpuid(CPUInfo, level);
Chris@42 119 /* Set an error code if the user wanted a non-zero ecxval, since we did not have cpuidex */
Chris@42 120 rc = (ecxval > 0) ? -1 : 0;
Chris@42 121 # endif
Chris@42 122 *eax = CPUInfo[0];
Chris@42 123 *ebx = CPUInfo[1];
Chris@42 124 *ecx = CPUInfo[2];
Chris@42 125 *edx = CPUInfo[3];
Chris@42 126
Chris@42 127 #else
Chris@42 128 /* Not MSVC */
Chris@42 129 *eax = level;
Chris@42 130 *ecx = ecxval;
Chris@42 131 *ebx = 0;
Chris@42 132 *edx = 0;
Chris@42 133 /* Avoid clobbering global offset table in 32-bit pic code (ebx) */
Chris@42 134 # if defined(__PIC__)
Chris@42 135 __asm__ ("xchgl %%ebx, %1 \n\t"
Chris@42 136 "cpuid \n\t"
Chris@42 137 "xchgl %%ebx, %1 \n\t"
Chris@42 138 : "+a" (*eax), "+r" (*ebx), "+c" (*ecx), "+d" (*edx));
Chris@42 139 # else
Chris@42 140 /* No need to save ebx if we are not in pic mode */
Chris@42 141 __asm__ ("cpuid \n\t"
Chris@42 142 : "+a" (*eax), "+b" (*ebx), "+c" (*ecx), "+d" (*edx));
Chris@42 143 # endif
Chris@42 144 #endif
Chris@42 145 }
Chris@42 146
Chris@42 147 static inline int cpuid_edx(int op)
Chris@42 148 {
Chris@42 149 # ifdef _MSC_VER
Chris@42 150 int result;
Chris@42 151 _asm {
Chris@42 152 push ebx
Chris@42 153 mov eax,op
Chris@42 154 cpuid
Chris@42 155 mov result,edx
Chris@42 156 pop ebx
Chris@42 157 }
Chris@42 158 return result;
Chris@42 159 # else
Chris@42 160 int eax, ecx, edx;
Chris@42 161
Chris@42 162 __asm__("push %%ebx\n\tcpuid\n\tpop %%ebx"
Chris@42 163 : "=a" (eax), "=c" (ecx), "=d" (edx)
Chris@42 164 : "a" (op));
Chris@42 165 return edx;
Chris@42 166 # endif
Chris@42 167 }
Chris@42 168
Chris@42 169 static inline int cpuid_ecx(int op)
Chris@42 170 {
Chris@42 171 # ifdef _MSC_VER
Chris@42 172 int result;
Chris@42 173 _asm {
Chris@42 174 push ebx
Chris@42 175 mov eax,op
Chris@42 176 cpuid
Chris@42 177 mov result,ecx
Chris@42 178 pop ebx
Chris@42 179 }
Chris@42 180 return result;
Chris@42 181 # else
Chris@42 182 int eax, ecx, edx;
Chris@42 183
Chris@42 184 __asm__("push %%ebx\n\tcpuid\n\tpop %%ebx"
Chris@42 185 : "=a" (eax), "=c" (ecx), "=d" (edx)
Chris@42 186 : "a" (op));
Chris@42 187 return ecx;
Chris@42 188 # endif
Chris@42 189 }
Chris@42 190
Chris@42 191 static inline int xgetbv_eax(int op)
Chris@42 192 {
Chris@42 193 # ifdef _MSC_VER
Chris@42 194 int veax, vedx;
Chris@42 195 _asm {
Chris@42 196 mov ecx,op
Chris@42 197 # if defined(__INTEL_COMPILER) || (_MSC_VER >= 1600)
Chris@42 198 xgetbv
Chris@42 199 # else
Chris@42 200 __emit 15
Chris@42 201 __emit 1
Chris@42 202 __emit 208
Chris@42 203 # endif
Chris@42 204 mov veax,eax
Chris@42 205 mov vedx,edx
Chris@42 206 }
Chris@42 207 return veax;
Chris@42 208 # else
Chris@42 209 int eax, edx;
Chris@42 210 __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (op));
Chris@42 211 return eax;
Chris@42 212 #endif
Chris@42 213 }