libm: arm: Add arm specific floor() optimization

Add arm specific floor() implementation which avoids VMSR and VMRS
instructions.

Change-Id: Ibd4cd7147aa2f98c9b5bbaf74948843ea619dba4
diff --git a/libm/Android.mk b/libm/Android.mk
index dc6c704..ebc3c9f 100644
--- a/libm/Android.mk
+++ b/libm/Android.mk
@@ -130,7 +130,6 @@
     upstream-freebsd/lib/msun/src/s_fdim.c \
     upstream-freebsd/lib/msun/src/s_finite.c \
     upstream-freebsd/lib/msun/src/s_finitef.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 \
@@ -264,20 +263,39 @@
 LOCAL_SRC_FILES_arm += \
     arm/fenv.c \
 
+# s_floor.S requires neon instructions.
+ifdef TARGET_2ND_ARCH
+arch_variant := $(TARGET_2ND_ARCH_VARIANT)
+else
+arch_variant := $(TARGET_ARCH_VARIANT)
+endif
+
+# Use the C version on armv7-a since it doesn't support neon instructions.
+ifeq ($(arch_variant),armv7-a)
+LOCAL_SRC_FILES_arm += upstream-freebsd/lib/msun/src/s_floor.c
+else
+LOCAL_SRC_FILES_arm += arm/s_floor.S
+endif
+
 LOCAL_SRC_FILES_arm64 += \
     arm64/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_SRC_FILES_mips += \
     mips/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_SRC_FILES_mips64 += \
     mips/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_SRC_FILES_x86 += \
     i387/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_SRC_FILES_x86_64 += \
     amd64/fenv.c \
+    upstream-freebsd/lib/msun/src/s_floor.c \
 
 LOCAL_C_INCLUDES_x86 += $(LOCAL_PATH)/i387
 
@@ -297,6 +315,9 @@
     -Wno-unknown-pragmas \
     -fvisibility=hidden \
 
+LOCAL_ASFLAGS := \
+    -Ibionic/libc \
+
 # Workaround the GCC "(long)fn -> lfn" optimization bug which will result in
 # self recursions for lrint, lrintf, and lrintl.
 # BUG: 14225968