[3/4] Add ILP32 support to aarch64

Message ID d2ded737-80dd-aa78-4a3b-0262c77cbed5@twiddle.net
State New, archived
Headers

Commit Message

Richard Henderson Aug. 28, 2017, 2:52 p.m. UTC
  On 08/08/2017 11:10 AM, Steve Ellcey wrote:
> @@ -44,6 +66,32 @@ __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
> +         we save and restore the FE and only set one or the other.  */
> +
> +      fenv_t env;
> +      int feflags;
> +
> +      libc_feholdexcept (&env);
> +      asm ( "frintx" "\t%" IREGS "1, %" IREGS "2\n\t"
> +	    "fcvtzs" "\t%" OREGS "0, %" IREGS "1"
> +	    : "=r" (result), "=w" (temp) : "w" (x) );
> +      feflags = libc_fetestexcept (FE_INVALID | FE_INEXACT);
> +      libc_fesetenv (&env);
> +
> +      if (feflags & FE_INVALID)
> +	feraiseexcept (FE_INVALID);
> +      else if (feflags & FE_INEXACT)
> +	feraiseexcept (FE_INEXACT);
> +
> +      return result;
> +  }
> +#endif

Surely it is simply better to do the conversion in one step, getting the proper
flags set the first time.  Like so.


r~
  

Comments

Szabolcs Nagy Aug. 29, 2017, 10:32 a.m. UTC | #1
On 28/08/17 15:52, Richard Henderson wrote:
> Surely it is simply better to do the conversion in one step, getting the proper
> flags set the first time.  Like so.
> 

hm true, for ilp32, but on lp64 you don't want
unnecessary fpcr access and dispatch on the rounding mode.
  

Patch

diff --git a/sysdeps/aarch64/fpu/s_lrint.c b/sysdeps/aarch64/fpu/s_lrint.c
index 8c61a039bf..a6ac070fa6 100644
--- a/sysdeps/aarch64/fpu/s_lrint.c
+++ b/sysdeps/aarch64/fpu/s_lrint.c
@@ -17,6 +17,7 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #include <math.h>
+#include <get-rounding-mode.h>
 
 #ifndef FUNC
 # define FUNC lrint
@@ -43,10 +44,25 @@  OTYPE
 __CONCATX(__,FUNC) (ITYPE x)
 {
   OTYPE result;
-  ITYPE temp;
-  asm ( "frintx" "\t%" IREGS "1, %" IREGS "2\n\t"
-        "fcvtzs" "\t%" OREGS "0, %" IREGS "1"
-        : "=r" (result), "=w" (temp) : "w" (x) );
+  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;
+    default:
+    case FE_TOWARDZERO:
+      asm volatile ("fcvtzs" "\t%" OREGS "0, %" IREGS "1"
+		    : "=r" (result) : "w" (x));
+    }
   return result;
 }