X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fx86-64-linux-os.c;h=e012289022eec477d7f0e3e9a6e8b23e2e75b3cd;hb=35ab27e7aab71c94aa6be12da15603c7fd87fca8;hp=6633b326ac265fcd058671ffb9f11d102b16b4be;hpb=cd056980425e3fa67b8b77de3936ccb46508c3b0;p=sbcl.git diff --git a/src/runtime/x86-64-linux-os.c b/src/runtime/x86-64-linux-os.c index 6633b32..e012289 100644 --- a/src/runtime/x86-64-linux-os.c +++ b/src/runtime/x86-64-linux-os.c @@ -14,6 +14,8 @@ * files for more information. */ +#define _GNU_SOURCE /* for REG_RAX etc. from sys/ucontext */ + #include #include #include @@ -22,10 +24,7 @@ #include #include -#define __USE_GNU #include -#undef __USE_GNU - #include "./signal.h" #include "os.h" @@ -48,7 +47,7 @@ #include #include #include -#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(offsetuc_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(offsetuc_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,12 +134,11 @@ os_context_fp_addr(os_context_t *context) unsigned long os_context_fp_control(os_context_t *context) { -#if 0 - return ((((context->uc_mcontext.fpregs->cw) & 0xffff) ^ 0x3f) | - (((context->uc_mcontext.fpregs->sw) & 0xffff) << 16)); -#else - return 0; -#endif + /* 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 * @@ -146,9 +150,13 @@ os_context_sigmask_addr(os_context_t *context) void os_restore_fp_control(os_context_t *context) { -#if 0 - asm ("fldcw %0" : : "m" (context->uc_mcontext.fpregs->cw)); -#endif + 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