blob: 0d85a6fffa23b7432e23e1b35c383a76b1c017ab [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",
njn10c122e2005-09-13 00:45:14 +000019 "ppc32",
njnc6168192004-11-29 13:54:10 +000020 "x86",
nethercote362c0d22004-11-18 18:21:56 +000021 NULL
22};
nethercoteb625bcb2004-10-19 16:29:30 +000023
njn21071ec2005-07-30 01:22:37 +000024#ifdef __x86_64__
njnc6168192004-11-29 13:54:10 +000025static Bool go(char* cpu)
26{
27 if ( strcmp( cpu, "amd64" ) == 0 )
28 return True;
29 else
30 return False;
31}
njn21071ec2005-07-30 01:22:37 +000032#endif // __x86_64__
njnc6168192004-11-29 13:54:10 +000033
sewardj5c522982005-06-21 10:11:36 +000034#ifdef __powerpc__
njnc6168192004-11-29 13:54:10 +000035static Bool go(char* cpu)
36{
37 if ( strcmp( cpu, "ppc" ) == 0 )
38 return True;
39 else
40 return False;
41}
sewardj5c522982005-06-21 10:11:36 +000042#endif // __powerpc__
njnc6168192004-11-29 13:54:10 +000043
njn21071ec2005-07-30 01:22:37 +000044#ifdef __i386__
sewardjb5f6f512005-03-10 23:59:00 +000045static void cpuid ( unsigned int n,
46 unsigned int* a, unsigned int* b,
47 unsigned int* c, unsigned int* d )
nethercote288b7662004-01-20 09:24:53 +000048{
49 __asm__ __volatile__ (
50 "cpuid"
51 : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) /* output */
52 : "0" (n) /* input */
53 );
54}
55
nethercote362c0d22004-11-18 18:21:56 +000056static Bool go(char* cpu)
nethercoteb625bcb2004-10-19 16:29:30 +000057{
58 unsigned int level = 0, mask = 0, a, b, c, d;
nethercote288b7662004-01-20 09:24:53 +000059
nethercoteb625bcb2004-10-19 16:29:30 +000060 if ( strcmp( cpu, "x86" ) == 0 ) {
nethercote362c0d22004-11-18 18:21:56 +000061 return True;
nethercoteb625bcb2004-10-19 16:29:30 +000062 } else if ( strcmp( cpu, "x86-fpu" ) == 0 ) {
63 level = 1;
64 mask = 1 << 0;
65 } else if ( strcmp( cpu, "x86-cmov" ) == 0 ) {
66 level = 1;
67 mask = 1 << 15;
68 } else if ( strcmp( cpu, "x86-mmx" ) == 0 ) {
69 level = 1;
70 mask = 1 << 23;
71 } else if ( strcmp( cpu, "x86-mmxext" ) == 0 ) {
72 level = 0x80000001;
73 mask = 1 << 22;
74 } else if ( strcmp( cpu, "x86-sse" ) == 0 ) {
75 level = 1;
76 mask = 1 << 25;
77 } else if ( strcmp( cpu, "x86-sse2" ) == 0 ) {
78 level = 1;
79 mask = 1 << 26;
80 } else {
nethercote362c0d22004-11-18 18:21:56 +000081 return False;
nethercote288b7662004-01-20 09:24:53 +000082 }
83
nethercote1018bdd2004-02-11 23:33:29 +000084 cpuid( level & 0x80000000, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000085
nethercote1018bdd2004-02-11 23:33:29 +000086 if ( a >= level ) {
87 cpuid( level, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000088
nethercote362c0d22004-11-18 18:21:56 +000089 if ( ( d & mask ) != 0 ) return True;
nethercote288b7662004-01-20 09:24:53 +000090 }
nethercote362c0d22004-11-18 18:21:56 +000091 return False;
nethercoteb625bcb2004-10-19 16:29:30 +000092}
njn21071ec2005-07-30 01:22:37 +000093#endif // __i386__
nethercote288b7662004-01-20 09:24:53 +000094
nethercoteb625bcb2004-10-19 16:29:30 +000095
nethercoteb625bcb2004-10-19 16:29:30 +000096int main(int argc, char **argv)
97{
nethercote362c0d22004-11-18 18:21:56 +000098 int i;
nethercoteb625bcb2004-10-19 16:29:30 +000099 if ( argc != 2 ) {
100 fprintf( stderr, "usage: cputest <cpu-type>\n" );
nethercote362c0d22004-11-18 18:21:56 +0000101 exit( 2 );
nethercoteb625bcb2004-10-19 16:29:30 +0000102 }
nethercote362c0d22004-11-18 18:21:56 +0000103 if (go( argv[1] )) {
104 return 0; // matched
105 }
106 for (i = 0; NULL != all_archs[i]; i++) {
107 if ( strcmp( argv[1], all_archs[i] ) == 0 )
108 return 1;
109 }
110 return 2;
nethercote288b7662004-01-20 09:24:53 +0000111}