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