diff --git a/lib/libtcc1.c b/lib/libtcc1.c index 87f4e84..58324a9 100644 --- a/lib/libtcc1.c +++ b/lib/libtcc1.c @@ -533,21 +533,22 @@ unsigned long long __fixunssfdi (float a1) register union float_long fl1; register int exp; register unsigned long l; - + int s; fl1.f = a1; if (fl1.l == 0) - return (0); + return 0; exp = EXP (fl1.l) - EXCESS - 24; l = MANT(fl1.l); - if (exp >= 41) - return (unsigned long long)-1; + s = SIGN(fl1.l)? -1: 1; + if (exp >= 64) + return (unsigned long long)-1; else if (exp >= 0) - return (unsigned long long)l << exp; + return ((unsigned long long)l << exp)*s; else if (exp >= -23) - return l >> -exp; + return (l >> -exp)*s; else return 0; } @@ -557,22 +558,22 @@ unsigned long long __fixunsdfdi (double a1) register union double_long dl1; register int exp; register unsigned long long l; - + int s; dl1.d = a1; if (dl1.ll == 0) - return (0); + return (0); exp = EXPD (dl1) - EXCESSD - 53; l = MANTD_LL(dl1); - - if (exp >= 12) - return (unsigned long long)-1; + s = SIGND(dl1)? -1: 1; + if (exp >= 64) + return (unsigned long long)-1; else if (exp >= 0) - return l << exp; + return (l << exp)*s; else if (exp >= -52) - return l >> -exp; + return (l >> -exp)*s; else return 0; } @@ -582,20 +583,22 @@ unsigned long long __fixunsxfdi (long double a1) register union ldouble_long dl1; register int exp; register unsigned long long l; - + int s; dl1.ld = a1; if (dl1.l.lower == 0 && dl1.l.upper == 0) - return (0); + return (0); exp = EXPLD (dl1) - EXCESSLD - 64; - + s = SIGNLD(dl1)? -1: 1; l = dl1.l.lower; - if (exp > 0) - return (unsigned long long)-1; - else if (exp >= -63) - return l >> -exp; + if (exp >= 64) + return (unsigned long long)-1; + else if (exp >= 0) + return ((unsigned long long)l << exp)*s; + else if (exp >= -64) + return (l >> -exp)*s; else return 0; } @@ -637,7 +640,7 @@ extern void abort(void); #endif enum __va_arg_type { - __va_gen_reg, __va_float_reg, __va_stack + __va_gen_reg, __va_float_reg, __va_ld_reg, __va_stack }; //This should be in sync with the declaration on our include/stdarg.h diff --git a/tests/tcctest.c b/tests/tcctest.c index 66a1cac..22a8278 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -1729,7 +1729,6 @@ void prefix ## fcast(type a)\ printf("ftof: %f %f %Lf\n", fa, da, la);\ ia = (int)a;\ llia = (long long)a;\ - a = (a >= 0) ? a : -a;\ ua = (unsigned int)a;\ llua = (unsigned long long)a;\ printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\ @@ -1759,6 +1758,18 @@ void prefix ## call(void)\ printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\ }\ \ +void prefix ## calc(type x, type y)\ +{\ + x=x*x;y=y*y;\ + printf("%d, %d\n", (int)x, (int)y);\ + x=x-y;y=y-x;\ + printf("%d, %d\n", (int)x, (int)y);\ + x=x/y;y=y/x;\ + printf("%d, %d\n", (int)x, (int)y);\ + x=x+x;y=y+y;\ + printf("%d, %d\n", (int)x, (int)y);\ +}\ +\ void prefix ## signed_zeros(void) \ {\ type x = 0.0, y = -0.0, n, p;\ @@ -1781,7 +1792,7 @@ void prefix ## signed_zeros(void) \ 1.0 / x != 1.0 / p);\ else\ printf ("x != +y; this is wrong!\n");\ - p = -y;\ + p = -y;\ if (x == p)\ printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\ 1.0 / x != 1.0 / p);\ @@ -1797,6 +1808,7 @@ void prefix ## test(void)\ prefix ## fcast(234.6);\ prefix ## fcast(-2334.6);\ prefix ## call();\ + prefix ## calc(1, 1.0000000000000001);\ prefix ## signed_zeros();\ } @@ -2623,7 +2635,6 @@ int constant_p_var; void builtin_test(void) { -#if GCC_MAJOR >= 3 COMPAT_TYPE(int, int); COMPAT_TYPE(int, unsigned int); COMPAT_TYPE(int, char); @@ -2633,9 +2644,9 @@ void builtin_test(void) COMPAT_TYPE(int *, void *); COMPAT_TYPE(int *, const int *); COMPAT_TYPE(char *, unsigned char *); + COMPAT_TYPE(char, unsigned char); /* space is needed because tcc preprocessor introduces a space between each token */ - COMPAT_TYPE(char * *, void *); -#endif + COMPAT_TYPE(char **, void *); printf("res = %d\n", __builtin_constant_p(1)); printf("res = %d\n", __builtin_constant_p(1 + 2)); printf("res = %d\n", __builtin_constant_p(&constant_p_var));