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