diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | alc/alc.cpp | 12 | ||||
-rw-r--r-- | common/threads.h | 13 | ||||
-rw-r--r-- | config.h.in | 3 |
4 files changed, 14 insertions, 16 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index ae21a83e..e4d3776d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -470,6 +470,7 @@ if(ALSOFT_REQUIRE_NEON AND NOT HAVE_NEON) endif() +set(ALSOFT_FORCE_ALIGN ) set(SSE_FLAGS ) set(FPMATH_SET "0") if(CMAKE_SIZEOF_VOID_P MATCHES "4" AND HAVE_SSE2) @@ -494,6 +495,7 @@ if(CMAKE_SIZEOF_VOID_P MATCHES "4" AND HAVE_SSE2) # OSs don't guarantee this on 32-bit, so externally-callable # functions need to ensure an aligned stack. set(EXPORT_DECL "${EXPORT_DECL}__attribute__((force_align_arg_pointer))") + set(ALSOFT_FORCE_ALIGN "__attribute__((force_align_arg_pointer))") endif() endif() endif() diff --git a/alc/alc.cpp b/alc/alc.cpp index 299a1ee9..128b3d7e 100644 --- a/alc/alc.cpp +++ b/alc/alc.cpp @@ -3228,11 +3228,17 @@ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device * Renders some samples into a buffer, using the format last set by the * attributes given to alcCreateContext. */ -FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) noexcept +#if defined(__GNUC__) && defined(__i386__) +/* Needed on x86-32 even without SSE codegen, since the mixer may still use SSE + * and GCC assumes the stack is aligned (x86-64 ABI guarantees alignment). + */ +[[gnu::force_align_arg_pointer]] +#endif +ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) noexcept { - if(!device || device->Type != DeviceType::Loopback) + if(!device || device->Type != DeviceType::Loopback) UNLIKELY alcSetError(device, ALC_INVALID_DEVICE); - else if(samples < 0 || (samples > 0 && buffer == nullptr)) + else if(samples < 0 || (samples > 0 && buffer == nullptr)) UNLIKELY alcSetError(device, ALC_INVALID_VALUE); else device->renderSamples(buffer, static_cast<uint>(samples), device->channelsFromFmt()); diff --git a/common/threads.h b/common/threads.h index 62d80828..1ef037bb 100644 --- a/common/threads.h +++ b/common/threads.h @@ -1,19 +1,6 @@ #ifndef AL_THREADS_H #define AL_THREADS_H -#if defined(__GNUC__) && defined(__i386__) -/* force_align_arg_pointer may be required for proper stack alignment when SSE - * code is used. GCC generates code with the assumption the stack pointer is - * suitably aligned, while some systems (Windows, QNX) do not guarantee non- - * exported functions will be properly aligned when called externally, and - * older apps for other systems may have been built with a lower stack - * alignment than expected by newer builds. - */ -#define FORCE_ALIGN __attribute__((force_align_arg_pointer)) -#else -#define FORCE_ALIGN -#endif - #if defined(__APPLE__) #include <AvailabilityMacros.h> #include <TargetConditionals.h> diff --git a/config.h.in b/config.h.in index d1cf0395..20df5b46 100644 --- a/config.h.in +++ b/config.h.in @@ -1,3 +1,6 @@ +/* Define the alignment attribute for externally callable functions. */ +#define FORCE_ALIGN @ALSOFT_FORCE_ALIGN@ + /* Define if deprecated EAX extensions are enabled */ #cmakedefine ALSOFT_EAX |