From 5062680c602c27c9128ae2e38d199df22a8c2d38 Mon Sep 17 00:00:00 2001 From: Michael Collison Date: Mon, 23 Oct 2017 10:28:01 +0100 Subject: aarch64: Implement math acceleration via builtins This patch converts asm statements into builtins for AArch64. As an example for the file sysdeps/aarch64/fpu/s_ceil.c, we convert the function from double __ceil (double x) { double result; asm ("frintp\t%d0, %d1" : "=w" (result) : "w" (x) ); return result; } into double __ceil (double x) { return __builtin_ceil (x); } Tested on aarch64-linux-gnu with gcc-4.9.4 and gcc-6. * sysdeps/aarch64/fpu/e_sqrt.c (ieee754_sqrt): Replace asm statements with __builtin_sqrt. * sysdeps/aarch64/fpu/e_sqrtf.c (ieee754_sqrtf): Replace asm statements with __builtin_sqrtf. * sysdeps/aarch64/fpu/s_ceil.c (__ceil): Replace asm statements with __builtin_ceil. * sysdeps/aarch64/fpu/s_ceilf.c (__ceilf): Replace asm statements with __builtin_ceilf. * sysdeps/aarch64/fpu/s_floor.c (__floor): Replace asm statements with __builtin_floor. * sysdeps/aarch64/fpu/s_floorf.c (__floorf): Replace asm statements with __builtin_floorf. * sysdeps/aarch64/fpu/s_fma.c (__fma): Replace asm statements with __builtin_fma. * sysdeps/aarch64/fpu/s_fmaf.c (__fmaf): Replace asm statements with __builtin_fmaf. * sysdeps/aarch64/fpu/s_fmax.c (__fmax): Replace asm statements with __builtin_fmax. * sysdeps/aarch64/fpu/s_fmaxf.c (__fmaxf): Replace asm statements with __builtin_fmaxf. * sysdeps/aarch64/fpu/s_fmin.c (__fmin): Replace asm statements with __builtin_fmin. * sysdeps/aarch64/fpu/s_fminf.c (__fminf): Replace asm statements with __builtin_fminf. * sysdeps/aarch64/fpu/s_frint.c: Delete file. * sysdeps/aarch64/fpu/s_frintf.c: Delete file. * sysdeps/aarch64/fpu/s_llrint.c (__llrint): Replace asm statements with builtin_rint and conversion to int. * sysdeps/aarch64/fpu/s_llrintf.c (__llrintf): Likewise. * sysdeps/aarch64/fpu/s_llround.c (__llround): Replace asm statements with builtin_llround. * sysdeps/aarch64/fpu/s_llroundf.c (__llroundf): Likewise. * sysdeps/aarch64/fpu/s_lrint.c (__lrint): Replace asm statements with builtin_rint and conversion to long int. * sysdeps/aarch64/fpu/s_lrintf.c (__lrintf): Likewise. * sysdeps/aarch64/fpu/s_lround.c (__lround): Replace asm statements with builtin_lround. * sysdeps/aarch64/fpu/s_lroundf.c (__lroundf): Replace asm statements with builtin_lroundf. * sysdeps/aarch64/fpu/s_nearbyint.c (__nearbyint): Replace asm statements with __builtin_nearbyint. * sysdeps/aarch64/fpu/s_nearbyintf.c (__nearbyintf): Replace asm statements with __builtin_nearbyintf. * sysdeps/aarch64/fpu/s_rint.c (__rint): Replace asm statements with __builtin_rint. * sysdeps/aarch64/fpu/s_rintf.c (__rintf): Replace asm statements with __builtin_rintf. * sysdeps/aarch64/fpu/s_round.c (__round): Replace asm statements with __builtin_round. * sysdeps/aarch64/fpu/s_roundf.c (__roundf): Replace asm statements with __builtin_roundf. * sysdeps/aarch64/fpu/s_trunc.c (__trunc): Replace asm statements with __builtin_trunc. * sysdeps/aarch64/fpu/s_truncf.c (__truncf): Replace asm statements with __builtin_truncf. * sysdeps/aarch64/fpu/Makefile: Build e_sqrt[f].c with -fno-math-errno. --- ChangeLog | 59 ++++++++++++++++++++++++++++++++++++++ sysdeps/aarch64/fpu/e_sqrt.c | 4 +-- sysdeps/aarch64/fpu/e_sqrtf.c | 4 +-- sysdeps/aarch64/fpu/s_ceil.c | 12 ++++++-- sysdeps/aarch64/fpu/s_ceilf.c | 12 ++++++-- sysdeps/aarch64/fpu/s_floor.c | 12 ++++++-- sysdeps/aarch64/fpu/s_floorf.c | 12 ++++++-- sysdeps/aarch64/fpu/s_fma.c | 26 +++-------------- sysdeps/aarch64/fpu/s_fmaf.c | 13 ++++++--- sysdeps/aarch64/fpu/s_fmax.c | 12 ++++++-- sysdeps/aarch64/fpu/s_fmaxf.c | 14 +++++---- sysdeps/aarch64/fpu/s_fmin.c | 30 +++---------------- sysdeps/aarch64/fpu/s_fminf.c | 13 ++++++--- sysdeps/aarch64/fpu/s_frint.c | 49 ------------------------------- sysdeps/aarch64/fpu/s_frintf.c | 24 ---------------- sysdeps/aarch64/fpu/s_llrint.c | 20 ++++++++++--- sysdeps/aarch64/fpu/s_llrintf.c | 23 +++++++++++---- sysdeps/aarch64/fpu/s_llround.c | 13 ++++++--- sysdeps/aarch64/fpu/s_llroundf.c | 15 ++++++---- sysdeps/aarch64/fpu/s_lrint.c | 46 +++++++++-------------------- sysdeps/aarch64/fpu/s_lrintf.c | 20 ++++++++++--- sysdeps/aarch64/fpu/s_lround.c | 55 ++++------------------------------- sysdeps/aarch64/fpu/s_lroundf.c | 13 ++++++--- sysdeps/aarch64/fpu/s_nearbyint.c | 12 ++++++-- sysdeps/aarch64/fpu/s_nearbyintf.c | 12 ++++++-- sysdeps/aarch64/fpu/s_rint.c | 12 ++++++-- sysdeps/aarch64/fpu/s_rintf.c | 12 ++++++-- sysdeps/aarch64/fpu/s_round.c | 12 ++++++-- sysdeps/aarch64/fpu/s_roundf.c | 12 ++++++-- sysdeps/aarch64/fpu/s_trunc.c | 12 ++++++-- sysdeps/aarch64/fpu/s_truncf.c | 12 ++++++-- 31 files changed, 309 insertions(+), 288 deletions(-) delete mode 100644 sysdeps/aarch64/fpu/s_frint.c delete mode 100644 sysdeps/aarch64/fpu/s_frintf.c diff --git a/ChangeLog b/ChangeLog index 677f46d61a..4a011b136b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,62 @@ +2017-10-23 Michael Collison + + * sysdeps/aarch64/fpu/e_sqrt.c (ieee754_sqrt): Replace asm statements + with __builtin_sqrt. + * sysdeps/aarch64/fpu/e_sqrtf.c (ieee754_sqrtf): Replace asm statements + with __builtin_sqrtf. + * sysdeps/aarch64/fpu/s_ceil.c (__ceil): Replace asm statements + with __builtin_ceil. + * sysdeps/aarch64/fpu/s_ceilf.c (__ceilf): Replace asm statements + with __builtin_ceilf. + * sysdeps/aarch64/fpu/s_floor.c (__floor): Replace asm statements + with __builtin_floor. + * sysdeps/aarch64/fpu/s_floorf.c (__floorf): Replace asm statements + with __builtin_floorf. + * sysdeps/aarch64/fpu/s_fma.c (__fma): Replace asm statements + with __builtin_fma. + * sysdeps/aarch64/fpu/s_fmaf.c (__fmaf): Replace asm statements + with __builtin_fmaf. + * sysdeps/aarch64/fpu/s_fmax.c (__fmax): Replace asm statements + with __builtin_fmax. + * sysdeps/aarch64/fpu/s_fmaxf.c (__fmaxf): Replace asm statements + with __builtin_fmaxf. + * sysdeps/aarch64/fpu/s_fmin.c (__fmin): Replace asm statements + with __builtin_fmin. + * sysdeps/aarch64/fpu/s_fminf.c (__fminf): Replace asm statements + with __builtin_fminf. + * sysdeps/aarch64/fpu/s_frint.c: Delete file. + * sysdeps/aarch64/fpu/s_frintf.c: Delete file. + * sysdeps/aarch64/fpu/s_llrint.c (__llrint): Replace asm statements + with builtin_rint and conversion to int. + * sysdeps/aarch64/fpu/s_llrintf.c (__llrintf): Likewise. + * sysdeps/aarch64/fpu/s_llround.c (__llround): Replace asm statements + with builtin_llround. + * sysdeps/aarch64/fpu/s_llroundf.c (__llroundf): Likewise. + * sysdeps/aarch64/fpu/s_lrint.c (__lrint): Replace asm statements + with builtin_rint and conversion to long int. + * sysdeps/aarch64/fpu/s_lrintf.c (__lrintf): Likewise. + * sysdeps/aarch64/fpu/s_lround.c (__lround): Replace asm statements + with builtin_lround. + * sysdeps/aarch64/fpu/s_lroundf.c (__lroundf): Replace asm statements + with builtin_lroundf. + * sysdeps/aarch64/fpu/s_nearbyint.c (__nearbyint): Replace asm + statements with __builtin_nearbyint. + * sysdeps/aarch64/fpu/s_nearbyintf.c (__nearbyintf): Replace asm + statements with __builtin_nearbyintf. + * sysdeps/aarch64/fpu/s_rint.c (__rint): Replace asm statements + with __builtin_rint. + * sysdeps/aarch64/fpu/s_rintf.c (__rintf): Replace asm statements + with __builtin_rintf. + * sysdeps/aarch64/fpu/s_round.c (__round): Replace asm statements + with __builtin_round. + * sysdeps/aarch64/fpu/s_roundf.c (__roundf): Replace asm statements + with __builtin_roundf. + * sysdeps/aarch64/fpu/s_trunc.c (__trunc): Replace asm statements + with __builtin_trunc. + * sysdeps/aarch64/fpu/s_truncf.c (__truncf): Replace asm statements + with __builtin_truncf. + * sysdeps/aarch64/fpu/Makefile: Build e_sqrt[f].c with -fno-math-errno. + 2017-10-23 Alan Modra * sysdeps/powerpc/powerpc64/power8/strncpy.S: Move LR cfi. diff --git a/sysdeps/aarch64/fpu/e_sqrt.c b/sysdeps/aarch64/fpu/e_sqrt.c index f984d877b6..b80ac27261 100644 --- a/sysdeps/aarch64/fpu/e_sqrt.c +++ b/sysdeps/aarch64/fpu/e_sqrt.c @@ -21,8 +21,6 @@ double __ieee754_sqrt (double d) { - double res; - asm ("fsqrt %d0, %d1" : "=w" (res) : "w" (d)); - return res; + return __builtin_sqrt (d); } strong_alias (__ieee754_sqrt, __sqrt_finite) diff --git a/sysdeps/aarch64/fpu/e_sqrtf.c b/sysdeps/aarch64/fpu/e_sqrtf.c index 67707ef833..73804542c8 100644 --- a/sysdeps/aarch64/fpu/e_sqrtf.c +++ b/sysdeps/aarch64/fpu/e_sqrtf.c @@ -21,8 +21,6 @@ float __ieee754_sqrtf (float s) { - float res; - asm ("fsqrt %s0, %s1" : "=w" (res) : "w" (s)); - return res; + return __builtin_sqrtf (s); } strong_alias (__ieee754_sqrtf, __sqrtf_finite) diff --git a/sysdeps/aarch64/fpu/s_ceil.c b/sysdeps/aarch64/fpu/s_ceil.c index d0a8bd8981..bc90ab98db 100644 --- a/sysdeps/aarch64/fpu/s_ceil.c +++ b/sysdeps/aarch64/fpu/s_ceil.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC ceil -#define INSN "frintp" -#include +#include + +double +__ceil (double x) +{ + return __builtin_ceil (x); +} + +weak_alias (__ceil, ceil) diff --git a/sysdeps/aarch64/fpu/s_ceilf.c b/sysdeps/aarch64/fpu/s_ceilf.c index b9c2e7c3e5..d5c438335e 100644 --- a/sysdeps/aarch64/fpu/s_ceilf.c +++ b/sysdeps/aarch64/fpu/s_ceilf.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC ceilf -#define INSN "frintp" -#include +#include + +float +__ceilf (float x) +{ + return __builtin_ceilf (x); +} + +weak_alias (__ceilf, ceilf) diff --git a/sysdeps/aarch64/fpu/s_floor.c b/sysdeps/aarch64/fpu/s_floor.c index f7f8731d98..049535c8bf 100644 --- a/sysdeps/aarch64/fpu/s_floor.c +++ b/sysdeps/aarch64/fpu/s_floor.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC floor -#define INSN "frintm" -#include +#include + +double +__floor (double x) +{ + return __builtin_floor (x); +} + +weak_alias (__floor, floor) diff --git a/sysdeps/aarch64/fpu/s_floorf.c b/sysdeps/aarch64/fpu/s_floorf.c index 7be63b5a04..fa6fa17907 100644 --- a/sysdeps/aarch64/fpu/s_floorf.c +++ b/sysdeps/aarch64/fpu/s_floorf.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC floorf -#define INSN "frintm" -#include +#include + +float +__floorf (float x) +{ + return __builtin_floorf (x); +} + +weak_alias (__floorf, floorf) diff --git a/sysdeps/aarch64/fpu/s_fma.c b/sysdeps/aarch64/fpu/s_fma.c index 6f62ce2365..e496ec6438 100644 --- a/sysdeps/aarch64/fpu/s_fma.c +++ b/sysdeps/aarch64/fpu/s_fma.c @@ -18,28 +18,10 @@ #include -#ifndef FUNC -# define FUNC fma -#endif - -#ifndef TYPE -# define TYPE double -# define REGS "d" -#else -# ifndef REGS -# error REGS not defined -# endif -#endif - -#define __CONCATX(a,b) __CONCAT(a,b) - -TYPE -__CONCATX(__,FUNC) (TYPE x, TYPE y, TYPE z) +double +__fma (double x, double y, double z) { - TYPE result; - asm ( "fmadd" "\t%" REGS "0, %" REGS "1, %" REGS "2, %" REGS "3" - : "=w" (result) : "w" (x), "w" (y), "w" (z) ); - return result; + return __builtin_fma (x, y, z); } -weak_alias (__CONCATX(__,FUNC), FUNC) +weak_alias (__fma, fma) diff --git a/sysdeps/aarch64/fpu/s_fmaf.c b/sysdeps/aarch64/fpu/s_fmaf.c index 880a22dfd4..ff1abbf5b4 100644 --- a/sysdeps/aarch64/fpu/s_fmaf.c +++ b/sysdeps/aarch64/fpu/s_fmaf.c @@ -16,7 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC fmaf -#define TYPE float -#define REGS "s" -#include +#include + +float +__fmaf (float x, float y, float z) +{ + return __builtin_fmaf (x, y, z); +} + +weak_alias (__fmaf, fmaf) diff --git a/sysdeps/aarch64/fpu/s_fmax.c b/sysdeps/aarch64/fpu/s_fmax.c index 395a9bacfd..d7a82f8980 100644 --- a/sysdeps/aarch64/fpu/s_fmax.c +++ b/sysdeps/aarch64/fpu/s_fmax.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC fmax -#define INSN "fmaxnm" -#include +#include + +double +__fmax (double x, double y) +{ + return __builtin_fmax (x, y); +} + +weak_alias (__fmax, fmax) diff --git a/sysdeps/aarch64/fpu/s_fmaxf.c b/sysdeps/aarch64/fpu/s_fmaxf.c index f450d9fe82..ec4dcdd8c0 100644 --- a/sysdeps/aarch64/fpu/s_fmaxf.c +++ b/sysdeps/aarch64/fpu/s_fmaxf.c @@ -16,8 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC fmaxf -#define INSN "fmaxnm" -#define TYPE float -#define REGS "s" -#include +#include + +float +__fmaxf (float x, float y) +{ + return __builtin_fmaxf (x, y); +} + +weak_alias (__fmaxf, fmaxf) diff --git a/sysdeps/aarch64/fpu/s_fmin.c b/sysdeps/aarch64/fpu/s_fmin.c index b6d32d5050..bba894e9b0 100644 --- a/sysdeps/aarch64/fpu/s_fmin.c +++ b/sysdeps/aarch64/fpu/s_fmin.c @@ -18,32 +18,10 @@ #include -#ifndef FUNC -# define FUNC fmin -#endif - -#ifndef INSN -# define INSN "fminnm" -#endif - -#ifndef TYPE -# define TYPE double -# define REGS "d" -#else -# ifndef REGS -# error REGS not defined -# endif -#endif - -#define __CONCATX(a,b) __CONCAT(a,b) - -TYPE -__CONCATX(__,FUNC) (TYPE x, TYPE y) +double +__fmin (double x, double y) { - TYPE result; - asm ( INSN "\t%" REGS "0, %" REGS "1, %" REGS "2" - : "=w" (result) : "w" (x), "w" (y) ); - return result; + return __builtin_fmin (x, y); } -weak_alias (__CONCATX(__,FUNC), FUNC) +weak_alias (__fmin, fmin) diff --git a/sysdeps/aarch64/fpu/s_fminf.c b/sysdeps/aarch64/fpu/s_fminf.c index 032262d953..7d3a3a3a32 100644 --- a/sysdeps/aarch64/fpu/s_fminf.c +++ b/sysdeps/aarch64/fpu/s_fminf.c @@ -16,7 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC fminf -#define TYPE float -#define REGS "s" -#include +#include + +float +__fminf (float x, float y) +{ + return __builtin_fminf (x, y); +} + +weak_alias (__fminf, fminf) diff --git a/sysdeps/aarch64/fpu/s_frint.c b/sysdeps/aarch64/fpu/s_frint.c deleted file mode 100644 index 48881f5868..0000000000 --- a/sysdeps/aarch64/fpu/s_frint.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include - -#ifndef FUNC -# error FUNC not defined -#endif - -#ifndef TYPE -# define TYPE double -# define REGS "d" -#else -# ifndef REGS -# error REGS not defined -# endif -#endif - -#ifndef INSN -# error INSN not defined -#endif - -#define __CONCATX(a,b) __CONCAT(a,b) - -TYPE -__CONCATX(__,FUNC) (TYPE x) -{ - TYPE result; - asm ( INSN "\t%" REGS "0, %" REGS "1" : - "=w" (result) : "w" (x) ); - return result; -} - -weak_alias (__CONCATX(__,FUNC), FUNC) diff --git a/sysdeps/aarch64/fpu/s_frintf.c b/sysdeps/aarch64/fpu/s_frintf.c deleted file mode 100644 index dae99d7816..0000000000 --- a/sysdeps/aarch64/fpu/s_frintf.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright (C) 2011-2017 Free Software Foundation, Inc. - - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef FUNC -# error FUNC not defined -#endif -#define TYPE float -#define REGS "s" -#include diff --git a/sysdeps/aarch64/fpu/s_llrint.c b/sysdeps/aarch64/fpu/s_llrint.c index 57821c02f8..f0e0b09b52 100644 --- a/sysdeps/aarch64/fpu/s_llrint.c +++ b/sysdeps/aarch64/fpu/s_llrint.c @@ -16,7 +16,19 @@ License along with the GNU C Library; if not, see . */ -#define FUNC llrint -#define OTYPE long long int -#define OREG_SIZE 64 -#include +#include +#include + +long long int +__llrint (double x) +{ + double r = __builtin_rint (x); + + /* Prevent gcc from calling llrint directly when compiled with + -fno-math-errno by inserting a barrier. */ + + math_opt_barrier (r); + return r; +} + +weak_alias (__llrint, llrint) diff --git a/sysdeps/aarch64/fpu/s_llrintf.c b/sysdeps/aarch64/fpu/s_llrintf.c index 98ed4f864e..dac73f2058 100644 --- a/sysdeps/aarch64/fpu/s_llrintf.c +++ b/sysdeps/aarch64/fpu/s_llrintf.c @@ -16,9 +16,20 @@ License along with the GNU C Library; if not, see . */ -#define FUNC llrintf -#define ITYPE float -#define IREG_SIZE 32 -#define OTYPE long long int -#define OREG_SIZE 64 -#include +#include +#include + +long long int +__llrintf (float x) +{ + float r = __builtin_rintf (x); + + /* Prevent gcc from calling llrintf directly when compiled with + -fno-math-errno by inserting a barrier. */ + + + math_opt_barrier (r); + return r; +} + +weak_alias (__llrintf, llrintf) diff --git a/sysdeps/aarch64/fpu/s_llround.c b/sysdeps/aarch64/fpu/s_llround.c index ef7aedf36b..2902946bcd 100644 --- a/sysdeps/aarch64/fpu/s_llround.c +++ b/sysdeps/aarch64/fpu/s_llround.c @@ -16,7 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC llround -#define OTYPE long long int -#define OREG_SIZE 64 -#include +#include + +long long int +__llround (double x) +{ + return __builtin_llround (x); +} + +weak_alias (__llround, llround) diff --git a/sysdeps/aarch64/fpu/s_llroundf.c b/sysdeps/aarch64/fpu/s_llroundf.c index 294f0f4761..0ca390baec 100644 --- a/sysdeps/aarch64/fpu/s_llroundf.c +++ b/sysdeps/aarch64/fpu/s_llroundf.c @@ -16,9 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC llroundf -#define ITYPE float -#define IREG_SIZE 32 -#define OTYPE long long int -#define OREG_SIZE 64 -#include +#include + +long long int +__llroundf (float x) +{ + return __builtin_llroundf (x); +} + +weak_alias (__llroundf, llroundf) diff --git a/sysdeps/aarch64/fpu/s_lrint.c b/sysdeps/aarch64/fpu/s_lrint.c index 6ef64e22bf..ee645ad29e 100644 --- a/sysdeps/aarch64/fpu/s_lrint.c +++ b/sysdeps/aarch64/fpu/s_lrint.c @@ -19,38 +19,17 @@ #include #include #include +#include -#ifndef FUNC -# define FUNC lrint -#endif - -#ifndef ITYPE -# define ITYPE double # define IREG_SIZE 64 -#else -# 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 #if OREG_SIZE == 32 # define OREGS "w" @@ -58,15 +37,14 @@ # define OREGS "x" #endif -#define __CONCATX(a,b) __CONCAT(a,b) -OTYPE -__CONCATX(__,FUNC) (ITYPE x) +long int +__lrint (double x) { - OTYPE result; - ITYPE temp; #if IREG_SIZE == 64 && OREG_SIZE == 32 + long int result; + if (__builtin_fabs (x) > INT32_MAX) { /* Converting large values to a 32 bit int may cause the frintx/fcvtza @@ -96,10 +74,14 @@ __CONCATX(__,FUNC) (ITYPE 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) ); - return result; + + double r = __builtin_rint (x); + + /* Prevent gcc from calling lrint directly when compiled with + -fno-math-errno by inserting a barrier. */ + + math_opt_barrier (r); + return r; } -weak_alias (__CONCATX(__,FUNC), FUNC) +weak_alias (__lrint, lrint) diff --git a/sysdeps/aarch64/fpu/s_lrintf.c b/sysdeps/aarch64/fpu/s_lrintf.c index 2e73271497..5b6a426937 100644 --- a/sysdeps/aarch64/fpu/s_lrintf.c +++ b/sysdeps/aarch64/fpu/s_lrintf.c @@ -16,7 +16,19 @@ License along with the GNU C Library; if not, see . */ -#define FUNC lrintf -#define ITYPE float -#define IREG_SIZE 32 -#include +#include +#include + +long int +__lrintf (float x) +{ + float r = __builtin_rintf (x); + + /* Prevent gcc from calling lrintf directly when compiled with + -fno-math-errno by inserting a barrier. */ + + math_opt_barrier (r); + return r; +} + +weak_alias (__lrintf, lrintf) diff --git a/sysdeps/aarch64/fpu/s_lround.c b/sysdeps/aarch64/fpu/s_lround.c index 1f77d82e33..90c3163e8e 100644 --- a/sysdeps/aarch64/fpu/s_lround.c +++ b/sysdeps/aarch64/fpu/s_lround.c @@ -18,53 +18,10 @@ #include -#ifndef FUNC -# define FUNC lround -#endif +long int +__lround (double x) + { + return __builtin_lround (x); + } -#ifndef ITYPE -# define ITYPE double -# define IREG_SIZE 64 -#else -# 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 - -#if OREG_SIZE == 32 -# define OREGS "w" -#else -# define OREGS "x" -#endif - -#define __CONCATX(a,b) __CONCAT(a,b) - -OTYPE -__CONCATX(__,FUNC) (ITYPE x) -{ - OTYPE result; - asm ( "fcvtas" "\t%" OREGS "0, %" IREGS "1" - : "=r" (result) : "w" (x) ); - return result; -} - -weak_alias (__CONCATX(__,FUNC), FUNC) +weak_alias (__lround, lround) diff --git a/sysdeps/aarch64/fpu/s_lroundf.c b/sysdeps/aarch64/fpu/s_lroundf.c index b30ddb6dbb..baf06938be 100644 --- a/sysdeps/aarch64/fpu/s_lroundf.c +++ b/sysdeps/aarch64/fpu/s_lroundf.c @@ -16,7 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC lroundf -#define ITYPE float -#define IREG_SIZE 32 -#include +#include + +long int +__lroundf (float x) +{ + return __builtin_lroundf (x); +} + +weak_alias (__lroundf, lroundf) diff --git a/sysdeps/aarch64/fpu/s_nearbyint.c b/sysdeps/aarch64/fpu/s_nearbyint.c index 51067f23c8..6ba5de11e7 100644 --- a/sysdeps/aarch64/fpu/s_nearbyint.c +++ b/sysdeps/aarch64/fpu/s_nearbyint.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC nearbyint -#define INSN "frinti" -#include +#include + +double +__nearbyint (double x) +{ + return __builtin_nearbyint (x); +} + +weak_alias (__nearbyint, nearbyint) diff --git a/sysdeps/aarch64/fpu/s_nearbyintf.c b/sysdeps/aarch64/fpu/s_nearbyintf.c index 8125646c2e..de69fd9b82 100644 --- a/sysdeps/aarch64/fpu/s_nearbyintf.c +++ b/sysdeps/aarch64/fpu/s_nearbyintf.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC nearbyintf -#define INSN "frinti" -#include +#include + +float +__nearbyintf (float x) +{ + return __builtin_nearbyintf (x); +} + +weak_alias (__nearbyintf, nearbyintf) diff --git a/sysdeps/aarch64/fpu/s_rint.c b/sysdeps/aarch64/fpu/s_rint.c index 73b4e26786..b4ac349fc0 100644 --- a/sysdeps/aarch64/fpu/s_rint.c +++ b/sysdeps/aarch64/fpu/s_rint.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC rint -#define INSN "frintx" -#include +#include + +double +__rint (double x) +{ + return __builtin_rint (x); +} + +weak_alias (__rint, rint) diff --git a/sysdeps/aarch64/fpu/s_rintf.c b/sysdeps/aarch64/fpu/s_rintf.c index 3560dc2827..d0f70ce925 100644 --- a/sysdeps/aarch64/fpu/s_rintf.c +++ b/sysdeps/aarch64/fpu/s_rintf.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC rintf -#define INSN "frintx" -#include +#include + +float +__rintf (float x) +{ + return __builtin_rintf (x); +} + +weak_alias (__rintf, rintf) diff --git a/sysdeps/aarch64/fpu/s_round.c b/sysdeps/aarch64/fpu/s_round.c index 67817485c3..a34fca1196 100644 --- a/sysdeps/aarch64/fpu/s_round.c +++ b/sysdeps/aarch64/fpu/s_round.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC round -#define INSN "frinta" -#include +#include + +double +__round (double x) +{ + return __builtin_round (x); +} + +weak_alias (__round, round) diff --git a/sysdeps/aarch64/fpu/s_roundf.c b/sysdeps/aarch64/fpu/s_roundf.c index ef6f672c7d..66c8ee6d09 100644 --- a/sysdeps/aarch64/fpu/s_roundf.c +++ b/sysdeps/aarch64/fpu/s_roundf.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC roundf -#define INSN "frinta" -#include +#include + +float +__roundf (float x) +{ + return __builtin_roundf (x); +} + +weak_alias (__roundf, roundf) diff --git a/sysdeps/aarch64/fpu/s_trunc.c b/sysdeps/aarch64/fpu/s_trunc.c index 2bf5474a7e..6550dfcdb6 100644 --- a/sysdeps/aarch64/fpu/s_trunc.c +++ b/sysdeps/aarch64/fpu/s_trunc.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC trunc -#define INSN "frintz" -#include +#include + +double +__trunc (double x) +{ + return __builtin_trunc (x); +} + +weak_alias (__trunc, trunc) diff --git a/sysdeps/aarch64/fpu/s_truncf.c b/sysdeps/aarch64/fpu/s_truncf.c index 94865a470b..b7890a2d94 100644 --- a/sysdeps/aarch64/fpu/s_truncf.c +++ b/sysdeps/aarch64/fpu/s_truncf.c @@ -16,6 +16,12 @@ License along with the GNU C Library; if not, see . */ -#define FUNC truncf -#define INSN "frintz" -#include +#include + +float +__truncf (float x) +{ + return __builtin_truncf (x); +} + +weak_alias (__truncf, truncf) -- cgit 1.4.1