From d9ff799a5b2884d2abc0a1689fb6b2c71084424c Mon Sep 17 00:00:00 2001 From: Steve Ellcey Date: Thu, 31 Aug 2017 13:38:11 -0700 Subject: [PATCH] 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. --- ChangeLog | 23 +++++++++++++++ sysdeps/aarch64/fpu/s_llrint.c | 1 + sysdeps/aarch64/fpu/s_llrintf.c | 3 +- sysdeps/aarch64/fpu/s_llround.c | 1 + sysdeps/aarch64/fpu/s_llroundf.c | 3 +- sysdeps/aarch64/fpu/s_lrint.c | 60 +++++++++++++++++++++++++++++++++++++--- sysdeps/aarch64/fpu/s_lrintf.c | 2 +- sysdeps/aarch64/fpu/s_lround.c | 27 +++++++++++++++--- sysdeps/aarch64/fpu/s_lroundf.c | 2 +- 9 files changed, 110 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index a934c69393..4841dca473 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2017-08-31 Steve Ellcey + Richard Henderson + + * 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. + 2017-08-31 Adhemerval Zanella * sysdeps/generic/not-cancel.h (NO_CANCELLATION): Remove macro. 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 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 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 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 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 @@ . */ #include +#include +#include #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 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 -- 2.11.4.GIT