| commit de751ebc9efa97ce0115e42bd55fa1beeb614380 |
| Author: Paul A. Clarke <pc@us.ibm.com> |
| Date: Fri Mar 15 19:04:24 2019 -0400 |
| |
| [powerpc] get_rounding_mode: utilize faster method to get rounding mode |
| |
| Add support to use 'mffsl' instruction if compiled for POWER9 (or later). |
| |
| Also, mask the result to avoid bleeding unrelated bits into the result of |
| _FPU_GET_RC(). |
| |
| Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> |
| |
| diff --git a/sysdeps/powerpc/fpu/get-rounding-mode.h b/sysdeps/powerpc/fpu/get-rounding-mode.h |
| new file mode 100644 |
| index 0000000000000000..e2fdbbbcce72bd66 |
| |
| |
| @@ -0,0 +1,33 @@ |
| +/* Determine floating-point rounding mode within libc. powerpc64 version. |
| + Copyright (C) 2019 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 |
| + <http://www.gnu.org/licenses/>. */ |
| + |
| +#ifndef _POWERPC64_GET_ROUNDING_MODE_H |
| +#define _POWERPC64_GET_ROUNDING_MODE_H 1 |
| + |
| +#include <fenv.h> |
| +#include <fpu_control.h> |
| + |
| +/* Return the floating-point rounding mode. */ |
| + |
| +static inline int |
| +get_rounding_mode (void) |
| +{ |
| + return _FPU_GET_RC (); |
| +} |
| + |
| +#endif /* get-rounding-mode.h */ |
| diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h |
| index 9d0698b4fc3eb595..62c478d72ae660cb 100644 |
| |
| |
| @@ -71,6 +71,8 @@ extern fpu_control_t __fpu_control; |
| # define _FPU_RC_UP 0x02 |
| # define _FPU_RC_ZERO 0x01 |
| |
| +# define _FPU_MASK_RC (_FPU_RC_NEAREST|_FPU_RC_DOWN|_FPU_RC_UP|_FPU_RC_ZERO) |
| + |
| # define _FPU_MASK_NI 0x04 /* non-ieee mode */ |
| |
| /* masking of interrupts */ |
| @@ -94,15 +96,36 @@ extern fpu_control_t __fpu_control; |
| typedef unsigned int fpu_control_t; |
| |
| /* Macros for accessing the hardware control word. */ |
| +# define __FPU_MFFS() \ |
| + ({register double __fr; \ |
| + __asm__ ("mffs %0" : "=f" (__fr)); \ |
| + __fr; \ |
| + }) |
| + |
| # define _FPU_GETCW(cw) \ |
| ({union { double __d; unsigned long long __ll; } __u; \ |
| - register double __fr; \ |
| - __asm__ ("mffs %0" : "=f" (__fr)); \ |
| - __u.__d = __fr; \ |
| + __u.__d = __FPU_MFFS(); \ |
| (cw) = (fpu_control_t) __u.__ll; \ |
| (fpu_control_t) __u.__ll; \ |
| }) |
| |
| +#ifdef _ARCH_PWR9 |
| +# define __FPU_MFFSL() \ |
| + ({register double __fr; \ |
| + __asm__ ("mffsl %0" : "=f" (__fr)); \ |
| + __fr; \ |
| + }) |
| +#else |
| +# define __FPU_MFFSL() __FPU_MFFS() |
| +#endif |
| + |
| +# define _FPU_GET_RC() \ |
| + ({union { double __d; unsigned long long __ll; } __u; \ |
| + __u.__d = __FPU_MFFSL(); \ |
| + __u.__ll &= _FPU_MASK_RC; \ |
| + (fpu_control_t) __u.__ll; \ |
| + }) |
| + |
| # define _FPU_SETCW(cw) \ |
| { union { double __d; unsigned long long __ll; } __u; \ |
| register double __fr; \ |