From: Rich Felker Date: Fri, 23 Jun 2017 20:01:00 +0000 (-0400) Subject: powerpc64: add single-instruction math functions X-Git-Tag: v1.1.17~47 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=94f744195e17cf787a36c259254d56386b31fe20;p=oweals%2Fmusl.git 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. --- 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