summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2017-06-23 16:01:00 -0400
committerRich Felker <dalias@aerifal.cx>2017-06-23 16:01:00 -0400
commit94f744195e17cf787a36c259254d56386b31fe20 (patch)
tree6702e9ebf15bd4db3049d769fd06bd51abe124d8
parent9d12a6a21fd146f543e8a6b8ec4cce7fd61be606 (diff)
downloadmusl-94f744195e17cf787a36c259254d56386b31fe20.tar.gz
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.
-rw-r--r--src/math/powerpc64/ceil.c15
-rw-r--r--src/math/powerpc64/ceilf.c15
-rw-r--r--src/math/powerpc64/fabs.c7
-rw-r--r--src/math/powerpc64/fabsf.c7
-rw-r--r--src/math/powerpc64/floor.c15
-rw-r--r--src/math/powerpc64/floorf.c15
-rw-r--r--src/math/powerpc64/fma.c7
-rw-r--r--src/math/powerpc64/fmaf.c7
-rw-r--r--src/math/powerpc64/fmax.c15
-rw-r--r--src/math/powerpc64/fmaxf.c15
-rw-r--r--src/math/powerpc64/fmin.c15
-rw-r--r--src/math/powerpc64/fminf.c15
-rw-r--r--src/math/powerpc64/lrint.c16
-rw-r--r--src/math/powerpc64/lrintf.c16
-rw-r--r--src/math/powerpc64/lround.c18
-rw-r--r--src/math/powerpc64/lroundf.c18
-rw-r--r--src/math/powerpc64/round.c15
-rw-r--r--src/math/powerpc64/roundf.c15
-rw-r--r--src/math/powerpc64/sqrt.c7
-rw-r--r--src/math/powerpc64/sqrtf.c7
-rw-r--r--src/math/powerpc64/trunc.c15
-rw-r--r--src/math/powerpc64/truncf.c15
22 files changed, 290 insertions, 0 deletions
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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+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 <math.h>
+
+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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+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 <math.h>
+
+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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+#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 <math.h>
+
+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 <math.h>
+
+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 <math.h>
+
+#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 <math.h>
+
+#ifdef _ARCH_PWR5X
+
+float truncf(float x)
+{
+ __asm__ ("friz %0, %1" : "=f"(x) : "f"(x));
+ return x;
+}
+
+#else
+
+#include "../truncf.c"
+
+#endif