blob: 3933c6ca3398814869f051f6e89b49ee2d30ec25 [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[] = {
18 "x86",
19 "ppc",
20 "amd64",
21 NULL
22};
nethercoteb625bcb2004-10-19 16:29:30 +000023
24#ifdef __x86__
nethercote1018bdd2004-02-11 23:33:29 +000025static __inline__ void cpuid(unsigned int n,
nethercote288b7662004-01-20 09:24:53 +000026 unsigned int *a, unsigned int *b,
27 unsigned int *c, unsigned int *d)
28{
29 __asm__ __volatile__ (
30 "cpuid"
31 : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) /* output */
32 : "0" (n) /* input */
33 );
34}
35
nethercote362c0d22004-11-18 18:21:56 +000036static Bool go(char* cpu)
nethercoteb625bcb2004-10-19 16:29:30 +000037{
38 unsigned int level = 0, mask = 0, a, b, c, d;
nethercote288b7662004-01-20 09:24:53 +000039
nethercoteb625bcb2004-10-19 16:29:30 +000040 if ( strcmp( cpu, "x86" ) == 0 ) {
nethercote362c0d22004-11-18 18:21:56 +000041 return True;
nethercoteb625bcb2004-10-19 16:29:30 +000042 } else if ( strcmp( cpu, "x86-fpu" ) == 0 ) {
43 level = 1;
44 mask = 1 << 0;
45 } else if ( strcmp( cpu, "x86-cmov" ) == 0 ) {
46 level = 1;
47 mask = 1 << 15;
48 } else if ( strcmp( cpu, "x86-mmx" ) == 0 ) {
49 level = 1;
50 mask = 1 << 23;
51 } else if ( strcmp( cpu, "x86-mmxext" ) == 0 ) {
52 level = 0x80000001;
53 mask = 1 << 22;
54 } else if ( strcmp( cpu, "x86-sse" ) == 0 ) {
55 level = 1;
56 mask = 1 << 25;
57 } else if ( strcmp( cpu, "x86-sse2" ) == 0 ) {
58 level = 1;
59 mask = 1 << 26;
60 } else {
nethercote362c0d22004-11-18 18:21:56 +000061 return False;
nethercote288b7662004-01-20 09:24:53 +000062 }
63
nethercote1018bdd2004-02-11 23:33:29 +000064 cpuid( level & 0x80000000, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000065
nethercote1018bdd2004-02-11 23:33:29 +000066 if ( a >= level ) {
67 cpuid( level, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000068
nethercote362c0d22004-11-18 18:21:56 +000069 if ( ( d & mask ) != 0 ) return True;
nethercote288b7662004-01-20 09:24:53 +000070 }
nethercote362c0d22004-11-18 18:21:56 +000071 return False;
nethercoteb625bcb2004-10-19 16:29:30 +000072}
73#endif // __x86__
nethercote288b7662004-01-20 09:24:53 +000074
nethercoteb625bcb2004-10-19 16:29:30 +000075
76#ifdef __ppc__
nethercote362c0d22004-11-18 18:21:56 +000077static Bool go(char* cpu)
nethercoteb625bcb2004-10-19 16:29:30 +000078{
79 if ( strcmp( cpu, "ppc" ) == 0 )
nethercote362c0d22004-11-18 18:21:56 +000080 return True;
nethercoteb625bcb2004-10-19 16:29:30 +000081 else
nethercote362c0d22004-11-18 18:21:56 +000082 return False;
nethercoteb625bcb2004-10-19 16:29:30 +000083}
84#endif // __ppc__
85
nethercoteb625bcb2004-10-19 16:29:30 +000086int main(int argc, char **argv)
87{
nethercote362c0d22004-11-18 18:21:56 +000088 int i;
nethercoteb625bcb2004-10-19 16:29:30 +000089 if ( argc != 2 ) {
90 fprintf( stderr, "usage: cputest <cpu-type>\n" );
nethercote362c0d22004-11-18 18:21:56 +000091 exit( 2 );
nethercoteb625bcb2004-10-19 16:29:30 +000092 }
nethercote362c0d22004-11-18 18:21:56 +000093 if (go( argv[1] )) {
94 return 0; // matched
95 }
96 for (i = 0; NULL != all_archs[i]; i++) {
97 if ( strcmp( argv[1], all_archs[i] ) == 0 )
98 return 1;
99 }
100 return 2;
nethercote288b7662004-01-20 09:24:53 +0000101}