Fix cut-to-width in the presence of bad constants in dead code.
[sbcl.git] / src / runtime / x86-64-linux-os.c
index 01e69bc..e012289 100644 (file)
@@ -14,6 +14,8 @@
  * files for more information.
  */
 
+#define _GNU_SOURCE /* for REG_RAX etc. from sys/ucontext */
+
 #include <stdio.h>
 #include <stddef.h>
 #include <sys/param.h>
 #include <unistd.h>
 #include <errno.h>
 
-#define __USE_GNU
 #include <sys/ucontext.h>
-#undef __USE_GNU
-
 
 #include "./signal.h"
 #include "os.h"
@@ -48,7 +47,7 @@
 #include <linux/unistd.h>
 #include <sys/mman.h>
 #include <linux/version.h>
-#include "thread.h"            /* dynamic_values_bytes */
+#include "thread.h"             /* dynamic_values_bytes */
 
 #include "validate.h"
 size_t os_vm_page_size;
@@ -56,7 +55,11 @@ size_t os_vm_page_size;
 int arch_os_thread_init(struct thread *thread) {
     stack_t sigstack;
 #ifdef LISP_FEATURE_SB_THREAD
-#error Threads are not supported on x86-64 in this SBCL version
+#ifdef LISP_FEATURE_GCC_TLS
+    current_thread = thread;
+#else
+    pthread_setspecific(specials,thread);
+#endif
 #endif
 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
     /* Signal handlers are run on the control stack, so if it is exhausted
@@ -65,7 +68,9 @@ int arch_os_thread_init(struct thread *thread) {
     sigstack.ss_sp=((void *) thread)+dynamic_values_bytes;
     sigstack.ss_flags=0;
     sigstack.ss_size = 32*SIGSTKSZ;
-    sigaltstack(&sigstack,0);
+    if(sigaltstack(&sigstack,0)<0) {
+        lose("Cannot sigaltstack: %s\n",strerror(errno));
+    }
 #endif
     return 1;
 }
@@ -85,25 +90,25 @@ os_context_register_addr(os_context_t *context, int offset)
 #define RCASE(name) case reg_ ## name: return &context->uc_mcontext.gregs[REG_ ## name];
     switch(offset) {
         RCASE(RAX)
-       RCASE(RCX)
-       RCASE(RDX)
-       RCASE(RBX)
-       RCASE(RSP)
-       RCASE(RBP)
-       RCASE(RSI)
-       RCASE(RDI)
-       RCASE(R8)
-       RCASE(R9)
-       RCASE(R10)
-       RCASE(R11)
-       RCASE(R12)
-       RCASE(R13)
-       RCASE(R14)
-       RCASE(R15)
-      default: 
-       if(offset<NGREG) 
-           return &context->uc_mcontext.gregs[offset/2+4];
-       else return 0;
+        RCASE(RCX)
+        RCASE(RDX)
+        RCASE(RBX)
+        RCASE(RSP)
+        RCASE(RBP)
+        RCASE(RSI)
+        RCASE(RDI)
+        RCASE(R8)
+        RCASE(R9)
+        RCASE(R10)
+        RCASE(R11)
+        RCASE(R12)
+        RCASE(R13)
+        RCASE(R14)
+        RCASE(R15)
+      default:
+        if(offset<NGREG)
+            return &context->uc_mcontext.gregs[offset/2+4];
+        else return 0;
     }
     return &context->uc_mcontext.gregs[offset];
 }
@@ -116,7 +121,7 @@ os_context_pc_addr(os_context_t *context)
 
 os_context_register_t *
 os_context_sp_addr(os_context_t *context)
-{                              
+{
     return &context->uc_mcontext.gregs[REG_RSP];
 }
 
@@ -129,8 +134,11 @@ os_context_fp_addr(os_context_t *context)
 unsigned long
 os_context_fp_control(os_context_t *context)
 {
-    int mxcsr = context->uc_mcontext.fpregs->mxcsr;
-    return ((mxcsr & 0x3F) << 16 | ((mxcsr >> 7) & 0x3F)) ^ 0x3F;
+    /* return the x87 exception flags ored in with the sse2
+     * control+status flags */
+    unsigned int result = (context->uc_mcontext.fpregs->swd & 0x3F) | context->uc_mcontext.fpregs->mxcsr;
+    /* flip exception mask bits */
+    return result ^ (0x3F << 7);
 }
 
 sigset_t *
@@ -142,7 +150,13 @@ os_context_sigmask_addr(os_context_t *context)
 void
 os_restore_fp_control(os_context_t *context)
 {
-    asm ("ldmxcsr %0" : : "m" (context->uc_mcontext.fpregs->mxcsr));
+    if (context->uc_mcontext.fpregs) {
+        /* reset exception flags and restore control flags on SSE2 FPU */
+        unsigned int temp = (context->uc_mcontext.fpregs->mxcsr) & ~0x3F;
+        asm ("ldmxcsr %0" : : "m" (temp));
+        /* same for x87 FPU. */
+        asm ("fldcw %0" : : "m" (context->uc_mcontext.fpregs->cwd));
+    }
 }
 
 void