[powerpc] Use __builtin_{mffs,mtfsf}
Commit Message
From: "Paul A. Clarke" <pc@us.ibm.com>
Replace inline asm uses of the "mffs" and "mtfsf" instructions with
the analogous GCC builtins.
__builtin_mffs and __builtin_mtfsf are both available in GCC 5 and above.
Given the minimum GCC level for GLibC is now GCC 6.2, it is safe to use
these builtins without restriction.
2019-03-14 Paul A. Clarke <pc@us.ibm.com>
* sysdeps/powerpc/fpu/fenv_libc.h (fegetenv_register): Replace inline
asm with builtin.
* sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Likewise.
(_FPU_SETCW): Likewise.
* sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h (FP_INIT_ROUNDMODE):
Likewise.
* sysdeps/powerpc/fpu/tst-setcontext-fpscr.c (_GET_DI_FPSCR): Likewise.
(_GET_SI_FPSCR): Likewise.
(_SET_SI_FPSCR): Likewise.
---
sysdeps/powerpc/fpu/fenv_libc.h | 5 ++---
sysdeps/powerpc/fpu/tst-setcontext-fpscr.c | 10 +++-------
sysdeps/powerpc/fpu_control.h | 8 ++------
sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h | 3 +--
4 files changed, 8 insertions(+), 18 deletions(-)
Comments
On 14/03/2019 19:45, Paul A. Clarke wrote:
> From: "Paul A. Clarke" <pc@us.ibm.com>
>
> Replace inline asm uses of the "mffs" and "mtfsf" instructions with
> the analogous GCC builtins.
>
> __builtin_mffs and __builtin_mtfsf are both available in GCC 5 and above.
> Given the minimum GCC level for GLibC is now GCC 6.2, it is safe to use
> these builtins without restriction.
>
> 2019-03-14 Paul A. Clarke <pc@us.ibm.com>
>
> * sysdeps/powerpc/fpu/fenv_libc.h (fegetenv_register): Replace inline
> asm with builtin.
> * sysdeps/powerpc/fpu_control.h (_FPU_GETCW): Likewise.
> (_FPU_SETCW): Likewise.
> * sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h (FP_INIT_ROUNDMODE):
> Likewise.
> * sysdeps/powerpc/fpu/tst-setcontext-fpscr.c (_GET_DI_FPSCR): Likewise.
> (_GET_SI_FPSCR): Likewise.
> (_SET_SI_FPSCR): Likewise.
LGTM with the change below.
> ---
> sysdeps/powerpc/fpu/fenv_libc.h | 5 ++---
> sysdeps/powerpc/fpu/tst-setcontext-fpscr.c | 10 +++-------
> sysdeps/powerpc/fpu_control.h | 8 ++------
> sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h | 3 +--
> 4 files changed, 8 insertions(+), 18 deletions(-)
>
> diff --git a/sysdeps/powerpc/fpu/fenv_libc.h b/sysdeps/powerpc/fpu/fenv_libc.h
> index 67a9c9a..8a0bace 100644
> --- a/sysdeps/powerpc/fpu/fenv_libc.h
> +++ b/sysdeps/powerpc/fpu/fenv_libc.h
> @@ -32,8 +32,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
>
> /* Equivalent to fegetenv, but returns a fenv_t instead of taking a
> pointer. */
> -#define fegetenv_register() \
> - ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; })
> +#define fegetenv_register() __builtin_mffs()
>
> /* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */
> #define fesetenv_register(env) \
> @@ -45,7 +44,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
> "mtfsf 0xff,%0,1,0; " \
> ".machine pop" : : "f" (d)); \
> else \
> - asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \
> + __builtin_mtfsf (0xff, d); \
> } while(0)
>
> /* This very handy macro:
> diff --git a/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c b/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c
> index 958afff..7dfd5a9 100644
> --- a/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c
> +++ b/sysdeps/powerpc/fpu/tst-setcontext-fpscr.c
> @@ -97,9 +97,7 @@ typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
> /* Macros for accessing the hardware control word on Power6[x]. */
> #define _GET_DI_FPSCR(__fpscr) \
> ({union { double d; di_fpscr_t fpscr; } u; \
> - register double fr; \
> - __asm__ ("mffs %0" : "=f" (fr)); \
> - u.d = fr; \
> + u.d = __builtin_mffs (); \
> (__fpscr) = u.fpscr; \
> u.fpscr; \
> })
> @@ -121,9 +119,7 @@ typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
>
> # define _GET_SI_FPSCR(__fpscr) \
> ({union { double d; di_fpscr_t fpscr; } u; \
> - register double fr; \
> - __asm__ ("mffs %0" : "=f" (fr)); \
> - u.d = fr; \
> + u.d = __builtin_mffs (); \
> (__fpscr) = (si_fpscr_t) u.fpscr; \
> (si_fpscr_t) u.fpscr; \
> })
> @@ -137,7 +133,7 @@ typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
> u.fpscr = 0xfff80000ULL << 32; \
> u.fpscr |= __fpscr & 0xffffffffULL; \
> fr = u.d; \
> - __asm__ ("mtfsf 255,%0" : : "f" (fr)); \
> + __builtin_mtfsf (255, fr); \
> fr = 0.0; \
> }
>
> diff --git a/sysdeps/powerpc/fpu_control.h b/sysdeps/powerpc/fpu_control.h
> index e0c5cf6..a48d3cc 100644
> --- a/sysdeps/powerpc/fpu_control.h
> +++ b/sysdeps/powerpc/fpu_control.h
> @@ -96,20 +96,16 @@ typedef unsigned int fpu_control_t;
> /* Macros for accessing the hardware control word. */
> # 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 = __builtin_mffs (); \
> (cw) = (fpu_control_t) __u.__ll; \
> (fpu_control_t) __u.__ll; \
> })
This is an installed header and thus might be used with a compiler that
does not support the builtins.
>
> # define _FPU_SETCW(cw) \
> { union { double __d; unsigned long long __ll; } __u; \
> - register double __fr; \
> __u.__ll = 0xfff80000LL << 32; /* This is a QNaN. */ \
> __u.__ll |= (cw) & 0xffffffffLL; \
> - __fr = __u.__d; \
> - __asm__ ("mtfsf 255,%0" : : "f" (__fr)); \
> + __builtin_mtfsf (255, __u.__d); \
> }
>
> /* Default control word set at startup. */
> diff --git a/sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h b/sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h
> index ac74097..b4b27f9 100644
> --- a/sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h
> +++ b/sysdeps/powerpc/powerpc64/le/fpu/sfp-machine.h
> @@ -107,8 +107,7 @@ void __sfp_handle_exceptions (int);
>
> #define FP_INIT_ROUNDMODE \
> do { \
> - __asm__ __volatile__ ("mffs %0" \
> - : "=f" (_fpscr.d)); \
> + _fpscr.d = __builtin_mffs (); \
> } while (0)
>
> # define FP_ROUNDMODE (_fpscr.i & FP_RND_MASK)
>
@@ -32,8 +32,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
/* Equivalent to fegetenv, but returns a fenv_t instead of taking a
pointer. */
-#define fegetenv_register() \
- ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; })
+#define fegetenv_register() __builtin_mffs()
/* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */
#define fesetenv_register(env) \
@@ -45,7 +44,7 @@ extern const fenv_t *__fe_mask_env (void) attribute_hidden;
"mtfsf 0xff,%0,1,0; " \
".machine pop" : : "f" (d)); \
else \
- asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \
+ __builtin_mtfsf (0xff, d); \
} while(0)
/* This very handy macro:
@@ -97,9 +97,7 @@ typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
/* Macros for accessing the hardware control word on Power6[x]. */
#define _GET_DI_FPSCR(__fpscr) \
({union { double d; di_fpscr_t fpscr; } u; \
- register double fr; \
- __asm__ ("mffs %0" : "=f" (fr)); \
- u.d = fr; \
+ u.d = __builtin_mffs (); \
(__fpscr) = u.fpscr; \
u.fpscr; \
})
@@ -121,9 +119,7 @@ typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
# define _GET_SI_FPSCR(__fpscr) \
({union { double d; di_fpscr_t fpscr; } u; \
- register double fr; \
- __asm__ ("mffs %0" : "=f" (fr)); \
- u.d = fr; \
+ u.d = __builtin_mffs (); \
(__fpscr) = (si_fpscr_t) u.fpscr; \
(si_fpscr_t) u.fpscr; \
})
@@ -137,7 +133,7 @@ typedef unsigned int si_fpscr_t __attribute__ ((__mode__ (__SI__)));
u.fpscr = 0xfff80000ULL << 32; \
u.fpscr |= __fpscr & 0xffffffffULL; \
fr = u.d; \
- __asm__ ("mtfsf 255,%0" : : "f" (fr)); \
+ __builtin_mtfsf (255, fr); \
fr = 0.0; \
}
@@ -96,20 +96,16 @@ typedef unsigned int fpu_control_t;
/* Macros for accessing the hardware control word. */
# 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 = __builtin_mffs (); \
(cw) = (fpu_control_t) __u.__ll; \
(fpu_control_t) __u.__ll; \
})
# define _FPU_SETCW(cw) \
{ union { double __d; unsigned long long __ll; } __u; \
- register double __fr; \
__u.__ll = 0xfff80000LL << 32; /* This is a QNaN. */ \
__u.__ll |= (cw) & 0xffffffffLL; \
- __fr = __u.__d; \
- __asm__ ("mtfsf 255,%0" : : "f" (__fr)); \
+ __builtin_mtfsf (255, __u.__d); \
}
/* Default control word set at startup. */
@@ -107,8 +107,7 @@ void __sfp_handle_exceptions (int);
#define FP_INIT_ROUNDMODE \
do { \
- __asm__ __volatile__ ("mffs %0" \
- : "=f" (_fpscr.d)); \
+ _fpscr.d = __builtin_mffs (); \
} while (0)
# define FP_ROUNDMODE (_fpscr.i & FP_RND_MASK)