GNU Radio 3.6.5 C++ API
|
00001 /* 00002 * Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. 00003 * 00004 * This file is free software; you can redistribute it and/or modify it 00005 * under the terms of the GNU General Public License as published by the 00006 * Free Software Foundation; either version 3, or (at your option) any 00007 * later version. 00008 * 00009 * This file is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * General Public License for more details. 00013 * 00014 * Under Section 7 of GPL version 3, you are granted additional 00015 * permissions described in the GCC Runtime Library Exception, version 00016 * 3.1, as published by the Free Software Foundation. 00017 * 00018 * You should have received a copy of the GNU General Public License and 00019 * a copy of the GCC Runtime Library Exception along with this program; 00020 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00021 * <http://www.gnu.org/licenses/>. 00022 */ 00023 00024 /* %ecx */ 00025 #define bit_SSE3 (1 << 0) 00026 #define bit_PCLMUL (1 << 1) 00027 #define bit_SSSE3 (1 << 9) 00028 #define bit_FMA (1 << 12) 00029 #define bit_CMPXCHG16B (1 << 13) 00030 #define bit_SSE4_1 (1 << 19) 00031 #define bit_SSE4_2 (1 << 20) 00032 #define bit_MOVBE (1 << 22) 00033 #define bit_POPCNT (1 << 23) 00034 #define bit_AES (1 << 25) 00035 #define bit_XSAVE (1 << 26) 00036 #define bit_OSXSAVE (1 << 27) 00037 #define bit_AVX (1 << 28) 00038 #define bit_F16C (1 << 29) 00039 #define bit_RDRND (1 << 30) 00040 00041 /* %edx */ 00042 #define bit_CMPXCHG8B (1 << 8) 00043 #define bit_CMOV (1 << 15) 00044 #define bit_MMX (1 << 23) 00045 #define bit_FXSAVE (1 << 24) 00046 #define bit_SSE (1 << 25) 00047 #define bit_SSE2 (1 << 26) 00048 00049 /* Extended Features */ 00050 /* %ecx */ 00051 #define bit_LAHF_LM (1 << 0) 00052 #define bit_ABM (1 << 5) 00053 #define bit_SSE4a (1 << 6) 00054 #define bit_XOP (1 << 11) 00055 #define bit_LWP (1 << 15) 00056 #define bit_FMA4 (1 << 16) 00057 #define bit_TBM (1 << 21) 00058 00059 /* %edx */ 00060 #define bit_MMXEXT (1 << 22) 00061 #define bit_LM (1 << 29) 00062 #define bit_3DNOWP (1 << 30) 00063 #define bit_3DNOW (1 << 31) 00064 00065 /* Extended Features (%eax == 7) */ 00066 #define bit_FSGSBASE (1 << 0) 00067 #define bit_BMI (1 << 3) 00068 00069 #if defined(__i386__) && defined(__PIC__) 00070 /* %ebx may be the PIC register. */ 00071 #if __GNUC__ >= 3 00072 #define __cpuid(level, a, b, c, d) \ 00073 __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ 00074 "cpuid\n\t" \ 00075 "xchg{l}\t{%%}ebx, %1\n\t" \ 00076 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ 00077 : "0" (level)) 00078 00079 #define __cpuid_count(level, count, a, b, c, d) \ 00080 __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ 00081 "cpuid\n\t" \ 00082 "xchg{l}\t{%%}ebx, %1\n\t" \ 00083 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ 00084 : "0" (level), "2" (count)) 00085 #else 00086 /* Host GCCs older than 3.0 weren't supporting Intel asm syntax 00087 nor alternatives in i386 code. */ 00088 #define __cpuid(level, a, b, c, d) \ 00089 __asm__ ("xchgl\t%%ebx, %1\n\t" \ 00090 "cpuid\n\t" \ 00091 "xchgl\t%%ebx, %1\n\t" \ 00092 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ 00093 : "0" (level)) 00094 00095 #define __cpuid_count(level, count, a, b, c, d) \ 00096 __asm__ ("xchgl\t%%ebx, %1\n\t" \ 00097 "cpuid\n\t" \ 00098 "xchgl\t%%ebx, %1\n\t" \ 00099 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ 00100 : "0" (level), "2" (count)) 00101 #endif 00102 #else 00103 #define __cpuid(level, a, b, c, d) \ 00104 __asm__ ("cpuid\n\t" \ 00105 : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 00106 : "0" (level)) 00107 00108 #define __cpuid_count(level, count, a, b, c, d) \ 00109 __asm__ ("cpuid\n\t" \ 00110 : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 00111 : "0" (level), "2" (count)) 00112 #endif 00113 00114 /* Return highest supported input value for cpuid instruction. ext can 00115 be either 0x0 or 0x8000000 to return highest supported value for 00116 basic or extended cpuid information. Function returns 0 if cpuid 00117 is not supported or whatever cpuid returns in eax register. If sig 00118 pointer is non-null, then first four bytes of the signature 00119 (as found in ebx register) are returned in location pointed by sig. */ 00120 00121 static __inline unsigned int 00122 __get_cpuid_max (unsigned int __ext, unsigned int *__sig) 00123 { 00124 unsigned int __eax, __ebx, __ecx, __edx; 00125 00126 #ifndef __x86_64__ 00127 /* See if we can use cpuid. On AMD64 we always can. */ 00128 #if __GNUC__ >= 3 00129 __asm__ ("pushf{l|d}\n\t" 00130 "pushf{l|d}\n\t" 00131 "pop{l}\t%0\n\t" 00132 "mov{l}\t{%0, %1|%1, %0}\n\t" 00133 "xor{l}\t{%2, %0|%0, %2}\n\t" 00134 "push{l}\t%0\n\t" 00135 "popf{l|d}\n\t" 00136 "pushf{l|d}\n\t" 00137 "pop{l}\t%0\n\t" 00138 "popf{l|d}\n\t" 00139 : "=&r" (__eax), "=&r" (__ebx) 00140 : "i" (0x00200000)); 00141 #else 00142 /* Host GCCs older than 3.0 weren't supporting Intel asm syntax 00143 nor alternatives in i386 code. */ 00144 __asm__ ("pushfl\n\t" 00145 "pushfl\n\t" 00146 "popl\t%0\n\t" 00147 "movl\t%0, %1\n\t" 00148 "xorl\t%2, %0\n\t" 00149 "pushl\t%0\n\t" 00150 "popfl\n\t" 00151 "pushfl\n\t" 00152 "popl\t%0\n\t" 00153 "popfl\n\t" 00154 : "=&r" (__eax), "=&r" (__ebx) 00155 : "i" (0x00200000)); 00156 #endif 00157 00158 if (!((__eax ^ __ebx) & 0x00200000)) 00159 return 0; 00160 #endif 00161 00162 /* Host supports cpuid. Return highest supported cpuid input value. */ 00163 __cpuid (__ext, __eax, __ebx, __ecx, __edx); 00164 00165 if (__sig) 00166 *__sig = __ebx; 00167 00168 return __eax; 00169 } 00170 00171 /* Return cpuid data for requested cpuid level, as found in returned 00172 eax, ebx, ecx and edx registers. The function checks if cpuid is 00173 supported and returns 1 for valid cpuid information or 0 for 00174 unsupported cpuid level. All pointers are required to be non-null. */ 00175 00176 static __inline int 00177 __get_cpuid (unsigned int __level, 00178 unsigned int *__eax, unsigned int *__ebx, 00179 unsigned int *__ecx, unsigned int *__edx) 00180 { 00181 unsigned int __ext = __level & 0x80000000; 00182 00183 if (__get_cpuid_max (__ext, 0) < __level) 00184 return 0; 00185 00186 __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx); 00187 return 1; 00188 }