diff options
-rw-r--r-- | Alc/effects/pshifter.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/Alc/effects/pshifter.c b/Alc/effects/pshifter.c index bf36f5eb..7411f705 100644 --- a/Alc/effects/pshifter.c +++ b/Alc/effects/pshifter.c @@ -108,8 +108,32 @@ static alonce_flag HannInitOnce = AL_ONCE_FLAG_INIT; static inline ALint double2int(ALdouble d) { - /* TODO: Make a more efficient version for x87. */ +#if ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) && \ + !defined(__SSE2_MATH__)) || (defined(_MSC_VER) && defined(_M_IX86_FP) && _M_IX86_FP < 2) + ALint sign, shift; + ALint64 mant; + union { + ALdouble d; + ALint64 i64; + } conv; + + conv.d = d; + sign = (conv.i64>>63) | 1; + shift = ((conv.i64>>52)&0x7ff) - (1023+52); + + /* Over/underflow */ + if(UNLIKELY(shift >= 63 || shift < -52)) + return 0; + + mant = (conv.i64&U64(0xfffffffffffff)) | U64(0x10000000000000); + if(LIKELY(shift < 0)) + return (ALint)(mant >> -shift) * sign; + return (ALint)(mant << shift) * sign; + +#else + return (ALint)d; +#endif } |