diff options
author | Sergey Dmitrouk <sdmitrouk@accesssoftek.com> | 2015-04-06 11:54:51 +0000 |
---|---|---|
committer | Sergey Dmitrouk <sdmitrouk@accesssoftek.com> | 2015-04-06 11:54:51 +0000 |
commit | 0bca6b4e196838da6c317a0786b1927d0dcc9296 (patch) | |
tree | 577423a4b4b489f67add64522ceffe41aeff071e | |
parent | 520f9cce77f7ac8196f1091b7c1b38722a490f38 (diff) |
Add hard float versions of FP to LL conversions
This adds hard-float implementation for the following builtins:
* __fixdfdi()
* __fixsfdi()
* __fixunsdfdi()
* __fixunssfdi()
The soft-float implementation does never raise floating point
exceptions, which doesn't allow clients to detect floating point
conversion errors.
I must mention that I had to refer to libgcc's implementation to
write these functions.
Related unit-tests of compiler-rt passed with these changes.
Patch was somewhat out-dated, so was updated locally without any
functional changes.
Differential Revision: http://reviews.llvm.org/D5376
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@234148 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/builtins/fixdfdi.c | 24 | ||||
-rw-r--r-- | lib/builtins/fixsfdi.c | 24 | ||||
-rw-r--r-- | lib/builtins/fixunsdfdi.c | 26 | ||||
-rw-r--r-- | lib/builtins/fixunssfdi.c | 27 |
4 files changed, 97 insertions, 4 deletions
diff --git a/lib/builtins/fixdfdi.c b/lib/builtins/fixdfdi.c index 67b124a16..14283ef42 100644 --- a/lib/builtins/fixdfdi.c +++ b/lib/builtins/fixdfdi.c @@ -12,6 +12,28 @@ #include "fp_lib.h" 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. + */ + typedef di_int fixint_t; typedef du_int fixuint_t; #include "fp_fixint_impl.inc" @@ -20,3 +42,5 @@ COMPILER_RT_ABI di_int __fixdfdi(fp_t a) { return __fixint(a); } + +#endif diff --git a/lib/builtins/fixsfdi.c b/lib/builtins/fixsfdi.c index 835ff852d..fab47e272 100644 --- a/lib/builtins/fixsfdi.c +++ b/lib/builtins/fixsfdi.c @@ -13,6 +13,28 @@ 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. + */ + typedef di_int fixint_t; typedef du_int fixuint_t; #include "fp_fixint_impl.inc" @@ -21,3 +43,5 @@ COMPILER_RT_ABI di_int __fixsfdi(fp_t a) { return __fixint(a); } + +#endif diff --git a/lib/builtins/fixunsdfdi.c b/lib/builtins/fixunsdfdi.c index f4f689e39..b93d1c10b 100644 --- a/lib/builtins/fixunsdfdi.c +++ b/lib/builtins/fixunsdfdi.c @@ -10,12 +10,34 @@ #define DOUBLE_PRECISION #include "fp_lib.h" -typedef du_int fixuint_t; -#include "fp_fixuint_impl.inc" 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. + */ + +typedef du_int fixuint_t; +#include "fp_fixuint_impl.inc" + COMPILER_RT_ABI du_int __fixunsdfdi(fp_t a) { return __fixuint(a); } + +#endif diff --git a/lib/builtins/fixunssfdi.c b/lib/builtins/fixunssfdi.c index cd21cfd18..374ebbe82 100644 --- a/lib/builtins/fixunssfdi.c +++ b/lib/builtins/fixunssfdi.c @@ -10,12 +10,35 @@ #define SINGLE_PRECISION #include "fp_lib.h" -typedef du_int fixuint_t; -#include "fp_fixuint_impl.inc" 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. + */ + +typedef du_int fixuint_t; +#include "fp_fixuint_impl.inc" + COMPILER_RT_ABI du_int __fixunssfdi(fp_t a) { return __fixuint(a); } + +#endif |