aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--alc/alc.cpp12
-rw-r--r--common/threads.h13
-rw-r--r--config.h.in3
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