Use builtins for fma/fmax/fmin/round on arm/arm64.
Bug: http://b/27829506
Test: ran tests and inspected arm/arm64/x86/x86-64 assembler
Change-Id: I8af60b44c75dddbb11949f208a8a70ed3cff12c8
diff --git a/libm/Android.bp b/libm/Android.bp
index da9c9a8..a4bdbb8 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -211,7 +211,7 @@
"fake_long_double.c",
// Home-grown stuff.
- "fabs.cpp",
+ "builtins.cpp",
"signbit.cpp",
],
@@ -291,6 +291,14 @@
"upstream-freebsd/lib/msun/src/e_sqrt.c",
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
"upstream-freebsd/lib/msun/src/s_floor.c",
+ "upstream-freebsd/lib/msun/src/s_fma.c",
+ "upstream-freebsd/lib/msun/src/s_fmaf.c",
+ "upstream-freebsd/lib/msun/src/s_fmax.c",
+ "upstream-freebsd/lib/msun/src/s_fmaxf.c",
+ "upstream-freebsd/lib/msun/src/s_fmin.c",
+ "upstream-freebsd/lib/msun/src/s_fminf.c",
+ "upstream-freebsd/lib/msun/src/s_round.c",
+ "upstream-freebsd/lib/msun/src/s_roundf.c",
],
},
instruction_set: "arm",
@@ -302,7 +310,6 @@
srcs: [
"arm64/ceil.S",
"arm64/fenv.c",
- "arm64/fma.S",
"arm64/floor.S",
"arm64/lrint.S",
"arm64/rint.S",
@@ -314,16 +321,22 @@
"upstream-freebsd/lib/msun/src/e_sqrtf.c",
"upstream-freebsd/lib/msun/src/s_ceil.c",
"upstream-freebsd/lib/msun/src/s_ceilf.c",
- "upstream-freebsd/lib/msun/src/s_fma.c",
- "upstream-freebsd/lib/msun/src/s_fmaf.c",
"upstream-freebsd/lib/msun/src/s_floor.c",
"upstream-freebsd/lib/msun/src/s_floorf.c",
+ "upstream-freebsd/lib/msun/src/s_fma.c",
+ "upstream-freebsd/lib/msun/src/s_fmaf.c",
+ "upstream-freebsd/lib/msun/src/s_fmax.c",
+ "upstream-freebsd/lib/msun/src/s_fmaxf.c",
+ "upstream-freebsd/lib/msun/src/s_fmin.c",
+ "upstream-freebsd/lib/msun/src/s_fminf.c",
"upstream-freebsd/lib/msun/src/s_llrint.c",
"upstream-freebsd/lib/msun/src/s_llrintf.c",
"upstream-freebsd/lib/msun/src/s_lrint.c",
"upstream-freebsd/lib/msun/src/s_lrintf.c",
"upstream-freebsd/lib/msun/src/s_rint.c",
"upstream-freebsd/lib/msun/src/s_rintf.c",
+ "upstream-freebsd/lib/msun/src/s_round.c",
+ "upstream-freebsd/lib/msun/src/s_roundf.c",
"upstream-freebsd/lib/msun/src/s_trunc.c",
"upstream-freebsd/lib/msun/src/s_truncf.c",
],
diff --git a/libm/arm64/fma.S b/libm/arm64/fma.S
deleted file mode 100644
index 1a8a158..0000000
--- a/libm/arm64/fma.S
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY(fma)
- fmadd d0, d0, d1, d2
- ret
-END(fma)
-
-ENTRY(fmaf)
- fmadd s0, s0, s1, s2
- ret
-END(fmaf)
diff --git a/libm/fabs.cpp b/libm/builtins.cpp
similarity index 69%
rename from libm/fabs.cpp
rename to libm/builtins.cpp
index add73fe..aec0f5f 100644
--- a/libm/fabs.cpp
+++ b/libm/builtins.cpp
@@ -44,3 +44,17 @@
return fabs(x);
}
#endif
+
+#if defined(__arm__) || defined(__aarch64__)
+float fmaf(float x, float y, float z) { return __builtin_fmaf(x, y, z); }
+double fma(double x, double y, double z) { return __builtin_fma(x, y, z); }
+
+float fmaxf(float x, float y) { return __builtin_fmaxf(x, y); }
+double fmax(double x, double y) { return __builtin_fmax(x, y); }
+
+float fminf(float x, float y) { return __builtin_fminf(x, y); }
+double fmin(double x, double y) { return __builtin_fmin(x, y); }
+
+float roundf(float x) { return __builtin_roundf(x); }
+double round(double x) { return __builtin_round(x); }
+#endif
diff --git a/libm/fake_long_double.c b/libm/fake_long_double.c
index fd983ed..360ee2b 100644
--- a/libm/fake_long_double.c
+++ b/libm/fake_long_double.c
@@ -24,6 +24,9 @@
// that call the regular "double" function.
long double copysignl(long double a1, long double a2) { return copysign(a1, a2); }
+#if defined(__arm__) // See builtins.cpp.
+long double fmal(long double a1, long double a2, long double a3) { return fma(a1, a2, a3); }
+#endif
long double fmaxl(long double a1, long double a2) { return fmax(a1, a2); }
long double fmodl(long double a1, long double a2) { return fmod(a1, a2); }
long double fminl(long double a1, long double a2) { return fmin(a1, a2); }