From 312c4e22a78ddfb6a0e51f3225e8f9cc3256d1af Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 16 May 2012 22:43:23 +0000 Subject: [PATCH] Align the address of the pointer to the fxsave block to a 16-byte boundary (as well as the pointer itself), which the internets seem to suggest is required. git-svn-id: svn://localhost/ardour2/branches/3.0@12313 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/pbd/fpu.cc | 62 ++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/libs/pbd/fpu.cc b/libs/pbd/fpu.cc index 7efc63715b..479c422c37 100644 --- a/libs/pbd/fpu.cc +++ b/libs/pbd/fpu.cc @@ -4,6 +4,7 @@ #include // for memset #include #include +#include #include "pbd/fpu.h" #include "pbd/error.h" @@ -67,7 +68,7 @@ FPU::FPU () if (cpuflags & (1 << 24)) { - char* fxbuf = 0; + char** fxbuf = 0; /* DAZ wasn't available in the first version of SSE. Since setting a reserved bit in MXCSR causes a general protection @@ -80,37 +81,40 @@ FPU::FPU () */ #ifdef NO_POSIX_MEMALIGN - if ((fxbuf = (char *) malloc(512)) == 0) + fxbuf = (char **) malloc (sizeof (char *)); + assert (fxbuf); + *fxbuf = (char *) malloc (512); + assert (*fxbuf); #else - if (posix_memalign ((void**)&fxbuf, 16, 512)) + posix_memalign ((void **) &fxbuf, 16, sizeof (char *)); + assert (fxbuf); + posix_memalign ((void **) fxbuf, 16, 512); + assert (*fxbuf); #endif - { - error << _("cannot allocate 16 byte aligned buffer for h/w feature detection") << endmsg; - } else { - - memset (fxbuf, 0, 512); - - asm volatile ( - "fxsave (%0)" - : - : "r" (fxbuf) - : "memory" - ); - - uint32_t mxcsr_mask = *((uint32_t*) &fxbuf[28]); - - /* if the mask is zero, set its default value (from intel specs) */ - - if (mxcsr_mask == 0) { - mxcsr_mask = 0xffbf; - } - - if (mxcsr_mask & (1<<6)) { - _flags = Flags (_flags | HasDenormalsAreZero); - } - - free (fxbuf); + + memset (*fxbuf, 0, 512); + + asm volatile ( + "fxsave (%0)" + : + : "r" (*fxbuf) + : "memory" + ); + + uint32_t mxcsr_mask = *((uint32_t*) &((*fxbuf)[28])); + + /* if the mask is zero, set its default value (from intel specs) */ + + if (mxcsr_mask == 0) { + mxcsr_mask = 0xffbf; } + + if (mxcsr_mask & (1<<6)) { + _flags = Flags (_flags | HasDenormalsAreZero); + } + + free (*fxbuf); + free (fxbuf); } #endif }