mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-23 03:52:12 -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)
|
#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
|
#else
|
||||||
|
|
||||||
#define div64_32(a, b) ((fixed_t)((a) / (b)))
|
#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)
|
inline static fixed_t FixedDiv(fixed_t a, fixed_t b)
|
||||||
{
|
{
|
||||||
// [FG] avoid 31-bit shift (from Chocolate Doom)
|
// [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;
|
return (a ^ b) < 0 ? INT_MIN : INT_MAX;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user