2 * Copyright 2011, Blender Foundation.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "util_system.h"
20 #include "util_types.h"
23 #if(!defined(FREE_WINDOWS))
27 #elif defined(__APPLE__)
28 #include <sys/sysctl.h>
29 #include <sys/types.h>
36 int system_cpu_thread_count()
38 static uint count = 0;
46 count = (uint)info.dwNumberOfProcessors;
47 #elif defined(__APPLE__)
48 size_t len = sizeof(count);
49 int mib[2] = { CTL_HW, HW_NCPU };
51 sysctl(mib, 2, &count, &len, NULL, 0);
53 count = (uint)sysconf(_SC_NPROCESSORS_ONLN);
62 #if !defined(_WIN32) || defined(FREE_WINDOWS)
63 static void __cpuid(int data[4], int selector)
66 asm("cpuid" : "=a" (data[0]), "=b" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
69 asm("pushl %%ebx \n\t"
72 "popl %%ebx \n\t" : "=a" (data[0]), "=r" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
74 data[0] = data[1] = data[2] = data[3] = 0;
80 static void replace_string(string& haystack, const string& needle, const string& other)
84 while((i = haystack.find(needle)) != string::npos)
85 haystack.replace(i, needle.length(), other);
88 string system_cpu_brand_string()
93 __cpuid(result, 0x80000000);
95 if(result[0] >= (int)0x80000004) {
96 __cpuid((int*)(buf+0), 0x80000002);
97 __cpuid((int*)(buf+16), 0x80000003);
98 __cpuid((int*)(buf+32), 0x80000004);
102 /* make it a bit more presentable */
103 replace_string(brand, "(TM)", "");
104 replace_string(brand, "(R)", "");
107 if((i = brand.find(" ")) != string::npos)
108 brand = brand.substr(0, i);
113 return "Unknown CPU";
116 int system_cpu_bits()
118 return (sizeof(void*)*8);
121 #if defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(_M_IX86)
123 struct CPUCapabilities {
139 bool system_cpu_support_optimized()
141 static CPUCapabilities caps;
142 static bool caps_init = false;
145 int result[4], num, num_ex;
147 memset(&caps, 0, sizeof(caps));
152 __cpuid(result, 0x80000000);
156 __cpuid(result, 0x00000001);
157 caps.mmx = (result[3] & ((int)1 << 23)) != 0;
158 caps.sse = (result[3] & ((int)1 << 25)) != 0;
159 caps.sse2 = (result[3] & ((int)1 << 26)) != 0;
160 caps.sse3 = (result[2] & ((int)1 << 0)) != 0;
162 caps.ssse3 = (result[2] & ((int)1 << 9)) != 0;
163 caps.sse41 = (result[2] & ((int)1 << 19)) != 0;
164 caps.sse42 = (result[2] & ((int)1 << 20)) != 0;
166 caps.avx = (result[2] & ((int)1 << 28)) != 0;
167 caps.fma3 = (result[2] & ((int)1 << 12)) != 0;
170 /*if(num_ex >= 0x80000001){
171 __cpuid(result, 0x80000001);
172 caps.x64 = (result[3] & ((int)1 << 29)) != 0;
173 caps.sse4a = (result[2] & ((int)1 << 6)) != 0;
174 caps.fma4 = (result[2] & ((int)1 << 16)) != 0;
175 caps.xop = (result[2] & ((int)1 << 11)) != 0;
181 /* optimization flags use these */
182 return caps.sse && caps.sse2 && caps.sse3;
187 bool system_cpu_support_optimized()