blob: aab5792d5045f85be26b5e5706ec927eee000cae [file] [log] [blame]
nethercote288b7662004-01-20 09:24:53 +00001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
sewardjc49ae752006-08-05 12:22:52 +00004#include <assert.h>
nethercote288b7662004-01-20 09:24:53 +00005
nethercote362c0d22004-11-18 18:21:56 +00006// We return:
7// - 0 if the machine matches the asked-for cpu
8// - 1 if it didn't match, but did match the name of another arch
9// - 2 otherwise
10
11// When updating this file for a new architecture, add the name to
12// 'all_archs' as well as adding go().
13
14#define False 0
15#define True 1
16typedef int Bool;
17
18char* all_archs[] = {
nethercote362c0d22004-11-18 18:21:56 +000019 "amd64",
njn10c122e2005-09-13 00:45:14 +000020 "ppc32",
sewardj0d4f8ac2006-01-02 16:24:03 +000021 "ppc64",
njnc6168192004-11-29 13:54:10 +000022 "x86",
nethercote362c0d22004-11-18 18:21:56 +000023 NULL
24};
nethercoteb625bcb2004-10-19 16:29:30 +000025
sewardjbe714ff2006-10-17 01:49:50 +000026#if !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
njnc6168192004-11-29 13:54:10 +000027static Bool go(char* cpu)
28{
sewardjfcbb9422005-11-10 23:30:21 +000029 if ( strcmp( cpu, "ppc32" ) == 0 )
njnc6168192004-11-29 13:54:10 +000030 return True;
sewardj87f7fdd2006-01-04 03:08:16 +000031 return False;
njnc6168192004-11-29 13:54:10 +000032}
sewardj0d4f8ac2006-01-02 16:24:03 +000033#endif // __powerpc__ (32)
34
sewardjbe714ff2006-10-17 01:49:50 +000035#if !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
sewardj0d4f8ac2006-01-02 16:24:03 +000036static Bool go(char* cpu)
37{
38 if ( strcmp( cpu, "ppc64" ) == 0 )
39 return True;
sewardj87f7fdd2006-01-04 03:08:16 +000040 if ( strcmp( cpu, "ppc32" ) == 0 )
41 return True;
42 return False;
sewardj0d4f8ac2006-01-02 16:24:03 +000043}
44#endif // __powerpc__ (64)
njnc6168192004-11-29 13:54:10 +000045
sewardjbe714ff2006-10-17 01:49:50 +000046#if defined(_AIX)
47static Bool go(char* cpu)
48{
49 if (sizeof(void*) == 8) {
50 /* cpu is in 64-bit mode */
51 if ( strcmp( cpu, "ppc64" ) == 0 )
52 return True;
53 if ( strcmp( cpu, "ppc32" ) == 0 )
54 return True;
55 } else {
56 if ( strcmp( cpu, "ppc32" ) == 0 )
57 return True;
58 }
59 return False;
60}
61#endif // _AIX
62
63#if !defined(_AIX) && (defined(__i386__) || defined(__x86_64__))
sewardjb5f6f512005-03-10 23:59:00 +000064static void cpuid ( unsigned int n,
65 unsigned int* a, unsigned int* b,
66 unsigned int* c, unsigned int* d )
nethercote288b7662004-01-20 09:24:53 +000067{
68 __asm__ __volatile__ (
69 "cpuid"
70 : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) /* output */
71 : "0" (n) /* input */
72 );
73}
74
nethercote362c0d22004-11-18 18:21:56 +000075static Bool go(char* cpu)
nethercoteb625bcb2004-10-19 16:29:30 +000076{
sewardjc49ae752006-08-05 12:22:52 +000077 unsigned int level = 0, cmask = 0, dmask = 0, a, b, c, d;
nethercote288b7662004-01-20 09:24:53 +000078
nethercoteb625bcb2004-10-19 16:29:30 +000079 if ( strcmp( cpu, "x86" ) == 0 ) {
nethercote362c0d22004-11-18 18:21:56 +000080 return True;
nethercoteb625bcb2004-10-19 16:29:30 +000081 } else if ( strcmp( cpu, "x86-fpu" ) == 0 ) {
82 level = 1;
sewardjc49ae752006-08-05 12:22:52 +000083 dmask = 1 << 0;
nethercoteb625bcb2004-10-19 16:29:30 +000084 } else if ( strcmp( cpu, "x86-cmov" ) == 0 ) {
85 level = 1;
sewardjc49ae752006-08-05 12:22:52 +000086 dmask = 1 << 15;
nethercoteb625bcb2004-10-19 16:29:30 +000087 } else if ( strcmp( cpu, "x86-mmx" ) == 0 ) {
88 level = 1;
sewardjc49ae752006-08-05 12:22:52 +000089 dmask = 1 << 23;
nethercoteb625bcb2004-10-19 16:29:30 +000090 } else if ( strcmp( cpu, "x86-mmxext" ) == 0 ) {
91 level = 0x80000001;
sewardjc49ae752006-08-05 12:22:52 +000092 dmask = 1 << 22;
nethercoteb625bcb2004-10-19 16:29:30 +000093 } else if ( strcmp( cpu, "x86-sse" ) == 0 ) {
94 level = 1;
sewardjc49ae752006-08-05 12:22:52 +000095 dmask = 1 << 25;
nethercoteb625bcb2004-10-19 16:29:30 +000096 } else if ( strcmp( cpu, "x86-sse2" ) == 0 ) {
97 level = 1;
sewardjc49ae752006-08-05 12:22:52 +000098 dmask = 1 << 26;
99 } else if ( strcmp( cpu, "x86-sse3" ) == 0 ) {
100 level = 1;
101 cmask = 1 << 0;
toma00febc2009-01-12 15:26:59 +0000102 } else if ( strcmp( cpu, "x86-ssse3" ) == 0 ) {
103 level = 1;
104 cmask = 1 << 9;
tomef567322005-11-11 14:33:43 +0000105#if defined(__x86_64__)
106 } else if ( strcmp( cpu, "amd64" ) == 0 ) {
107 return True;
sewardjc49ae752006-08-05 12:22:52 +0000108 } else if ( strcmp( cpu, "amd64-sse3" ) == 0 ) {
109 level = 1;
110 cmask = 1 << 0;
toma00febc2009-01-12 15:26:59 +0000111 } else if ( strcmp( cpu, "amd64-ssse3" ) == 0 ) {
112 level = 1;
113 cmask = 1 << 9;
tomef567322005-11-11 14:33:43 +0000114#endif
nethercoteb625bcb2004-10-19 16:29:30 +0000115 } else {
nethercote362c0d22004-11-18 18:21:56 +0000116 return False;
nethercote288b7662004-01-20 09:24:53 +0000117 }
118
sewardjc49ae752006-08-05 12:22:52 +0000119 assert( !(cmask != 0 && dmask != 0) );
120 assert( !(cmask == 0 && dmask == 0) );
121
nethercote1018bdd2004-02-11 23:33:29 +0000122 cpuid( level & 0x80000000, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +0000123
nethercote1018bdd2004-02-11 23:33:29 +0000124 if ( a >= level ) {
125 cpuid( level, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +0000126
sewardjc49ae752006-08-05 12:22:52 +0000127 if (dmask > 0 && (d & dmask) != 0) return True;
128 if (cmask > 0 && (c & cmask) != 0) return True;
nethercote288b7662004-01-20 09:24:53 +0000129 }
nethercote362c0d22004-11-18 18:21:56 +0000130 return False;
nethercoteb625bcb2004-10-19 16:29:30 +0000131}
sewardjbe714ff2006-10-17 01:49:50 +0000132#endif // !_AIX && (__i386__ || __x86_64__)
nethercote288b7662004-01-20 09:24:53 +0000133
nethercoteb625bcb2004-10-19 16:29:30 +0000134
nethercoteb625bcb2004-10-19 16:29:30 +0000135int main(int argc, char **argv)
136{
nethercote362c0d22004-11-18 18:21:56 +0000137 int i;
nethercoteb625bcb2004-10-19 16:29:30 +0000138 if ( argc != 2 ) {
139 fprintf( stderr, "usage: cputest <cpu-type>\n" );
nethercote362c0d22004-11-18 18:21:56 +0000140 exit( 2 );
nethercoteb625bcb2004-10-19 16:29:30 +0000141 }
nethercote362c0d22004-11-18 18:21:56 +0000142 if (go( argv[1] )) {
143 return 0; // matched
144 }
145 for (i = 0; NULL != all_archs[i]; i++) {
146 if ( strcmp( argv[1], all_archs[i] ) == 0 )
147 return 1;
148 }
149 return 2;
nethercote288b7662004-01-20 09:24:53 +0000150}