blob: c724b3c94553ba99fa03ef87f614cb4a35a10d08 [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
sewardj5c522982005-06-21 10:11:36 +000024#ifdef __powerpc__
njnc6168192004-11-29 13:54:10 +000025static Bool go(char* cpu)
26{
sewardjfcbb9422005-11-10 23:30:21 +000027 if ( strcmp( cpu, "ppc32" ) == 0 )
njnc6168192004-11-29 13:54:10 +000028 return True;
29 else
30 return False;
31}
sewardj5c522982005-06-21 10:11:36 +000032#endif // __powerpc__
njnc6168192004-11-29 13:54:10 +000033
tomef567322005-11-11 14:33:43 +000034#if defined(__i386__) || defined(__x86_64__)
sewardjb5f6f512005-03-10 23:59:00 +000035static void cpuid ( unsigned int n,
36 unsigned int* a, unsigned int* b,
37 unsigned int* c, unsigned int* d )
nethercote288b7662004-01-20 09:24:53 +000038{
39 __asm__ __volatile__ (
40 "cpuid"
41 : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) /* output */
42 : "0" (n) /* input */
43 );
44}
45
nethercote362c0d22004-11-18 18:21:56 +000046static Bool go(char* cpu)
nethercoteb625bcb2004-10-19 16:29:30 +000047{
48 unsigned int level = 0, mask = 0, a, b, c, d;
nethercote288b7662004-01-20 09:24:53 +000049
nethercoteb625bcb2004-10-19 16:29:30 +000050 if ( strcmp( cpu, "x86" ) == 0 ) {
nethercote362c0d22004-11-18 18:21:56 +000051 return True;
nethercoteb625bcb2004-10-19 16:29:30 +000052 } else if ( strcmp( cpu, "x86-fpu" ) == 0 ) {
53 level = 1;
54 mask = 1 << 0;
55 } else if ( strcmp( cpu, "x86-cmov" ) == 0 ) {
56 level = 1;
57 mask = 1 << 15;
58 } else if ( strcmp( cpu, "x86-mmx" ) == 0 ) {
59 level = 1;
60 mask = 1 << 23;
61 } else if ( strcmp( cpu, "x86-mmxext" ) == 0 ) {
62 level = 0x80000001;
63 mask = 1 << 22;
64 } else if ( strcmp( cpu, "x86-sse" ) == 0 ) {
65 level = 1;
66 mask = 1 << 25;
67 } else if ( strcmp( cpu, "x86-sse2" ) == 0 ) {
68 level = 1;
69 mask = 1 << 26;
tomef567322005-11-11 14:33:43 +000070#if defined(__x86_64__)
71 } else if ( strcmp( cpu, "amd64" ) == 0 ) {
72 return True;
73#endif
nethercoteb625bcb2004-10-19 16:29:30 +000074 } else {
nethercote362c0d22004-11-18 18:21:56 +000075 return False;
nethercote288b7662004-01-20 09:24:53 +000076 }
77
nethercote1018bdd2004-02-11 23:33:29 +000078 cpuid( level & 0x80000000, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000079
nethercote1018bdd2004-02-11 23:33:29 +000080 if ( a >= level ) {
81 cpuid( level, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000082
nethercote362c0d22004-11-18 18:21:56 +000083 if ( ( d & mask ) != 0 ) return True;
nethercote288b7662004-01-20 09:24:53 +000084 }
nethercote362c0d22004-11-18 18:21:56 +000085 return False;
nethercoteb625bcb2004-10-19 16:29:30 +000086}
tomef567322005-11-11 14:33:43 +000087#endif // __i386__ || __x86_64__
nethercote288b7662004-01-20 09:24:53 +000088
nethercoteb625bcb2004-10-19 16:29:30 +000089
nethercoteb625bcb2004-10-19 16:29:30 +000090int main(int argc, char **argv)
91{
nethercote362c0d22004-11-18 18:21:56 +000092 int i;
nethercoteb625bcb2004-10-19 16:29:30 +000093 if ( argc != 2 ) {
94 fprintf( stderr, "usage: cputest <cpu-type>\n" );
nethercote362c0d22004-11-18 18:21:56 +000095 exit( 2 );
nethercoteb625bcb2004-10-19 16:29:30 +000096 }
nethercote362c0d22004-11-18 18:21:56 +000097 if (go( argv[1] )) {
98 return 0; // matched
99 }
100 for (i = 0; NULL != all_archs[i]; i++) {
101 if ( strcmp( argv[1], all_archs[i] ) == 0 )
102 return 1;
103 }
104 return 2;
nethercote288b7662004-01-20 09:24:53 +0000105}