blob: 41fcdae1dd726ab0b223dbe2c56856ee4f65b06b [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",
sewardj0d4f8ac2006-01-02 16:24:03 +000020 "ppc64",
njnc6168192004-11-29 13:54:10 +000021 "x86",
nethercote362c0d22004-11-18 18:21:56 +000022 NULL
23};
nethercoteb625bcb2004-10-19 16:29:30 +000024
sewardj0d4f8ac2006-01-02 16:24:03 +000025#if defined(__powerpc__) && !defined(__powerpc64__)
njnc6168192004-11-29 13:54:10 +000026static Bool go(char* cpu)
27{
sewardjfcbb9422005-11-10 23:30:21 +000028 if ( strcmp( cpu, "ppc32" ) == 0 )
njnc6168192004-11-29 13:54:10 +000029 return True;
30 else
31 return False;
32}
sewardj0d4f8ac2006-01-02 16:24:03 +000033#endif // __powerpc__ (32)
34
35#if defined(__powerpc__) && defined(__powerpc64__)
36static Bool go(char* cpu)
37{
38 if ( strcmp( cpu, "ppc64" ) == 0 )
39 return True;
40 else
41 return False;
42}
43#endif // __powerpc__ (64)
njnc6168192004-11-29 13:54:10 +000044
tomef567322005-11-11 14:33:43 +000045#if defined(__i386__) || defined(__x86_64__)
sewardjb5f6f512005-03-10 23:59:00 +000046static void cpuid ( unsigned int n,
47 unsigned int* a, unsigned int* b,
48 unsigned int* c, unsigned int* d )
nethercote288b7662004-01-20 09:24:53 +000049{
50 __asm__ __volatile__ (
51 "cpuid"
52 : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) /* output */
53 : "0" (n) /* input */
54 );
55}
56
nethercote362c0d22004-11-18 18:21:56 +000057static Bool go(char* cpu)
nethercoteb625bcb2004-10-19 16:29:30 +000058{
59 unsigned int level = 0, mask = 0, a, b, c, d;
nethercote288b7662004-01-20 09:24:53 +000060
nethercoteb625bcb2004-10-19 16:29:30 +000061 if ( strcmp( cpu, "x86" ) == 0 ) {
nethercote362c0d22004-11-18 18:21:56 +000062 return True;
nethercoteb625bcb2004-10-19 16:29:30 +000063 } else if ( strcmp( cpu, "x86-fpu" ) == 0 ) {
64 level = 1;
65 mask = 1 << 0;
66 } else if ( strcmp( cpu, "x86-cmov" ) == 0 ) {
67 level = 1;
68 mask = 1 << 15;
69 } else if ( strcmp( cpu, "x86-mmx" ) == 0 ) {
70 level = 1;
71 mask = 1 << 23;
72 } else if ( strcmp( cpu, "x86-mmxext" ) == 0 ) {
73 level = 0x80000001;
74 mask = 1 << 22;
75 } else if ( strcmp( cpu, "x86-sse" ) == 0 ) {
76 level = 1;
77 mask = 1 << 25;
78 } else if ( strcmp( cpu, "x86-sse2" ) == 0 ) {
79 level = 1;
80 mask = 1 << 26;
tomef567322005-11-11 14:33:43 +000081#if defined(__x86_64__)
82 } else if ( strcmp( cpu, "amd64" ) == 0 ) {
83 return True;
84#endif
nethercoteb625bcb2004-10-19 16:29:30 +000085 } else {
nethercote362c0d22004-11-18 18:21:56 +000086 return False;
nethercote288b7662004-01-20 09:24:53 +000087 }
88
nethercote1018bdd2004-02-11 23:33:29 +000089 cpuid( level & 0x80000000, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000090
nethercote1018bdd2004-02-11 23:33:29 +000091 if ( a >= level ) {
92 cpuid( level, &a, &b, &c, &d );
nethercote288b7662004-01-20 09:24:53 +000093
nethercote362c0d22004-11-18 18:21:56 +000094 if ( ( d & mask ) != 0 ) return True;
nethercote288b7662004-01-20 09:24:53 +000095 }
nethercote362c0d22004-11-18 18:21:56 +000096 return False;
nethercoteb625bcb2004-10-19 16:29:30 +000097}
tomef567322005-11-11 14:33:43 +000098#endif // __i386__ || __x86_64__
nethercote288b7662004-01-20 09:24:53 +000099
nethercoteb625bcb2004-10-19 16:29:30 +0000100
nethercoteb625bcb2004-10-19 16:29:30 +0000101int main(int argc, char **argv)
102{
nethercote362c0d22004-11-18 18:21:56 +0000103 int i;
nethercoteb625bcb2004-10-19 16:29:30 +0000104 if ( argc != 2 ) {
105 fprintf( stderr, "usage: cputest <cpu-type>\n" );
nethercote362c0d22004-11-18 18:21:56 +0000106 exit( 2 );
nethercoteb625bcb2004-10-19 16:29:30 +0000107 }
nethercote362c0d22004-11-18 18:21:56 +0000108 if (go( argv[1] )) {
109 return 0; // matched
110 }
111 for (i = 0; NULL != all_archs[i]; i++) {
112 if ( strcmp( argv[1], all_archs[i] ) == 0 )
113 return 1;
114 }
115 return 2;
nethercote288b7662004-01-20 09:24:53 +0000116}