Date: Tuesday, December 14, 2010 @ 16:27:14 Author: rtoy Path: /project/cmucl/cvsroot/src/lisp Tag: cross-sol-x86-branch
Modified: x86-arch.c
Sun C miscompiles the inline assembly for the cpuid instruction, so on Solaris, use the /dev/cpu/self/cpuid device to get the cpuid data that we need.
------------+ x86-arch.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-)
Index: src/lisp/x86-arch.c diff -u src/lisp/x86-arch.c:1.39 src/lisp/x86-arch.c:1.39.24.1 --- src/lisp/x86-arch.c:1.39 Tue Jan 6 13:18:43 2009 +++ src/lisp/x86-arch.c Tue Dec 14 16:27:13 2010 @@ -1,6 +1,6 @@ /* x86-arch.c -*- Mode: C; comment-column: 40 -*- * - * $Header: /project/cmucl/cvsroot/src/lisp/x86-arch.c,v 1.39 2009-01-06 18:18:43 rtoy Rel $ + * $Header: /project/cmucl/cvsroot/src/lisp/x86-arch.c,v 1.39.24.1 2010-12-14 21:27:13 rtoy Exp $ * */
@@ -24,6 +24,50 @@
unsigned long fast_random_state = 1;
+#if defined(SOLARIS) +/* + * Use the /dev/cpu/self/cpuid interface on Solaris. We could use the + * same method below, but the Sun C compiler miscompiles the inline + * assembly. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +void cpuid(int level, unsigned int* a, unsigned int* b, + unsigned int* c, unsigned int* d) +{ + int device; + uint32_t regs[4]; + static const char devname[] = "/dev/cpu/self/cpuid"; + + *a = *b = *c = *d = 0; + if ((device = open(devname, O_RDONLY)) == -1) { + perror(devname); + goto exit; + } + + if (pread(device, regs, sizeof(regs), 1) != sizeof(regs)) { + perror(devname); + goto exit; + } + + *a = regs[0]; + *b = regs[1]; + *c = regs[2]; + *d = regs[3]; + + exit: + (void) close(device); + + return; +} + +#else #define __cpuid(level, a, b, c, d) \ __asm__ ("xchgl\t%%ebx, %1\n\t" \ "cpuid\n\t" \ @@ -43,6 +87,7 @@ *c = ecx; *d = edx; } +#endif
int arch_support_sse2(void)