GNU Radio 3.4.2 C++ API
|
00001 /* 00002 * Copyright (C) 2007, 2008, 2009 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 00039 /* %edx */ 00040 #define bit_CMPXCHG8B (1 << 8) 00041 #define bit_CMOV (1 << 15) 00042 #define bit_MMX (1 << 23) 00043 #define bit_FXSAVE (1 << 24) 00044 #define bit_SSE (1 << 25) 00045 #define bit_SSE2 (1 << 26) 00046 00047 /* Extended Features */ 00048 /* %ecx */ 00049 #define bit_LAHF_LM (1 << 0) 00050 #define bit_SSE4a (1 << 6) 00051 #define bit_SSE5 (1 << 11) 00052 00053 /* %edx */ 00054 #define bit_LM (1 << 29) 00055 #define bit_3DNOWP (1 << 30) 00056 #define bit_3DNOW (1 << 31) 00057 00058 00059 #if defined(__i386__) && defined(__PIC__) 00060 /* %ebx may be the PIC register. */ 00061 #if __GNUC__ >= 3 00062 #define __cpuid(level, a, b, c, d) \ 00063 __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ 00064 "cpuid\n\t" \ 00065 "xchg{l}\t{%%}ebx, %1\n\t" \ 00066 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ 00067 : "0" (level)) 00068 00069 #define __cpuid_count(level, count, a, b, c, d) \ 00070 __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ 00071 "cpuid\n\t" \ 00072 "xchg{l}\t{%%}ebx, %1\n\t" \ 00073 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ 00074 : "0" (level), "2" (count)) 00075 #else 00076 /* Host GCCs older than 3.0 weren't supporting Intel asm syntax 00077 nor alternatives in i386 code. */ 00078 #define __cpuid(level, a, b, c, d) \ 00079 __asm__ ("xchgl\t%%ebx, %1\n\t" \ 00080 "cpuid\n\t" \ 00081 "xchgl\t%%ebx, %1\n\t" \ 00082 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ 00083 : "0" (level)) 00084 00085 #define __cpuid_count(level, count, a, b, c, d) \ 00086 __asm__ ("xchgl\t%%ebx, %1\n\t" \ 00087 "cpuid\n\t" \ 00088 "xchgl\t%%ebx, %1\n\t" \ 00089 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ 00090 : "0" (level), "2" (count)) 00091 #endif 00092 #else 00093 #define __cpuid(level, a, b, c, d) \ 00094 __asm__ ("cpuid\n\t" \ 00095 : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 00096 : "0" (level)) 00097 00098 #define __cpuid_count(level, count, a, b, c, d) \ 00099 __asm__ ("cpuid\n\t" \ 00100 : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 00101 : "0" (level), "2" (count)) 00102 #endif 00103 00104 /* Return highest supported input value for cpuid instruction. ext can 00105 be either 0x0 or 0x8000000 to return highest supported value for 00106 basic or extended cpuid information. Function returns 0 if cpuid 00107 is not supported or whatever cpuid returns in eax register. If sig 00108 pointer is non-null, then first four bytes of the signature 00109 (as found in ebx register) are returned in location pointed by sig. */ 00110 00111 static __inline unsigned int 00112 __get_cpuid_max (unsigned int __ext, unsigned int *__sig) 00113 { 00114 unsigned int __eax, __ebx, __ecx, __edx; 00115 00116 #ifndef __x86_64__ 00117 #if __GNUC__ >= 3 00118 /* See if we can use cpuid. On AMD64 we always can. */ 00119 __asm__ ("pushf{l|d}\n\t" 00120 "pushf{l|d}\n\t" 00121 "pop{l}\t%0\n\t" 00122 "mov{l}\t{%0, %1|%1, %0}\n\t" 00123 "xor{l}\t{%2, %0|%0, %2}\n\t" 00124 "push{l}\t%0\n\t" 00125 "popf{l|d}\n\t" 00126 "pushf{l|d}\n\t" 00127 "pop{l}\t%0\n\t" 00128 "popf{l|d}\n\t" 00129 : "=&r" (__eax), "=&r" (__ebx) 00130 : "i" (0x00200000)); 00131 #else 00132 /* Host GCCs older than 3.0 weren't supporting Intel asm syntax 00133 nor alternatives in i386 code. */ 00134 __asm__ ("pushfl\n\t" 00135 "pushfl\n\t" 00136 "popl\t%0\n\t" 00137 "movl\t%0, %1\n\t" 00138 "xorl\t%2, %0\n\t" 00139 "pushl\t%0\n\t" 00140 "popfl\n\t" 00141 "pushfl\n\t" 00142 "popl\t%0\n\t" 00143 "popfl\n\t" 00144 : "=&r" (__eax), "=&r" (__ebx) 00145 : "i" (0x00200000)); 00146 #endif 00147 00148 if (!((__eax ^ __ebx) & 0x00200000)) 00149 return 0; 00150 #endif 00151 00152 /* Host supports cpuid. Return highest supported cpuid input value. */ 00153 __cpuid (__ext, __eax, __ebx, __ecx, __edx); 00154 00155 if (__sig) 00156 *__sig = __ebx; 00157 00158 return __eax; 00159 } 00160 00161 /* Return cpuid data for requested cpuid level, as found in returned 00162 eax, ebx, ecx and edx registers. The function checks if cpuid is 00163 supported and returns 1 for valid cpuid information or 0 for 00164 unsupported cpuid level. All pointers are required to be non-null. */ 00165 00166 static __inline int 00167 __get_cpuid (unsigned int __level, 00168 unsigned int *__eax, unsigned int *__ebx, 00169 unsigned int *__ecx, unsigned int *__edx) 00170 { 00171 unsigned int __ext = __level & 0x80000000; 00172 00173 if (__get_cpuid_max (__ext, 0) < __level) 00174 return 0; 00175 00176 __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx); 00177 return 1; 00178 }