diff --git a/common/opthelpers.h b/common/opthelpers.h index ae2611dad3..fff8815451 100644 --- a/common/opthelpers.h +++ b/common/opthelpers.h @@ -28,6 +28,24 @@ #define NOINLINE #endif +#if defined(__MINGW32__) && defined(__i386__) +/* 32-bit MinGW targets have a bug where __STDCPP_DEFAULT_NEW_ALIGNMENT__ + * reports 16, despite the default operator new calling standard malloc which + * only guarantees 8-byte alignment. As a result, structs that need and specify + * 16-byte alignment only get 8-byte alignment. Explicitly specifying 32-byte + * alignment forces the over-aligned operator new to be called, giving the + * correct (if larger than necessary) alignment. + * + * Technically this bug affects 32-bit GCC more generally, but typically only + * with fairly old glibc versions as newer versions do guarantee the 16-byte + * alignment as specified. MinGW is reliant on msvcrt.dll's malloc however, + * which can't be updated to give that guarantee. + */ +#define SIMDALIGN alignas(32) +#else +#define SIMDALIGN +#endif + /* Unlike the likely attribute, ASSUME requires the condition to be true or * else it invokes undefined behavior. It's essentially an assert without * actually checking the condition at run-time, allowing for stronger diff --git a/common/phase_shifter.h b/common/phase_shifter.h index 7febf34471..f76e42497f 100644 --- a/common/phase_shifter.h +++ b/common/phase_shifter.h @@ -21,7 +21,7 @@ * signal delay (FilterSize/2) to properly align. */ template -struct PhaseShifterT { +struct SIMDALIGN PhaseShifterT { static_assert(FilterSize >= 16, "FilterSize needs to be at least 16"); static_assert((FilterSize&(FilterSize-1)) == 0, "FilterSize needs to be power-of-two"); diff --git a/core/bformatdec.h b/core/bformatdec.h index 5bb2d3b409..b86f771da1 100644 --- a/core/bformatdec.h +++ b/core/bformatdec.h @@ -13,11 +13,12 @@ #include "devformat.h" #include "filters/splitter.h" #include "front_stablizer.h" +#include "opthelpers.h" using ChannelDec = std::array; -class BFormatDec { +class SIMDALIGN BFormatDec { static constexpr size_t sHFBand{0}; static constexpr size_t sLFBand{1}; static constexpr size_t sNumBands{2}; diff --git a/core/bsinc_tables.cpp b/core/bsinc_tables.cpp index 74f47a1299..793bc7ac2a 100644 --- a/core/bsinc_tables.cpp +++ b/core/bsinc_tables.cpp @@ -14,6 +14,7 @@ #include "alnumeric.h" #include "alspan.h" #include "bsinc_defs.h" +#include "opthelpers.h" #include "resampler_limits.h" @@ -153,7 +154,7 @@ constexpr BSincHeader bsinc24_hdr{60, 23}; template -struct BSincFilterArray { +struct SIMDALIGN BSincFilterArray { alignas(16) std::array mTable{}; BSincFilterArray() diff --git a/core/cubic_tables.h b/core/cubic_tables.h index 2106a1331f..b327644517 100644 --- a/core/cubic_tables.h +++ b/core/cubic_tables.h @@ -5,9 +5,10 @@ #include #include "cubic_defs.h" +#include "opthelpers.h" -struct CubicTable { +struct SIMDALIGN CubicTable { std::array mTable{}; }; diff --git a/core/device.h b/core/device.h index a628631898..c5aef0e6e9 100644 --- a/core/device.h +++ b/core/device.h @@ -179,7 +179,7 @@ enum class DeviceState : std::uint8_t { Playing }; -struct DeviceBase { +struct SIMDALIGN DeviceBase { std::atomic Connected{true}; const DeviceType Type{}; diff --git a/core/effects/base.h b/core/effects/base.h index b0d2671675..879f839005 100644 --- a/core/effects/base.h +++ b/core/effects/base.h @@ -8,6 +8,7 @@ #include "alspan.h" #include "core/bufferline.h" #include "intrusive_ptr.h" +#include "opthelpers.h" struct BufferStorage; struct ContextBase; @@ -193,7 +194,7 @@ struct EffectTarget { RealMixParams *RealOut; }; -struct EffectState : public al::intrusive_ref { +struct SIMDALIGN EffectState : public al::intrusive_ref { al::span mOutTarget; diff --git a/core/hrtf.h b/core/hrtf.h index e93fddaab9..91c9244387 100644 --- a/core/hrtf.h +++ b/core/hrtf.h @@ -11,7 +11,6 @@ #include "almalloc.h" #include "alspan.h" -#include "atomic.h" #include "ambidefs.h" #include "bufferline.h" #include "flexarray.h" diff --git a/core/mastering.cpp b/core/mastering.cpp index 069a21cea4..b9e8aa5019 100644 --- a/core/mastering.cpp +++ b/core/mastering.cpp @@ -19,7 +19,7 @@ /* These structures assume BufferLineSize is a power of 2. */ static_assert((BufferLineSize & (BufferLineSize-1)) == 0, "BufferLineSize is not a power of 2"); -struct SlidingHold { +struct SIMDALIGN SlidingHold { alignas(16) FloatBufferLine mValues; std::array mExpiries; uint mLowerIndex; diff --git a/core/mastering.h b/core/mastering.h index 032eae0826..0fafff91e2 100644 --- a/core/mastering.h +++ b/core/mastering.h @@ -4,10 +4,10 @@ #include #include -#include "almalloc.h" #include "alnumeric.h" #include "alspan.h" #include "bufferline.h" +#include "opthelpers.h" #include "vector.h" struct SlidingHold; @@ -25,7 +25,7 @@ using uint = unsigned int; * * http://c4dm.eecs.qmul.ac.uk/audioengineering/compressors/ */ -class Compressor { +class SIMDALIGN Compressor { size_t mNumChans{0u}; struct AutoFlags { diff --git a/core/uhjfilter.h b/core/uhjfilter.h index 55be31b22d..264a1e1aff 100644 --- a/core/uhjfilter.h +++ b/core/uhjfilter.h @@ -7,6 +7,7 @@ #include "alspan.h" #include "bufferline.h" +#include "opthelpers.h" inline constexpr std::size_t UhjLength256{256}; @@ -36,7 +37,7 @@ struct UhjAllPassFilter { }; -struct UhjEncoderBase { +struct SIMDALIGN UhjEncoderBase { UhjEncoderBase() = default; UhjEncoderBase(const UhjEncoderBase&) = delete; UhjEncoderBase(UhjEncoderBase&&) = delete; @@ -120,7 +121,7 @@ struct UhjEncoderIIR final : public UhjEncoderBase { }; -struct DecoderBase { +struct SIMDALIGN DecoderBase { static constexpr std::size_t sMaxPadding{256}; /* For 2-channel UHJ, shelf filters should use these LF responses. */ diff --git a/core/voice.h b/core/voice.h index c983c3e9f7..a55367aaf6 100644 --- a/core/voice.h +++ b/core/voice.h @@ -10,7 +10,6 @@ #include #include -#include "almalloc.h" #include "alspan.h" #include "bufferline.h" #include "buffer_storage.h" @@ -20,6 +19,7 @@ #include "filters/splitter.h" #include "mixer/defs.h" #include "mixer/hrtfdefs.h" +#include "opthelpers.h" #include "resampler_limits.h" #include "uhjfilter.h" #include "vector.h" @@ -180,7 +180,7 @@ enum : uint { VoiceFlagCount }; -struct Voice { +struct SIMDALIGN Voice { enum State { Stopped, Playing,