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 { 25 #ifdef __INTEL__ 26 setIntelCapabilities(); 27 #endif 28 29 PrintCapabilities(); 30 } 31 32 33 #ifdef __INTEL__ 34 void 35 CPUCapabilities::setIntelCapabilities() 36 { 37 cpuid_info baseInfo; 38 cpuid_info cpuInfo; 39 int32 maxStandardFunction, maxExtendedFunction = 0; 40 41 if (get_cpuid(&baseInfo, 0L, 0L) != B_OK) { 42 // this CPU doesn't support cpuid 43 return; 44 } 45 46 maxStandardFunction = baseInfo.eax_0.max_eax; 47 if (maxStandardFunction >= 500) { 48 maxStandardFunction = 0; /* old Pentium sample chips has cpu signature here */ 49 } 50 51 /* Extended cpuid */ 52 53 get_cpuid(&cpuInfo, 0x80000000, 0L); 54 55 // extended cpuid is only supported if max_eax is greater than the service id 56 if (cpuInfo.eax_0.max_eax > 0x80000000) { 57 maxExtendedFunction = cpuInfo.eax_0.max_eax & 0xff; 58 } 59 60 if (maxStandardFunction > 0) { 61 62 get_cpuid(&cpuInfo, 1L, 0L); 63 if (cpuInfo.eax_1.features & (1UL << 23)) { 64 capabilities = CAPABILITY_MMX; 65 } 66 67 if (cpuInfo.eax_1.features & (1UL << 25)) { 68 capabilities = CAPABILITY_SSE1; 69 } 70 71 if (cpuInfo.eax_1.features & (1UL << 26)) { 72 capabilities = CAPABILITY_SSE2; 73 } 74 75 if (maxStandardFunction >= 1) { 76 /* Extended features */ 77 if (cpuInfo.eax_1.extended_features & (1UL << 0)) { 78 capabilities = CAPABILITY_SSE3; 79 } 80 if (cpuInfo.eax_1.extended_features & (1UL << 9)) { 81 capabilities = CAPABILITY_SSSE3; 82 } 83 if (cpuInfo.eax_1.extended_features & (1UL << 19)) { 84 capabilities = CAPABILITY_SSE41; 85 } 86 if (cpuInfo.eax_1.extended_features & (1UL << 20)) { 87 capabilities = CAPABILITY_SSE42; 88 } 89 } 90 } 91 } 92 #endif // __INTEL__ 93 94 95 bool 96 CPUCapabilities::HasMMX() 97 { 98 return capabilities >= CAPABILITY_MMX; 99 } 100 101 102 bool 103 CPUCapabilities::HasSSE1() 104 { 105 return capabilities >= CAPABILITY_SSE1; 106 } 107 108 109 bool 110 CPUCapabilities::HasSSE2() 111 { 112 return capabilities >= CAPABILITY_SSE2; 113 } 114 115 116 bool 117 CPUCapabilities::HasSSE3() 118 { 119 return capabilities >= CAPABILITY_SSE3; 120 } 121 122 123 bool 124 CPUCapabilities::HasSSSE3() 125 { 126 return capabilities >= CAPABILITY_SSSE3; 127 } 128 129 130 bool 131 CPUCapabilities::HasSSE41() 132 { 133 return capabilities >= CAPABILITY_SSE41; 134 } 135 136 137 bool 138 CPUCapabilities::HasSSE42() 139 { 140 return capabilities >= CAPABILITY_SSE42; 141 } 142 143 144 void 145 CPUCapabilities::PrintCapabilities() 146 { 147 static const char *CapArray[8] = { 148 "", "MMX", "SSE1", "SSE2", "SSE3", "SSSE3", "SSE4.1", "SSE4.2" 149 }; 150 151 printf("CPU is capable of running "); 152 if (capabilities) { 153 for (uint32 i=1;i<=capabilities;i++) { 154 printf("%s ",CapArray[i]); 155 } 156 } else { 157 printf("no extensions"); 158 } 159 printf("\n"); 160 } 161