blob: 004b1a00eed4d1fc60e96fd7715e5bad7a13192e [file] [log] [blame]
nethercote288b7662004-01-20 09:24:53 +00001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
nethercote362c0d22004-11-18 18:21:56 +00005// We return:
6// - 0 if the machine matches the asked-for cpu
7// - 1 if it didn't match, but did match the name of another arch
8// - 2 otherwise
9
10// When updating this file for a new architecture, add the name to
11// 'all_archs' as well as adding go().
12
13#define False 0
14#define True 1
15typedef int Bool;
16
17char* all_archs[] = {
nethercote362c0d22004-11-18 18:21:56 +000018 "amd64",
njnc6168192004-11-29 13:54:10 +000019 "arm",
njnca0518d2004-11-26 19:34:36 +000020 "ppc",
njnc6168192004-11-29 13:54:10 +000021 "x86",
nethercote362c0d22004-11-18 18:21:56 +000022 NULL
23};
nethercoteb625bcb2004-10-19 16:29:30 +000024
njnc6168192004-11-29 13:54:10 +000025#ifdef __amd64
26static Bool go(char* cpu)
27{
28 if ( strcmp( cpu, "amd64" ) == 0 )
29 return True;
30 else
31 return False;
32}
33#endif // __amd64
34
35#ifdef __arm__
36static Bool go(char* cpu)
37{
38 if ( strcmp( cpu, "arm" ) == 0 )
39 return True;
40 else
41 return False;
42}
43#endif // __arm__
44
45#ifdef __ppc__
46static Bool go(char* cpu)
47{
48 if ( strcmp( cpu, "ppc" ) == 0 )
49 return True;
50 else
51 return False;
52}
53#endif // __ppc__
54
nethercoteb625bcb2004-10-19 16:29:30 +000055#ifdef __x86__
sewardjb5f6f512005-03-10 23:59:00 +000056static void cpuid ( unsigned int n,
57 unsigned int* a, unsigned int* b,
58 unsigned int* c, unsigned int* d )
nethercote288b7662004-01-20 09:24:53 +000059{
60 __asm__ __volatile__ (
61 "cpuid"
62 : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) /* output */
63 : "0" (n) /* input */
64 );
65}
66
nethercote362c0d22004-11-18 18:21:56 +000067static Bool go(char* cpu)
nethercoteb625bcb2004-10-19 16:29:30 +000068{
69 unsigned int level = 0, mask = 0, a, b, c, d;
nethercote288b7662004-01-20 09:24:53 +000070
nethercoteb625bcb2004-10-19 16:29:30 +000071 if ( strcmp( cpu, "x86" ) == 0 ) {
nethercote362c0d22004-11-18 18:21:56 +000072 return True;
nethercoteb625bcb2004-10-19 16:29:30 +000073 } else if ( strcmp( cpu, "x86-fpu" ) == 0 ) {
74 level = 1;
75 mask = 1 << 0;
76 } else if ( strcmp( cpu, "x86-cmov" ) == 0 ) {
77 level = 1;
78 mask = 1 << 15;
79 } else if ( strcmp( cpu, "x86-mmx" ) == 0 ) {
80 level = 1;
81 mask = 1 << 23;
82 } else if ( strcmp( cpu, "x86-mmxext" ) == 0 ) {
83 level = 0x80000001;
84 mask = 1 << 22;
85 } else if ( strcmp( cpu, "x86-sse" ) == 0 ) {
86 level = 1;
87 mask = 1 << 25;
88 } else if ( strcmp( cpu, "x86-sse2" ) == 0 ) {
89 level = 1;
90 mask = 1 << 26;
91 } else {
nethercote362c0d22004-11-18 18:21:56 +000092 return False;
nethercote288b7662004-01-20 09:24:53 +000093 }
94
nethercote1018bdd2004-02-11 23:33:29 +000095 cpuid( level & 0x80000000, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000096
nethercote1018bdd2004-02-11 23:33:29 +000097 if ( a >= level ) {
98 cpuid( level, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000099
nethercote362c0d22004-11-18 18:21:56 +0000100 if ( ( d & mask ) != 0 ) return True;
nethercote288b7662004-01-20 09:24:53 +0000101 }
nethercote362c0d22004-11-18 18:21:56 +0000102 return False;
nethercoteb625bcb2004-10-19 16:29:30 +0000103}
104#endif // __x86__
nethercote288b7662004-01-20 09:24:53 +0000105
nethercoteb625bcb2004-10-19 16:29:30 +0000106
nethercoteb625bcb2004-10-19 16:29:30 +0000107int main(int argc, char **argv)
108{
nethercote362c0d22004-11-18 18:21:56 +0000109 int i;
nethercoteb625bcb2004-10-19 16:29:30 +0000110 if ( argc != 2 ) {
111 fprintf( stderr, "usage: cputest <cpu-type>\n" );
nethercote362c0d22004-11-18 18:21:56 +0000112 exit( 2 );
nethercoteb625bcb2004-10-19 16:29:30 +0000113 }
nethercote362c0d22004-11-18 18:21:56 +0000114 if (go( argv[1] )) {
115 return 0; // matched
116 }
117 for (i = 0; NULL != all_archs[i]; i++) {
118 if ( strcmp( argv[1], all_archs[i] ) == 0 )
119 return 1;
120 }
121 return 2;
nethercote288b7662004-01-20 09:24:53 +0000122}