Index: lib/builtins/fixdfdi.c =================================================================== --- lib/builtins/fixdfdi.c +++ lib/builtins/fixdfdi.c @@ -17,7 +17,9 @@ /* Returns: convert a to a signed long long, rounding toward zero. */ /* Assumption: double is a IEEE 64 bit floating point type - * su_int is a 32 bit integral type + * si_int is a 32 bit integral type + * di_int is a 64 bit integral type + * du_int is a 64 bit integral type * value in double is representable in di_int (no range checking performed) */ @@ -25,6 +27,27 @@ ARM_EABI_FNALIAS(d2lz, fixdfdi) +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; can set the invalid flag as + * a side-effect of computation. + */ + +COMPILER_RT_ABI du_int __fixunsdfdi(double a); + +COMPILER_RT_ABI di_int +__fixdfdi(double a) +{ + if (a < 0.0) { + return -__fixunsdfdi(-a); + } + return __fixunsdfdi(a); +} + +#else +/* Support for systems that don't have hardware floating-point; there are no flags to + * set, and we don't want to code-gen to an unknown soft-float implementation. + */ + COMPILER_RT_ABI di_int __fixdfdi(double a) { @@ -42,4 +65,6 @@ else r.all >>= (52 - e); return (r.all ^ s) - s; -} +} + +#endif Index: lib/builtins/fixsfdi.c =================================================================== --- lib/builtins/fixsfdi.c +++ lib/builtins/fixsfdi.c @@ -16,8 +16,11 @@ /* Returns: convert a to a signed long long, rounding toward zero. */ -/* Assumption: float is a IEEE 32 bit floating point type - * su_int is a 32 bit integral type +/* Assumption: float is a IEEE 32 bit floating point type + * double is a IEEE 64 bit floating point type + * si_int is a 32 bit integral type + * di_int is a 64 bit integral type + * du_int is a 64 bit integral type * value in float is representable in di_int (no range checking performed) */ @@ -25,6 +28,27 @@ ARM_EABI_FNALIAS(f2lz, fixsfdi) +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; can set the invalid flag as + * a side-effect of computation. + */ + +COMPILER_RT_ABI du_int __fixunssfdi(float a); + +COMPILER_RT_ABI di_int +__fixsfdi(float a) +{ + if (a < 0.0f) { + return -__fixunssfdi(-a); + } + return __fixunssfdi(a); +} + +#else +/* Support for systems that don't have hardware floating-point; there are no flags to + * set, and we don't want to code-gen to an unknown soft-float implementation. + */ + COMPILER_RT_ABI di_int __fixsfdi(float a) { @@ -41,3 +65,5 @@ r >>= (23 - e); return (r ^ s) - s; } + +#endif Index: lib/builtins/fixunsdfdi.c =================================================================== --- lib/builtins/fixunsdfdi.c +++ lib/builtins/fixunsdfdi.c @@ -18,9 +18,10 @@ * Negative values all become zero. */ -/* Assumption: double is a IEEE 64 bit floating point type +/* Assumption: double is a IEEE 64 bit floating point type + * su_int is a 32 bit integral type * du_int is a 64 bit integral type - * value in double is representable in du_int or is negative + * value in double is representable in du_int or is negative * (no range checking performed) */ @@ -28,6 +29,24 @@ ARM_EABI_FNALIAS(d2ulz, fixunsdfdi) +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; can set the invalid flag as + * a side-effect of computation. + */ + +COMPILER_RT_ABI du_int +__fixunsdfdi(double a) +{ + su_int high = a/0x1p32f; + su_int low = a - (double)high*0x1p32f; + return ((du_int)high << 32) | low; +} + +#else +/* Support for systems that don't have hardware floating-point; there are no flags to + * set, and we don't want to code-gen to an unknown soft-float implementation. + */ + COMPILER_RT_ABI du_int __fixunsdfdi(double a) { @@ -45,3 +64,5 @@ r.all >>= (52 - e); return r.all; } + +#endif Index: lib/builtins/fixunssfdi.c =================================================================== --- lib/builtins/fixunssfdi.c +++ lib/builtins/fixunssfdi.c @@ -18,6 +18,7 @@ */ /* Assumption: float is a IEEE 32 bit floating point type + * su_int is a 32 bit integral type * du_int is a 64 bit integral type * value in float is representable in du_int or is negative * (no range checking performed) @@ -27,6 +28,25 @@ ARM_EABI_FNALIAS(f2ulz, fixunssfdi) +#ifndef __SOFT_FP__ +/* Support for systems that have hardware floating-point; can set the invalid flag as + * a side-effect of computation. + */ + +COMPILER_RT_ABI du_int +__fixunssfdi(float a) +{ + double da = a; + su_int high = da/0x1p32f; + su_int low = da - (double)high*0x1p32f; + return ((du_int)high << 32) | low; +} + +#else +/* Support for systems that don't have hardware floating-point; there are no flags to + * set, and we don't want to code-gen to an unknown soft-float implementation. + */ + COMPILER_RT_ABI du_int __fixunssfdi(float a) { @@ -42,3 +62,5 @@ r >>= (23 - e); return r; } + +#endif