From 94f744195e17cf787a36c259254d56386b31fe20 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 23 Jun 2017 16:01:00 -0400 Subject: [PATCH] powerpc64: add single-instruction math functions while the official elfv2 abi for "powerpc64le" sets power8 as the baseline isa, we use it for both little and big endian powerpc64 targets and need to maintain compatibility with pre-power8 models. the instructions for sqrt, fabs, and fma are in the baseline isa; support for the rest is conditional via predefined isa-level macros. patch by David Edelsohn. --- src/math/powerpc64/ceil.c | 15 +++++++++++++++ src/math/powerpc64/ceilf.c | 15 +++++++++++++++ src/math/powerpc64/fabs.c | 7 +++++++ src/math/powerpc64/fabsf.c | 7 +++++++ src/math/powerpc64/floor.c | 15 +++++++++++++++ src/math/powerpc64/floorf.c | 15 +++++++++++++++ src/math/powerpc64/fma.c | 7 +++++++ src/math/powerpc64/fmaf.c | 7 +++++++ src/math/powerpc64/fmax.c | 15 +++++++++++++++ src/math/powerpc64/fmaxf.c | 15 +++++++++++++++ src/math/powerpc64/fmin.c | 15 +++++++++++++++ src/math/powerpc64/fminf.c | 15 +++++++++++++++ src/math/powerpc64/lrint.c | 16 ++++++++++++++++ src/math/powerpc64/lrintf.c | 16 ++++++++++++++++ src/math/powerpc64/lround.c | 18 ++++++++++++++++++ src/math/powerpc64/lroundf.c | 18 ++++++++++++++++++ src/math/powerpc64/round.c | 15 +++++++++++++++ src/math/powerpc64/roundf.c | 15 +++++++++++++++ src/math/powerpc64/sqrt.c | 7 +++++++ src/math/powerpc64/sqrtf.c | 7 +++++++ src/math/powerpc64/trunc.c | 15 +++++++++++++++ src/math/powerpc64/truncf.c | 15 +++++++++++++++ 22 files changed, 290 insertions(+) create mode 100644 src/math/powerpc64/ceil.c create mode 100644 src/math/powerpc64/ceilf.c create mode 100644 src/math/powerpc64/fabs.c create mode 100644 src/math/powerpc64/fabsf.c create mode 100644 src/math/powerpc64/floor.c create mode 100644 src/math/powerpc64/floorf.c create mode 100644 src/math/powerpc64/fma.c create mode 100644 src/math/powerpc64/fmaf.c create mode 100644 src/math/powerpc64/fmax.c create mode 100644 src/math/powerpc64/fmaxf.c create mode 100644 src/math/powerpc64/fmin.c create mode 100644 src/math/powerpc64/fminf.c create mode 100644 src/math/powerpc64/lrint.c create mode 100644 src/math/powerpc64/lrintf.c create mode 100644 src/math/powerpc64/lround.c create mode 100644 src/math/powerpc64/lroundf.c create mode 100644 src/math/powerpc64/round.c create mode 100644 src/math/powerpc64/roundf.c create mode 100644 src/math/powerpc64/sqrt.c create mode 100644 src/math/powerpc64/sqrtf.c create mode 100644 src/math/powerpc64/trunc.c create mode 100644 src/math/powerpc64/truncf.c diff --git a/src/math/powerpc64/ceil.c b/src/math/powerpc64/ceil.c new file mode 100644 index 00000000..4b011336 --- /dev/null +++ b/src/math/powerpc64/ceil.c @@ -0,0 +1,15 @@ +#include + +#ifdef _ARCH_PWR5X + +double ceil(double x) +{ + __asm__ ("frip %0, %1" : "=d"(x) : "d"(x)); + return x; +} + +#else + +#include "../ceil.c" + +#endif diff --git a/src/math/powerpc64/ceilf.c b/src/math/powerpc64/ceilf.c new file mode 100644 index 00000000..59ba3961 --- /dev/null +++ b/src/math/powerpc64/ceilf.c @@ -0,0 +1,15 @@ +#include + +#ifdef _ARCH_PWR5X + +float ceilf(float x) +{ + __asm__ ("frip %0, %1" : "=f"(x) : "f"(x)); + return x; +} + +#else + +#include "../ceilf.c" + +#endif diff --git a/src/math/powerpc64/fabs.c b/src/math/powerpc64/fabs.c new file mode 100644 index 00000000..6123c753 --- /dev/null +++ b/src/math/powerpc64/fabs.c @@ -0,0 +1,7 @@ +#include + +double fabs(double x) +{ + __asm__ ("fabs %0, %1" : "=d"(x) : "d"(x)); + return x; +} diff --git a/src/math/powerpc64/fabsf.c b/src/math/powerpc64/fabsf.c new file mode 100644 index 00000000..e9e45643 --- /dev/null +++ b/src/math/powerpc64/fabsf.c @@ -0,0 +1,7 @@ +#include + +float fabsf(float x) +{ + __asm__ ("fabs %0, %1" : "=f"(x) : "f"(x)); + return x; +} diff --git a/src/math/powerpc64/floor.c b/src/math/powerpc64/floor.c new file mode 100644 index 00000000..4e680444 --- /dev/null +++ b/src/math/powerpc64/floor.c @@ -0,0 +1,15 @@ +#include + +#ifdef _ARCH_PWR5X + +double floor(double x) +{ + __asm__ ("frim %0, %1" : "=d"(x) : "d"(x)); + return x; +} + +#else + +#include "../floor.c" + +#endif diff --git a/src/math/powerpc64/floorf.c b/src/math/powerpc64/floorf.c new file mode 100644 index 00000000..e1031ef4 --- /dev/null +++ b/src/math/powerpc64/floorf.c @@ -0,0 +1,15 @@ +#include + +#ifdef _ARCH_PWR5X + +float floorf(float x) +{ + __asm__ ("frim %0, %1" : "=f"(x) : "f"(x)); + return x; +} + +#else + +#include "../floorf.c" + +#endif diff --git a/src/math/powerpc64/fma.c b/src/math/powerpc64/fma.c new file mode 100644 index 00000000..5aebd1ac --- /dev/null +++ b/src/math/powerpc64/fma.c @@ -0,0 +1,7 @@ +#include + +double fma(double x, double y, double z) +{ + __asm__ ("fmadd %0, %1, %2, %3" : "=d"(x) : "d"(x), "d"(y), "d"(z)); + return x; +} diff --git a/src/math/powerpc64/fmaf.c b/src/math/powerpc64/fmaf.c new file mode 100644 index 00000000..c678fefe --- /dev/null +++ b/src/math/powerpc64/fmaf.c @@ -0,0 +1,7 @@ +#include + +float fmaf(float x, float y, float z) +{ + __asm__ ("fmadds %0, %1, %2, %3" : "=f"(x) : "f"(x), "f"(y), "f"(z)); + return x; +} diff --git a/src/math/powerpc64/fmax.c b/src/math/powerpc64/fmax.c new file mode 100644 index 00000000..992df7f1 --- /dev/null +++ b/src/math/powerpc64/fmax.c @@ -0,0 +1,15 @@ +#include + +#ifdef __VSX__ + +double fmax(double x, double y) +{ + __asm__ ("xsmaxdp %x0, %x1, %x2" : "=ws"(x) : "ws"(x), "ws"(y)); + return x; +} + +#else + +#include "../fmax.c" + +#endif diff --git a/src/math/powerpc64/fmaxf.c b/src/math/powerpc64/fmaxf.c new file mode 100644 index 00000000..345a234a --- /dev/null +++ b/src/math/powerpc64/fmaxf.c @@ -0,0 +1,15 @@ +#include + +#ifdef __VSX__ + +float fmaxf(float x, float y) +{ + __asm__ ("xsmaxdp %x0, %x1, %x2" : "=ww"(x) : "ww"(x), "ww"(y)); + return x; +} + +#else + +#include "../fmaxf.c" + +#endif diff --git a/src/math/powerpc64/fmin.c b/src/math/powerpc64/fmin.c new file mode 100644 index 00000000..adf71bad --- /dev/null +++ b/src/math/powerpc64/fmin.c @@ -0,0 +1,15 @@ +#include + +#ifdef __VSX__ + +double fmin(double x, double y) +{ + __asm__ ("xsmindp %x0, %x1, %x2" : "=ws"(x) : "ws"(x), "ws"(y)); + return x; +} + +#else + +#include "../fmin.c" + +#endif diff --git a/src/math/powerpc64/fminf.c b/src/math/powerpc64/fminf.c new file mode 100644 index 00000000..faf0e47e --- /dev/null +++ b/src/math/powerpc64/fminf.c @@ -0,0 +1,15 @@ +#include + +#ifdef __VSX__ + +float fminf(float x, float y) +{ + __asm__ ("xsmindp %x0, %x1, %x2" : "=ww"(x) : "ww"(x), "ww"(y)); + return x; +} + +#else + +#include "../fminf.c" + +#endif diff --git a/src/math/powerpc64/lrint.c b/src/math/powerpc64/lrint.c new file mode 100644 index 00000000..4e4b2e00 --- /dev/null +++ b/src/math/powerpc64/lrint.c @@ -0,0 +1,16 @@ +#include + +#ifdef _ARCH_PWR5X + +long lrint(double x) +{ + long n; + __asm__ ("fctid %0, %1" : "=d"(n) : "d"(x)); + return n; +} + +#else + +#include "../lrint.c" + +#endif diff --git a/src/math/powerpc64/lrintf.c b/src/math/powerpc64/lrintf.c new file mode 100644 index 00000000..9070fc03 --- /dev/null +++ b/src/math/powerpc64/lrintf.c @@ -0,0 +1,16 @@ +#include + +#ifdef _ARCH_PWR5X + +long lrintf(float x) +{ + long n; + __asm__ ("fctid %0, %1" : "=d"(n) : "f"(x)); + return n; +} + +#else + +#include "../lrintf.c" + +#endif diff --git a/src/math/powerpc64/lround.c b/src/math/powerpc64/lround.c new file mode 100644 index 00000000..ee4d1143 --- /dev/null +++ b/src/math/powerpc64/lround.c @@ -0,0 +1,18 @@ +#include + +#ifdef __VSX__ + +long lround(double x) +{ + long n; + __asm__ ( + "xsrdpi %1, %1\n" + "fctid %0, %1\n" : "=d"(n), "+d"(x)); + return n; +} + +#else + +#include "../lround.c" + +#endif diff --git a/src/math/powerpc64/lroundf.c b/src/math/powerpc64/lroundf.c new file mode 100644 index 00000000..033094ff --- /dev/null +++ b/src/math/powerpc64/lroundf.c @@ -0,0 +1,18 @@ +#include + +#ifdef __VSX__ + +long lroundf(float x) +{ + long n; + __asm__ ( + "xsrdpi %1, %1\n" + "fctid %0, %1\n" : "=d"(n), "+f"(x)); + return n; +} + +#else + +#include "../lroundf.c" + +#endif diff --git a/src/math/powerpc64/round.c b/src/math/powerpc64/round.c new file mode 100644 index 00000000..4b9318e0 --- /dev/null +++ b/src/math/powerpc64/round.c @@ -0,0 +1,15 @@ +#include + +#ifdef _ARCH_PWR5X + +double round(double x) +{ + __asm__ ("frin %0, %1" : "=d"(x) : "d"(x)); + return x; +} + +#else + +#include "../round.c" + +#endif diff --git a/src/math/powerpc64/roundf.c b/src/math/powerpc64/roundf.c new file mode 100644 index 00000000..ae93f999 --- /dev/null +++ b/src/math/powerpc64/roundf.c @@ -0,0 +1,15 @@ +#include + +#ifdef _ARCH_PWR5X + +float roundf(float x) +{ + __asm__ ("frin %0, %1" : "=f"(x) : "f"(x)); + return x; +} + +#else + +#include "../roundf.c" + +#endif diff --git a/src/math/powerpc64/sqrt.c b/src/math/powerpc64/sqrt.c new file mode 100644 index 00000000..13bb98d9 --- /dev/null +++ b/src/math/powerpc64/sqrt.c @@ -0,0 +1,7 @@ +#include + +double sqrt(double x) +{ + __asm__ ("fsqrt %0, %1" : "=d"(x) : "d"(x)); + return x; +} diff --git a/src/math/powerpc64/sqrtf.c b/src/math/powerpc64/sqrtf.c new file mode 100644 index 00000000..b6ecb106 --- /dev/null +++ b/src/math/powerpc64/sqrtf.c @@ -0,0 +1,7 @@ +#include + +float sqrtf(float x) +{ + __asm__ ("fsqrts %0, %1" : "=f"(x) : "f"(x)); + return x; +} diff --git a/src/math/powerpc64/trunc.c b/src/math/powerpc64/trunc.c new file mode 100644 index 00000000..57918548 --- /dev/null +++ b/src/math/powerpc64/trunc.c @@ -0,0 +1,15 @@ +#include + +#ifdef _ARCH_PWR5X + +double trunc(double x) +{ + __asm__ ("friz %0, %1" : "=d"(x) : "d"(x)); + return x; +} + +#else + +#include "../trunc.c" + +#endif diff --git a/src/math/powerpc64/truncf.c b/src/math/powerpc64/truncf.c new file mode 100644 index 00000000..94e638fb --- /dev/null +++ b/src/math/powerpc64/truncf.c @@ -0,0 +1,15 @@ +#include + +#ifdef _ARCH_PWR5X + +float truncf(float x) +{ + __asm__ ("friz %0, %1" : "=f"(x) : "f"(x)); + return x; +} + +#else + +#include "../truncf.c" + +#endif -- 2.25.1