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)