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, maxExtendedFunction = 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 // extended cpuid is only supported if max_eax is greater than the service id 55 if (cpuInfo.eax_0.max_eax > 0x80000000) { 56 maxExtendedFunction = cpuInfo.eax_0.max_eax & 0xff; 57 } 58 59 if (maxStandardFunction > 0) { 60 61 get_cpuid(&cpuInfo, 1L, 0L); 62 if (cpuInfo.eax_1.features & (1UL << 23)) { 63 fCapabilities = CAPABILITY_MMX; 64 } 65 66 if (cpuInfo.eax_1.features & (1UL << 25)) { 67 fCapabilities = CAPABILITY_SSE1; 68 } 69 70 if (cpuInfo.eax_1.features & (1UL << 26)) { 71 fCapabilities = CAPABILITY_SSE2; 72 } 73 74 if (maxStandardFunction >= 1) { 75 /* Extended features */ 76 if (cpuInfo.eax_1.extended_features & (1UL << 0)) { 77 fCapabilities = CAPABILITY_SSE3; 78 } 79 if (cpuInfo.eax_1.extended_features & (1UL << 9)) { 80 fCapabilities = CAPABILITY_SSSE3; 81 } 82 if (cpuInfo.eax_1.extended_features & (1UL << 19)) { 83 fCapabilities = CAPABILITY_SSE41; 84 } 85 if (cpuInfo.eax_1.extended_features & (1UL << 20)) { 86 fCapabilities = CAPABILITY_SSE42; 87 } 88 } 89 } 90 } 91 #endif // __i386__ || __x86_64__ 92 93 94 bool 95 CPUCapabilities::HasMMX() 96 { 97 return fCapabilities >= CAPABILITY_MMX; 98 } 99 100 101 bool 102 CPUCapabilities::HasSSE1() 103 { 104 return fCapabilities >= CAPABILITY_SSE1; 105 } 106 107 108 bool 109 CPUCapabilities::HasSSE2() 110 { 111 return fCapabilities >= CAPABILITY_SSE2; 112 } 113 114 115 bool 116 CPUCapabilities::HasSSE3() 117 { 118 return fCapabilities >= CAPABILITY_SSE3; 119 } 120 121 122 bool 123 CPUCapabilities::HasSSSE3() 124 { 125 return fCapabilities >= CAPABILITY_SSSE3; 126 } 127 128 129 bool 130 CPUCapabilities::HasSSE41() 131 { 132 return fCapabilities >= CAPABILITY_SSE41; 133 } 134 135 136 bool 137 CPUCapabilities::HasSSE42() 138 { 139 return fCapabilities >= CAPABILITY_SSE42; 140 } 141 142 143 void 144 CPUCapabilities::PrintCapabilities() 145 { 146 static const char *CapArray[8] = { 147 "", "MMX", "SSE1", "SSE2", "SSE3", "SSSE3", "SSE4.1", "SSE4.2" 148 }; 149 150 printf("CPU is capable of running "); 151 if (fCapabilities > 0) { 152 for (uint32 i = 1; i <= fCapabilities; i++) 153 printf("%s ",CapArray[i]); 154 } else { 155 printf("no extensions"); 156 } 157 printf("\n"); 158 } 159