aboutsummaryrefslogtreecommitdiff
path: root/lib/armeabi.c
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2013-12-15 09:44:20 +0800
committerThomas Preud'homme <robotux@celest.fr>2013-12-15 09:44:20 +0800
commita24e31e85d2980bf4863ad3dd371c6501810ae97 (patch)
tree9e000eb0939857a8087e998b51af37863993f733 /lib/armeabi.c
parentf2dbcf7594887ddfdec646ab2a85f4e2358ec209 (diff)
downloadtinycc-a24e31e85d2980bf4863ad3dd371c6501810ae97.tar.gz
tinycc-a24e31e85d2980bf4863ad3dd371c6501810ae97.tar.bz2
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 include
Diffstat (limited to 'lib/armeabi.c')
-rw-r--r--lib/armeabi.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/lib/armeabi.c b/lib/armeabi.c
index c00ace6..e787ec1 100644
--- a/lib/armeabi.c
+++ b/lib/armeabi.c
@@ -1,4 +1,4 @@
-#include<limits.h>
+#include <limits.h>
/* We rely on the little endianness and EABI calling convention for this to
work */
@@ -325,22 +325,28 @@ static inline rettype aeabi_ ## name (type num, type den) \
}
#define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro) \
-void __aeabi_ ## name(type numerator, type denominator) \
+void __aeabi_ ## name(type numerator, type denominator) \
{ \
unsigned type num, den; \
urettype uxdiv_ret; \
rettype ret; \
\
- num = numerator & typemacro ## _MAX; \
- den = denominator & typemacro ## _MAX; \
+ if (numerator >= 0) \
+ num = numerator; \
+ else \
+ num = 0 - numerator; \
+ if (denominator >= 0) \
+ den = denominator; \
+ else \
+ den = 0 - denominator; \
uxdiv_ret = aeabi_ ## uiname(num, den); \
/* signs differ */ \
if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
- ret.quot = uxdiv_ret.quot * -1; \
+ ret.quot = 0 - uxdiv_ret.quot; \
else \
ret.quot = uxdiv_ret.quot; \
- if (numerator & typemacro ## _MIN) \
- ret.rem = uxdiv_ret.rem * -1; \
+ if (numerator < 0) \
+ ret.rem = 0 - uxdiv_ret.rem; \
else \
ret.rem = uxdiv_ret.rem; \
\
@@ -420,8 +426,14 @@ int __aeabi_idiv(int numerator, int denominator)
unsigned num, den;
uidiv_t ret;
- num = numerator & INT_MAX;
- den = denominator & INT_MAX;
+ if (numerator >= 0)
+ num = numerator;
+ else
+ num = 0 - numerator;
+ if (denominator >= 0)
+ den = denominator;
+ else
+ den = 0 - denominator;
ret = aeabi_uidivmod(num, den);
if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
ret.quot *= -1;