diff options
Diffstat (limited to 'contrib/compiler-rt/lib/builtins/fixxfti.c')
-rw-r--r-- | contrib/compiler-rt/lib/builtins/fixxfti.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/contrib/compiler-rt/lib/builtins/fixxfti.c b/contrib/compiler-rt/lib/builtins/fixxfti.c index 3d0a279b3842..968a4f0d5eea 100644 --- a/contrib/compiler-rt/lib/builtins/fixxfti.c +++ b/contrib/compiler-rt/lib/builtins/fixxfti.c @@ -19,8 +19,8 @@ /* Returns: convert a to a signed long long, rounding toward zero. */ /* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes - * su_int is a 32 bit integral type - * value in long double is representable in ti_int (no range checking performed) + * ti_int is a 128 bit integral type + * value in long double is representable in ti_int */ /* gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | @@ -30,6 +30,8 @@ COMPILER_RT_ABI ti_int __fixxfti(long double a) { + const ti_int ti_max = (ti_int)((~(tu_int)0) / 2); + const ti_int ti_min = -ti_max - 1; long_double_bits fb; fb.f = a; int e = (fb.u.high.s.low & 0x00007FFF) - 16383; @@ -37,6 +39,8 @@ __fixxfti(long double a) return 0; ti_int s = -(si_int)((fb.u.high.s.low & 0x00008000) >> 15); ti_int r = fb.u.low.all; + if ((unsigned)e >= sizeof(ti_int) * CHAR_BIT) + return a > 0 ? ti_max : ti_min; if (e > 63) r <<= (e - 63); else |