diff options
author | Steve Ellcey <sellcey@caviumnetworks.com> | 2017-08-31 13:38:11 -0700 |
---|---|---|
committer | Steve Ellcey <sellcey@caviumnetworks.com> | 2017-08-31 13:38:11 -0700 |
commit | d9ff799a5b2884d2abc0a1689fb6b2c71084424c (patch) | |
tree | c10c6256fd563ac826dffde3a547ff919a15d1e8 /sysdeps/aarch64/fpu | |
parent | 102dde842ae75ddee71a413fc8c4320894e159de (diff) | |
download | glibc-d9ff799a5b2884d2abc0a1689fb6b2c71084424c.tar.gz glibc-d9ff799a5b2884d2abc0a1689fb6b2c71084424c.tar.xz glibc-d9ff799a5b2884d2abc0a1689fb6b2c71084424c.zip |
ILP32 math changes
* sysdeps/aarch64/fpu/s_llrint.c (OREG_SIZE): New macro. * sysdeps/aarch64/fpu/s_llround.c (OREG_SIZE): Likewise. * sysdeps/aarch64/fpu/s_llrintf.c (OREGS, IREGS): Remove. (IREG_SIZE, OREG_SIZE): New macros. * sysdeps/aarch64/fpu/s_llroundf.c: (OREGS, IREGS): Remove. (IREG_SIZE, OREG_SIZE): New macros. * sysdeps/aarch64/fpu/s_lrintf.c (IREGS): Remove. (IREG_SIZE): New macro. * sysdeps/aarch64/fpu/s_lroundf.c (IREGS): Remove. (IREG_SIZE): New macro. * sysdeps/aarch64/fpu/s_lrint.c (get-rounding-mode.h, stdint.h): New includes. (IREG_SIZE, OREG_SIZE): Initialize if not already set. (OREGS, IREGS): Set based on IREG_SIZE and OREG_SIZE. (__CONCATX): Handle exceptions correctly on large values that may set FE_INVALID. * sysdeps/aarch64/fpu/s_lround.c (IREG_SIZE, OREG_SIZE): Initialize if not already set. (OREGS, IREGS): Set based on IREG_SIZE and OREG_SIZE.
Diffstat (limited to 'sysdeps/aarch64/fpu')
-rw-r--r-- | sysdeps/aarch64/fpu/s_llrint.c | 1 | ||||
-rw-r--r-- | sysdeps/aarch64/fpu/s_llrintf.c | 3 | ||||
-rw-r--r-- | sysdeps/aarch64/fpu/s_llround.c | 1 | ||||
-rw-r--r-- | sysdeps/aarch64/fpu/s_llroundf.c | 3 | ||||
-rw-r--r-- | sysdeps/aarch64/fpu/s_lrint.c | 60 | ||||
-rw-r--r-- | sysdeps/aarch64/fpu/s_lrintf.c | 2 | ||||
-rw-r--r-- | sysdeps/aarch64/fpu/s_lround.c | 27 | ||||
-rw-r--r-- | sysdeps/aarch64/fpu/s_lroundf.c | 2 |
8 files changed, 87 insertions, 12 deletions
diff --git a/sysdeps/aarch64/fpu/s_llrint.c b/sysdeps/aarch64/fpu/s_llrint.c index c0d0d0e879..57821c02f8 100644 --- a/sysdeps/aarch64/fpu/s_llrint.c +++ b/sysdeps/aarch64/fpu/s_llrint.c @@ -18,4 +18,5 @@ #define FUNC llrint #define OTYPE long long int +#define OREG_SIZE 64 #include <s_lrint.c> diff --git a/sysdeps/aarch64/fpu/s_llrintf.c b/sysdeps/aarch64/fpu/s_llrintf.c index 67724c6d47..98ed4f864e 100644 --- a/sysdeps/aarch64/fpu/s_llrintf.c +++ b/sysdeps/aarch64/fpu/s_llrintf.c @@ -18,6 +18,7 @@ #define FUNC llrintf #define ITYPE float -#define IREGS "s" +#define IREG_SIZE 32 #define OTYPE long long int +#define OREG_SIZE 64 #include <s_lrint.c> diff --git a/sysdeps/aarch64/fpu/s_llround.c b/sysdeps/aarch64/fpu/s_llround.c index ed4b192d5c..ef7aedf36b 100644 --- a/sysdeps/aarch64/fpu/s_llround.c +++ b/sysdeps/aarch64/fpu/s_llround.c @@ -18,4 +18,5 @@ #define FUNC llround #define OTYPE long long int +#define OREG_SIZE 64 #include <s_lround.c> diff --git a/sysdeps/aarch64/fpu/s_llroundf.c b/sysdeps/aarch64/fpu/s_llroundf.c index 360ce8b4c5..294f0f4761 100644 --- a/sysdeps/aarch64/fpu/s_llroundf.c +++ b/sysdeps/aarch64/fpu/s_llroundf.c @@ -18,6 +18,7 @@ #define FUNC llroundf #define ITYPE float -#define IREGS "s" +#define IREG_SIZE 32 #define OTYPE long long int +#define OREG_SIZE 64 #include <s_lround.c> diff --git a/sysdeps/aarch64/fpu/s_lrint.c b/sysdeps/aarch64/fpu/s_lrint.c index 8c61a039bf..6ef64e22bf 100644 --- a/sysdeps/aarch64/fpu/s_lrint.c +++ b/sysdeps/aarch64/fpu/s_lrint.c @@ -17,6 +17,8 @@ <http://www.gnu.org/licenses/>. */ #include <math.h> +#include <get-rounding-mode.h> +#include <stdint.h> #ifndef FUNC # define FUNC lrint @@ -24,18 +26,37 @@ #ifndef ITYPE # define ITYPE double -# define IREGS "d" +# define IREG_SIZE 64 #else -# ifndef IREGS -# error IREGS not defined +# ifndef IREG_SIZE +# error IREG_SIZE not defined # endif #endif #ifndef OTYPE # define OTYPE long int +# ifdef __ILP32__ +# define OREG_SIZE 32 +# else +# define OREG_SIZE 64 +# endif +#else +# ifndef OREG_SIZE +# error OREG_SIZE not defined +# endif #endif -#define OREGS "x" +#if IREG_SIZE == 32 +# define IREGS "s" +#else +# define IREGS "d" +#endif + +#if OREG_SIZE == 32 +# define OREGS "w" +#else +# define OREGS "x" +#endif #define __CONCATX(a,b) __CONCAT(a,b) @@ -44,6 +65,37 @@ __CONCATX(__,FUNC) (ITYPE x) { OTYPE result; ITYPE temp; + +#if IREG_SIZE == 64 && OREG_SIZE == 32 + if (__builtin_fabs (x) > INT32_MAX) + { + /* Converting large values to a 32 bit int may cause the frintx/fcvtza + sequence to set both FE_INVALID and FE_INEXACT. To avoid this + check the rounding mode and do a single instruction with the + appropriate rounding mode. */ + + switch (get_rounding_mode ()) + { + case FE_TONEAREST: + asm volatile ("fcvtns" "\t%" OREGS "0, %" IREGS "1" + : "=r" (result) : "w" (x)); + break; + case FE_UPWARD: + asm volatile ("fcvtps" "\t%" OREGS "0, %" IREGS "1" + : "=r" (result) : "w" (x)); + break; + case FE_DOWNWARD: + asm volatile ("fcvtms" "\t%" OREGS "0, %" IREGS "1" + : "=r" (result) : "w" (x)); + break; + case FE_TOWARDZERO: + default: + asm volatile ("fcvtzs" "\t%" OREGS "0, %" IREGS "1" + : "=r" (result) : "w" (x)); + } + return result; + } +#endif asm ( "frintx" "\t%" IREGS "1, %" IREGS "2\n\t" "fcvtzs" "\t%" OREGS "0, %" IREGS "1" : "=r" (result), "=w" (temp) : "w" (x) ); diff --git a/sysdeps/aarch64/fpu/s_lrintf.c b/sysdeps/aarch64/fpu/s_lrintf.c index a995e4b96f..2e73271497 100644 --- a/sysdeps/aarch64/fpu/s_lrintf.c +++ b/sysdeps/aarch64/fpu/s_lrintf.c @@ -18,5 +18,5 @@ #define FUNC lrintf #define ITYPE float -#define IREGS "s" +#define IREG_SIZE 32 #include <s_lrint.c> diff --git a/sysdeps/aarch64/fpu/s_lround.c b/sysdeps/aarch64/fpu/s_lround.c index 9be9e7fb0f..1f77d82e33 100644 --- a/sysdeps/aarch64/fpu/s_lround.c +++ b/sysdeps/aarch64/fpu/s_lround.c @@ -24,18 +24,37 @@ #ifndef ITYPE # define ITYPE double -# define IREGS "d" +# define IREG_SIZE 64 #else -# ifndef IREGS -# error IREGS not defined +# ifndef IREG_SIZE +# error IREG_SIZE not defined # endif #endif #ifndef OTYPE # define OTYPE long int +# ifdef __ILP32__ +# define OREG_SIZE 32 +# else +# define OREG_SIZE 64 +# endif +#else +# ifndef OREG_SIZE +# error OREG_SIZE not defined +# endif +#endif + +#if IREG_SIZE == 32 +# define IREGS "s" +#else +# define IREGS "d" #endif -#define OREGS "x" +#if OREG_SIZE == 32 +# define OREGS "w" +#else +# define OREGS "x" +#endif #define __CONCATX(a,b) __CONCAT(a,b) diff --git a/sysdeps/aarch64/fpu/s_lroundf.c b/sysdeps/aarch64/fpu/s_lroundf.c index 4a066d4816..b30ddb6dbb 100644 --- a/sysdeps/aarch64/fpu/s_lroundf.c +++ b/sysdeps/aarch64/fpu/s_lroundf.c @@ -18,5 +18,5 @@ #define FUNC lroundf #define ITYPE float -#define IREGS "s" +#define IREG_SIZE 32 #include <s_lround.c> |