x86_64: add single instruction fma
authorSzabolcs Nagy <nsz@port70.net>
Sat, 22 Sep 2018 21:43:42 +0000 (21:43 +0000)
committerRich Felker <dalias@aerifal.cx>
Mon, 15 Oct 2018 18:45:28 +0000 (14:45 -0400)
fma is only available on recent x86_64 cpus and it is much faster than
a software fma, so this should be done with a runtime check, however
that requires more changes, this patch just adds the code so it can be
tested when musl is compiled with -mfma or -mfma4.

src/math/x32/fma.c [new file with mode: 0644]
src/math/x32/fmaf.c [new file with mode: 0644]
src/math/x86_64/fma.c [new file with mode: 0644]
src/math/x86_64/fmaf.c [new file with mode: 0644]

diff --git a/src/math/x32/fma.c b/src/math/x32/fma.c
new file mode 100644 (file)
index 0000000..4dd53f2
--- /dev/null
@@ -0,0 +1,23 @@
+#include <math.h>
+
+#if __FMA__
+
+double fma(double x, double y, double z)
+{
+       __asm__ ("vfmadd132sd %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
+       return x;
+}
+
+#elif __FMA4__
+
+double fma(double x, double y, double z)
+{
+       __asm__ ("vfmaddsd %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
+       return x;
+}
+
+#else
+
+#include "../fma.c"
+
+#endif
diff --git a/src/math/x32/fmaf.c b/src/math/x32/fmaf.c
new file mode 100644 (file)
index 0000000..30b971f
--- /dev/null
@@ -0,0 +1,23 @@
+#include <math.h>
+
+#if __FMA__
+
+float fmaf(float x, float y, float z)
+{
+       __asm__ ("vfmadd132ss %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
+       return x;
+}
+
+#elif __FMA4__
+
+float fmaf(float x, float y, float z)
+{
+       __asm__ ("vfmaddss %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
+       return x;
+}
+
+#else
+
+#include "../fmaf.c"
+
+#endif
diff --git a/src/math/x86_64/fma.c b/src/math/x86_64/fma.c
new file mode 100644 (file)
index 0000000..4dd53f2
--- /dev/null
@@ -0,0 +1,23 @@
+#include <math.h>
+
+#if __FMA__
+
+double fma(double x, double y, double z)
+{
+       __asm__ ("vfmadd132sd %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
+       return x;
+}
+
+#elif __FMA4__
+
+double fma(double x, double y, double z)
+{
+       __asm__ ("vfmaddsd %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
+       return x;
+}
+
+#else
+
+#include "../fma.c"
+
+#endif
diff --git a/src/math/x86_64/fmaf.c b/src/math/x86_64/fmaf.c
new file mode 100644 (file)
index 0000000..30b971f
--- /dev/null
@@ -0,0 +1,23 @@
+#include <math.h>
+
+#if __FMA__
+
+float fmaf(float x, float y, float z)
+{
+       __asm__ ("vfmadd132ss %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
+       return x;
+}
+
+#elif __FMA4__
+
+float fmaf(float x, float y, float z)
+{
+       __asm__ ("vfmaddss %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
+       return x;
+}
+
+#else
+
+#include "../fmaf.c"
+
+#endif