diff --git a/src/lisp/Darwin-os.c b/src/lisp/Darwin-os.c index 693cbf6724feb8f1bcef00b262a8ea302ee1b4bb..5e8ddf98f96b85a4a6d226b29d02c5fae474d8f0 100644 --- a/src/lisp/Darwin-os.c +++ b/src/lisp/Darwin-os.c @@ -22,6 +22,8 @@ #include <errno.h> #include <dlfcn.h> #include <string.h> +#include <assert.h> + #include "os.h" #include "arch.h" #include "globals.h" @@ -332,7 +334,6 @@ os_sigcontext_fpu_reg(ucontext_t *scp, int index) return (unsigned char *) &scp->uc_mcontext->__fs.__fpu_stmm6; case 7: return (unsigned char *) &scp->uc_mcontext->__fs.__fpu_stmm7; -#ifdef FEATURE_SSE2 case 8: return (unsigned char *) &scp->uc_mcontext->__fs.__fpu_xmm0; case 9: @@ -348,43 +349,21 @@ os_sigcontext_fpu_reg(ucontext_t *scp, int index) case 14: return (unsigned char *) &scp->uc_mcontext->__fs.__fpu_xmm6; case 15: - return (unsigned char *) &scp->uc_mcontext->__fs.__fpu_stmm7; -#endif + return (unsigned char *) &scp->uc_mcontext->__fs.__fpu_stmm7; + default: + return NULL; } - return NULL; } unsigned int os_sigcontext_fpu_modes(ucontext_t *scp) { unsigned int modes; - unsigned int mxcsr; - unsigned short cw, sw; - - /* - * Get the status word and the control word. - */ - memcpy(&cw, &scp->uc_mcontext->__fs.__fpu_fcw, sizeof(cw)); - memcpy(&sw, &scp->uc_mcontext->__fs.__fpu_fsw, sizeof(sw)); - /* - * Put the cw in the upper bits and the status word in the lower 6 - * bits, ignoring everything except the exception masks and the - * exception flags. - */ - modes = ((cw & 0x3f) << 7) | (sw & 0x3f); + assert(fpu_mode == SSE2); - DPRINTF(0, (stderr, "FPU modes = %08x (sw = %4x, cw = %4x)\n", - modes, (unsigned int) sw, (unsigned int) cw)); - - if (fpu_mode == SSE2) { - mxcsr = scp->uc_mcontext->__fs.__fpu_mxcsr; - DPRINTF(0, (stderr, "SSE2 modes = %08x\n", mxcsr)); - - modes |= mxcsr; - } - - DPRINTF(0, (stderr, "modes pre mask = %08x\n", modes)); + modes = scp->uc_mcontext->__fs.__fpu_mxcsr; + DPRINTF(0, (stderr, "SSE2 modes = %08x\n", modes)); /* Convert exception mask to exception enable */ modes ^= (0x3f << 7); @@ -395,16 +374,11 @@ os_sigcontext_fpu_modes(ucontext_t *scp) void restore_fpu(ucontext_t *scp) { - unsigned short cw; unsigned int mxcsr; - memcpy(&cw, &scp->uc_mcontext->__fs.__fpu_fcw, sizeof(cw)); - DPRINTF(0, (stderr, "restore_fpu: FPU cw = 0x%x\n", cw)); - __asm__ __volatile__ ("fclex"); - __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw)); - mxcsr = scp->uc_mcontext->__fs.__fpu_mxcsr; DPRINTF(0, (stderr, "restore_fpu: mxcsr (raw) = %04x\n", mxcsr)); + __asm__ __volatile__ ("ldmxcsr %0" :: "m" (*&mxcsr)); } #endif diff --git a/src/lisp/Linux-os.c b/src/lisp/Linux-os.c index 7f7a4d7acd350c1ef5b443ef5a28cf848c2e368f..2da60fb59791eb574879c8eb2bca02a00ee2077e 100644 --- a/src/lisp/Linux-os.c +++ b/src/lisp/Linux-os.c @@ -217,16 +217,13 @@ os_sigcontext_fpu_reg(ucontext_t *scp, int offset) if (fpregs) { if (offset < 8) { reg = (unsigned char *) &fpregs->_st[offset]; - } -#ifdef FEATURE_SSE2 - else { + } else if (offset < 16) { struct _fpstate *fpstate; fpstate = (struct _fpstate*) scp->uc_mcontext.fpregs; if (fpstate->magic != 0xffff) { reg = (unsigned char *) &fpstate->_xmm[offset - 8]; } } -#endif } return reg; } @@ -234,39 +231,27 @@ os_sigcontext_fpu_reg(ucontext_t *scp, int offset) unsigned int os_sigcontext_fpu_modes(ucontext_t *scp) { - unsigned int modes; - unsigned short cw, sw; - - if (scp->uc_mcontext.fpregs == NULL) { - cw = 0; - sw = 0x3f; - } else { - cw = scp->uc_mcontext.fpregs->cw & 0xffff; - sw = scp->uc_mcontext.fpregs->sw & 0xffff; - } + unsigned int modes = 0; - modes = ((cw & 0x3f) << 7) | (sw & 0x3f); - -#ifdef FEATURE_SSE2 /* - * Add in the SSE2 part, if we're running the sse2 core. + * Get the SSE2 modes. FIXME: What should we do if the magic + * value indicates that the mxcsr value is not in the context? */ - if (fpu_mode == SSE2) { - struct _fpstate *fpstate; - unsigned long mxcsr; - - fpstate = (struct _fpstate*) scp->uc_mcontext.fpregs; - if (fpstate->magic == 0xffff) { - mxcsr = 0; - } else { - mxcsr = fpstate->mxcsr; - DPRINTF(0, (stderr, "SSE2 modes = %08lx\n", mxcsr)); - } + struct _fpstate *fpstate; + unsigned long mxcsr; - modes |= mxcsr; + fpstate = (struct _fpstate*) scp->uc_mcontext.fpregs; + if (fpstate->magic == 0xffff) { + mxcsr = 0; + } else { + mxcsr = fpstate->mxcsr; + DPRINTF(0, (stderr, "SSE2 modes = %08lx\n", mxcsr)); } -#endif + modes |= mxcsr; + + + /* Convert exception mask to exception enable */ modes ^= (0x3f << 7); return modes; } @@ -543,25 +528,19 @@ void restore_fpu(ucontext_t *context) { if (context->uc_mcontext.fpregs) { - short cw = context->uc_mcontext.fpregs->cw; - DPRINTF(0, (stderr, "restore_fpu: cw = %08x\n", cw)); - __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw)); -#ifdef FEATURE_SSE2 - if (fpu_mode == SSE2) { - struct _fpstate *fpstate; - unsigned int mxcsr; + struct _fpstate *fpstate; + unsigned int mxcsr; - fpstate = (struct _fpstate*) context->uc_mcontext.fpregs; - if (fpstate->magic != 0xffff) { - mxcsr = fpstate->mxcsr; - DPRINTF(0, (stderr, "restore_fpu: mxcsr (raw) = %04x\n", mxcsr)); - __asm__ __volatile__ ("ldmxcsr %0" :: "m" (*&mxcsr)); - } + fpstate = (struct _fpstate*) context->uc_mcontext.fpregs; + if (fpstate->magic != 0xffff) { + mxcsr = fpstate->mxcsr; + DPRINTF(0, (stderr, "restore_fpu: mxcsr (raw) = %04x\n", mxcsr)); + __asm__ __volatile__ ("ldmxcsr %0" :: "m" (*&mxcsr)); } -#endif } } + #ifdef i386 boolean os_support_sse2()