mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-22 19:38:06 -04:00
Fix potential overflow in FixedDiv, re-add gcc asm implementation (#1832)
* Revert "remove GCC variant of `div64_32` (#1818)" This reverts commit fac7cf789fd9063b523d85dc17b8e6ac701459ae. * Remove asm multi-constraint clang generates poor code otherwise: https://stackoverflow.com/questions/16850309/clang-llvm-inline-assembly-multiple-constraints-with-useless-spills-reload * Fix potential FixedDiv overflow when passed INT_MIN as first arg
This commit is contained in:
parent
89aae9c789
commit
458c61ae2d
@ -30,6 +30,20 @@
|
||||
|
||||
#define div64_32(a, b) _div64((a), (b), NULL)
|
||||
|
||||
#elif defined(__GNUC__) && defined(__x86_64__)
|
||||
|
||||
inline static int32_t div64_32(int64_t a, int32_t b)
|
||||
{
|
||||
if (__builtin_constant_p(b))
|
||||
{
|
||||
return a / b;
|
||||
}
|
||||
int32_t lo = a;
|
||||
int32_t hi = a >> 32;
|
||||
asm("idivl %[divisor]" : "+a" (lo), "+d" (hi) : [divisor] "r" (b));
|
||||
return lo;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define div64_32(a, b) ((fixed_t)((a) / (b)))
|
||||
@ -72,7 +86,7 @@ inline static int64_t FixedMul64(int64_t a, int64_t b)
|
||||
inline static fixed_t FixedDiv(fixed_t a, fixed_t b)
|
||||
{
|
||||
// [FG] avoid 31-bit shift (from Chocolate Doom)
|
||||
if ((abs(a) >> 14) >= abs(b))
|
||||
if (((unsigned)abs(a) >> 14) >= (unsigned)abs(b))
|
||||
{
|
||||
return (a ^ b) < 0 ? INT_MIN : INT_MAX;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user