forked from Mirrors/tinycc
Fix signed integer division in ARM runtime ABI
- fix computation of absolute value (clearing the sign bit does not since integers are encoded in 2's complement) - test sign of integer in a more conventional way (binary and with the high bit does not work for long long due to a bug in gtst) - spacing in includemaster
parent
f2dbcf7594
commit
a24e31e85d
|
@ -1,4 +1,4 @@
|
||||||
#include<limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
/* We rely on the little endianness and EABI calling convention for this to
|
/* We rely on the little endianness and EABI calling convention for this to
|
||||||
work */
|
work */
|
||||||
|
@ -331,16 +331,22 @@ void __aeabi_ ## name(type numerator, type denominator) \
|
||||||
urettype uxdiv_ret; \
|
urettype uxdiv_ret; \
|
||||||
rettype ret; \
|
rettype ret; \
|
||||||
\
|
\
|
||||||
num = numerator & typemacro ## _MAX; \
|
if (numerator >= 0) \
|
||||||
den = denominator & typemacro ## _MAX; \
|
num = numerator; \
|
||||||
|
else \
|
||||||
|
num = 0 - numerator; \
|
||||||
|
if (denominator >= 0) \
|
||||||
|
den = denominator; \
|
||||||
|
else \
|
||||||
|
den = 0 - denominator; \
|
||||||
uxdiv_ret = aeabi_ ## uiname(num, den); \
|
uxdiv_ret = aeabi_ ## uiname(num, den); \
|
||||||
/* signs differ */ \
|
/* signs differ */ \
|
||||||
if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
|
if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
|
||||||
ret.quot = uxdiv_ret.quot * -1; \
|
ret.quot = 0 - uxdiv_ret.quot; \
|
||||||
else \
|
else \
|
||||||
ret.quot = uxdiv_ret.quot; \
|
ret.quot = uxdiv_ret.quot; \
|
||||||
if (numerator & typemacro ## _MIN) \
|
if (numerator < 0) \
|
||||||
ret.rem = uxdiv_ret.rem * -1; \
|
ret.rem = 0 - uxdiv_ret.rem; \
|
||||||
else \
|
else \
|
||||||
ret.rem = uxdiv_ret.rem; \
|
ret.rem = uxdiv_ret.rem; \
|
||||||
\
|
\
|
||||||
|
@ -420,8 +426,14 @@ int __aeabi_idiv(int numerator, int denominator)
|
||||||
unsigned num, den;
|
unsigned num, den;
|
||||||
uidiv_t ret;
|
uidiv_t ret;
|
||||||
|
|
||||||
num = numerator & INT_MAX;
|
if (numerator >= 0)
|
||||||
den = denominator & INT_MAX;
|
num = numerator;
|
||||||
|
else
|
||||||
|
num = 0 - numerator;
|
||||||
|
if (denominator >= 0)
|
||||||
|
den = denominator;
|
||||||
|
else
|
||||||
|
den = 0 - denominator;
|
||||||
ret = aeabi_uidivmod(num, den);
|
ret = aeabi_uidivmod(num, den);
|
||||||
if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
|
if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
|
||||||
ret.quot *= -1;
|
ret.quot *= -1;
|
||||||
|
|
Loading…
Reference in New Issue