xref: /haiku/src/add-ons/media/plugins/ffmpeg/CpuCapabilities.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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