1 /* 2 * Copyright (C) 2009 David McPaul 3 * 4 * includes code from sysinfo.c which is 5 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. 6 * Copyright (c) 2002, Carlos Hasan, for Haiku. 7 * 8 * All rights reserved. Distributed under the terms of the MIT License. 9 */ 10 11 12 #include "CpuCapabilities.h" 13 14 #include <string.h> 15 #include <cpu_type.h> 16 17 18 CPUCapabilities::~CPUCapabilities() 19 { 20 } 21 22 23 CPUCapabilities::CPUCapabilities() 24 : fCapabilities(0) 25 { 26 #if defined(__i386__) || defined(__x86_64__) 27 _SetIntelCapabilities(); 28 #endif 29 } 30 31 32 #if defined(__i386__) || defined(__x86_64__) 33 void 34 CPUCapabilities::_SetIntelCapabilities() 35 { 36 cpuid_info baseInfo; 37 cpuid_info cpuInfo; 38 int32 maxStandardFunction = 0; 39 40 if (get_cpuid(&baseInfo, 0L, 0L) != B_OK) { 41 // this CPU doesn't support cpuid 42 return; 43 } 44 45 maxStandardFunction = baseInfo.eax_0.max_eax; 46 if (maxStandardFunction >= 500) { 47 maxStandardFunction = 0; /* old Pentium sample chips has cpu signature here */ 48 } 49 50 /* Extended cpuid */ 51 52 get_cpuid(&cpuInfo, 0x80000000, 0L); 53 54 if (maxStandardFunction > 0) { 55 56 get_cpuid(&cpuInfo, 1L, 0L); 57 if (cpuInfo.eax_1.features & (1UL << 23)) { 58 fCapabilities = CAPABILITY_MMX; 59 } 60 61 if (cpuInfo.eax_1.features & (1UL << 25)) { 62 fCapabilities = CAPABILITY_SSE1; 63 } 64 65 if (cpuInfo.eax_1.features & (1UL << 26)) { 66 fCapabilities = CAPABILITY_SSE2; 67 } 68 69 if (maxStandardFunction >= 1) { 70 /* Extended features */ 71 if (cpuInfo.eax_1.extended_features & (1UL << 0)) { 72 fCapabilities = CAPABILITY_SSE3; 73 } 74 if (cpuInfo.eax_1.extended_features & (1UL << 9)) { 75 fCapabilities = CAPABILITY_SSSE3; 76 } 77 if (cpuInfo.eax_1.extended_features & (1UL << 19)) { 78 fCapabilities = CAPABILITY_SSE41; 79 } 80 if (cpuInfo.eax_1.extended_features & (1UL << 20)) { 81 fCapabilities = CAPABILITY_SSE42; 82 } 83 } 84 } 85 } 86 #endif // __i386__ || __x86_64__ 87 88 89 bool 90 CPUCapabilities::HasMMX() 91 { 92 return fCapabilities >= CAPABILITY_MMX; 93 } 94 95 96 bool 97 CPUCapabilities::HasSSE1() 98 { 99 return fCapabilities >= CAPABILITY_SSE1; 100 } 101 102 103 bool 104 CPUCapabilities::HasSSE2() 105 { 106 return fCapabilities >= CAPABILITY_SSE2; 107 } 108 109 110 bool 111 CPUCapabilities::HasSSE3() 112 { 113 return fCapabilities >= CAPABILITY_SSE3; 114 } 115 116 117 bool 118 CPUCapabilities::HasSSSE3() 119 { 120 return fCapabilities >= CAPABILITY_SSSE3; 121 } 122 123 124 bool 125 CPUCapabilities::HasSSE41() 126 { 127 return fCapabilities >= CAPABILITY_SSE41; 128 } 129 130 131 bool 132 CPUCapabilities::HasSSE42() 133 { 134 return fCapabilities >= CAPABILITY_SSE42; 135 } 136 137 138 void 139 CPUCapabilities::PrintCapabilities() 140 { 141 static const char *CapArray[8] = { 142 "", "MMX", "SSE1", "SSE2", "SSE3", "SSSE3", "SSE4.1", "SSE4.2" 143 }; 144 145 printf("CPU is capable of running "); 146 if (fCapabilities > 0) { 147 for (uint32 i = 1; i <= fCapabilities; i++) 148 printf("%s ",CapArray[i]); 149 } else { 150 printf("no extensions"); 151 } 152 printf("\n"); 153 } 154