start adding implementation of arm *vfp routines with test cases

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@81558 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/arm/adddf3vfp.S b/lib/arm/adddf3vfp.S
new file mode 100644
index 0000000..f4bb1ce
--- /dev/null
+++ b/lib/arm/adddf3vfp.S
@@ -0,0 +1,23 @@
+//===-- adddf3vfp.S - Implement adddf3vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// double __adddf3vfp(double a, double b) { return a + b; }
+//
+// Adds two double precision floating point numbers using the Darwin
+// calling convention where double arguments are passsed in GPR pairs
+//
+		.globl ___adddf3vfp
+___adddf3vfp:
+	fmdrr	d6, r0, r1		// move first param from r0/r1 pair into d6
+	fmdrr	d7, r2, r3		// move second param from r2/r3 pair into d7
+	faddd	d6, d6, d7		
+	fmrrd	r0, r1, d6		// move result back to r0/r1 pair
+	bx	lr
diff --git a/lib/arm/addsf3vfp.S b/lib/arm/addsf3vfp.S
new file mode 100644
index 0000000..81b114f
--- /dev/null
+++ b/lib/arm/addsf3vfp.S
@@ -0,0 +1,23 @@
+//===-- addsf3vfp.S - Implement addsf3vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern float __addsf3vfp(float a, float b);
+//
+// Adds two single precision floating point numbers using the Darwin
+// calling convention where single arguments are passsed in GPRs
+//
+		.globl ___addsf3vfp
+___addsf3vfp:
+	fmsr	s14, r0		// move first param from r0 into float register
+	fmsr	s15, r1		// move second param from r1 into float register
+	fadds	s14, s14, s15
+	fmrs	r0, s14		// move result back to r0
+	bx	lr
diff --git a/lib/arm/divdf3vfp.S b/lib/arm/divdf3vfp.S
new file mode 100644
index 0000000..59421ef
--- /dev/null
+++ b/lib/arm/divdf3vfp.S
@@ -0,0 +1,23 @@
+//===-- divdf3vfp.S - Implement divdf3vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern double __divdf3vfp(double a, double b);
+//
+// Divides two double precision floating point numbers using the Darwin
+// calling convention where double arguments are passsed in GPR pairs
+//
+	.globl ___divdf3vfp
+___divdf3vfp:
+	fmdrr	d6, r0, r1		// move first param from r0/r1 pair into d6
+	fmdrr	d7, r2, r3		// move second param from r2/r3 pair into d7
+	fdivd	d5, d6, d7		
+	fmrrd	r0, r1, d5		// move result back to r0/r1 pair
+	bx	lr
diff --git a/lib/arm/divsf3vfp.S b/lib/arm/divsf3vfp.S
new file mode 100644
index 0000000..62c79ea
--- /dev/null
+++ b/lib/arm/divsf3vfp.S
@@ -0,0 +1,23 @@
+//===-- divsf3vfp.S - Implement divsf3vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern float __divsf3vfp(float a, float b);
+//
+// Divides two single precision floating point numbers using the Darwin
+// calling convention where single arguments are passsed like 32-bit ints.
+//
+	.globl ___divsf3vfp
+___divsf3vfp:
+	fmsr	s14, r0		// move first param from r0 into float register
+	fmsr	s15, r1		// move second param from r1 into float register
+	fdivs	s13, s14, s15
+	fmrs	r0, s13		// move result back to r0
+	bx	lr
diff --git a/lib/arm/muldf3vfp.S b/lib/arm/muldf3vfp.S
new file mode 100644
index 0000000..5292b8e
--- /dev/null
+++ b/lib/arm/muldf3vfp.S
@@ -0,0 +1,23 @@
+//===-- muldf3vfp.S - Implement muldf3vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern double __muldf3vfp(double a, double b);
+//
+// Multiplies two double precision floating point numbers using the Darwin
+// calling convention where double arguments are passsed in GPR pairs
+//
+	.globl ___muldf3vfp
+___muldf3vfp:
+	fmdrr	d6, r0, r1		// move first param from r0/r1 pair into d6
+	fmdrr	d7, r2, r3		// move second param from r2/r3 pair into d7
+	fmuld	d6, d6, d7		
+	fmrrd	r0, r1, d6		// move result back to r0/r1 pair
+	bx	lr
diff --git a/lib/arm/mulsf3vfp.S b/lib/arm/mulsf3vfp.S
new file mode 100644
index 0000000..e6cdca3
--- /dev/null
+++ b/lib/arm/mulsf3vfp.S
@@ -0,0 +1,23 @@
+//===-- mulsf3vfp.S - Implement mulsf3vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern float __mulsf3vfp(float a, float b);
+//
+// Multiplies two single precision floating point numbers using the Darwin
+// calling convention where single arguments are passsed like 32-bit ints.
+//
+	.globl ___mulsf3vfp
+___mulsf3vfp:
+	fmsr	s14, r0		// move first param from r0 into float register
+	fmsr	s15, r1		// move second param from r1 into float register
+	fmuls	s13, s14, s15
+	fmrs	r0, s13		// move result back to r0
+	bx	lr
diff --git a/lib/arm/subdf3vfp.S b/lib/arm/subdf3vfp.S
new file mode 100644
index 0000000..c138c3a
--- /dev/null
+++ b/lib/arm/subdf3vfp.S
@@ -0,0 +1,23 @@
+//===-- subdf3vfp.S - Implement subdf3vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern double __subdf3vfp(double a, double b);
+//
+// Returns difference between two double precision floating point numbers using 
+// the Darwin calling convention where double arguments are passsed in GPR pairs
+//
+		.globl ___subdf3vfp
+___subdf3vfp:
+	fmdrr	d6, r0, r1		// move first param from r0/r1 pair into d6
+	fmdrr	d7, r2, r3		// move second param from r2/r3 pair into d7
+	fsubd	d6, d6, d7		
+	fmrrd	r0, r1, d6		// move result back to r0/r1 pair
+	bx	lr
diff --git a/lib/arm/subsf3vfp.S b/lib/arm/subsf3vfp.S
new file mode 100644
index 0000000..493a850
--- /dev/null
+++ b/lib/arm/subsf3vfp.S
@@ -0,0 +1,24 @@
+//===-- subsf3vfp.S - Implement subsf3vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern float __subsf3vfp(float a, float b);
+//
+// Returns the difference between two single precision floating point numbers 
+// using the Darwin calling convention where single arguments are passsed
+// like 32-bit ints.
+//
+		.globl ___subsf3vfp
+___subsf3vfp:
+	fmsr	s14, r0		// move first param from r0 into float register
+	fmsr	s15, r1		// move second param from r1 into float register
+	fsubs	s14, s14, s15
+	fmrs	r0, s14		// move result back to r0
+	bx	lr
diff --git a/test/Unit/adddf3vfp.c b/test/Unit/adddf3vfp.c
new file mode 100644
index 0000000..c5bec05
--- /dev/null
+++ b/test/Unit/adddf3vfp.c
@@ -0,0 +1,46 @@
+//===-- adddf3vfp_test.c - Test __adddf3vfp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __adddf3vfp for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+#if __arm__
+extern double __adddf3vfp(double a, double b);
+
+int test__adddf3vfp(double a, double b)
+{
+    double actual = __adddf3vfp(a, b);
+    double expected = a + b;
+    if (actual != expected)
+        printf("error in test__adddf3vfp(%f, %f) = %f, expected %f\n",
+               a, b, actual, expected);
+    return actual != expected;
+}
+#endif
+
+int main()
+{
+#if __arm__
+    if (test__adddf3vfp(1.0, 1.0))
+        return 1;
+    if (test__adddf3vfp(HUGE_VAL, HUGE_VAL))
+        return 1;
+    if (test__adddf3vfp(0.0, HUGE_VAL))
+        return 1;
+    if (test__adddf3vfp(0.0, -0.0))
+        return 1;
+#endif
+    return 0;
+}
diff --git a/test/Unit/addsf3vfp.c b/test/Unit/addsf3vfp.c
new file mode 100644
index 0000000..0a731a9
--- /dev/null
+++ b/test/Unit/addsf3vfp.c
@@ -0,0 +1,46 @@
+//===-- addsf3vfp_test.c - Test __addsf3vfp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __addsf3vfp for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+extern float __addsf3vfp(float a, float b);
+
+#if __arm__
+int test__addsf3vfp(float a, float b)
+{
+    float actual = __addsf3vfp(a, b);
+    float expected = a + b;
+    if (actual != expected)
+        printf("error in test__addsf3vfp(%f, %f) = %f, expected %f\n",
+               a, b, actual, expected);
+    return actual != expected;
+}
+#endif
+
+int main()
+{
+#if __arm__
+    if (test__addsf3vfp(1.0, 1.0))
+        return 1;
+    if (test__addsf3vfp(HUGE_VALF, HUGE_VALF))
+        return 1;
+    if (test__addsf3vfp(0.0, HUGE_VALF))
+        return 1;
+    if (test__addsf3vfp(0.0, -0.0))
+        return 1;
+#endif
+    return 0;
+}
diff --git a/test/Unit/divdf3vfp.c b/test/Unit/divdf3vfp.c
new file mode 100644
index 0000000..2ca382a
--- /dev/null
+++ b/test/Unit/divdf3vfp.c
@@ -0,0 +1,46 @@
+//===-- divdf3vfp_test.c - Test __divdf3vfp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divdf3vfp for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+#if __arm__
+extern double __divdf3vfp(double a, double b);
+
+int test__divdf3vfp(double a, double b)
+{
+    double actual = __divdf3vfp(a, b);
+    double expected = a / b;
+    if (actual != expected)
+        printf("error in test__divdf3vfp(%f, %f) = %f, expected %f\n",
+               a, b, actual, expected);
+    return actual != expected;
+}
+#endif
+
+int main()
+{
+#if __arm__
+    if (test__divdf3vfp(1.0, 1.0))
+        return 1;
+    if (test__divdf3vfp(12345.678, 1.23))
+        return 1;
+    if (test__divdf3vfp(-10.0, 0.25))
+        return 1;
+    if (test__divdf3vfp(10.0, -2.0))
+        return 1;
+#endif
+    return 0;
+}
diff --git a/test/Unit/divsf3vfp.c b/test/Unit/divsf3vfp.c
new file mode 100644
index 0000000..0dbae2f
--- /dev/null
+++ b/test/Unit/divsf3vfp.c
@@ -0,0 +1,46 @@
+//===-- divsf3vfp_test.c - Test __divsf3vfp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __divsf3vfp for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+extern float __divsf3vfp(float a, float b);
+
+#if __arm__
+int test__divsf3vfp(float a, float b)
+{
+    float actual = __divsf3vfp(a, b);
+    float expected = a / b;
+    if (actual != expected)
+        printf("error in test__divsf3vfp(%f, %f) = %f, expected %f\n",
+               a, b, actual, expected);
+    return actual != expected;
+}
+#endif
+
+int main()
+{
+#if __arm__
+    if (test__divsf3vfp(1.0, 1.0))
+        return 1;
+    if (test__divsf3vfp(12345.678, 1.23))
+        return 1;
+    if (test__divsf3vfp(0.0, HUGE_VALF))
+        return 1;
+    if (test__divsf3vfp(10.0, -2.0))
+        return 1;
+#endif
+    return 0;
+}
diff --git a/test/Unit/muldf3vfp.c b/test/Unit/muldf3vfp.c
new file mode 100644
index 0000000..a99d8e9
--- /dev/null
+++ b/test/Unit/muldf3vfp.c
@@ -0,0 +1,48 @@
+//===-- muldf3vfp_test.c - Test __muldf3vfp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __muldf3vfp for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+#if __arm__
+extern double __muldf3vfp(double a, double b);
+
+int test__muldf3vfp(double a, double b)
+{
+    double actual = __muldf3vfp(a, b);
+    double expected = a * b;
+    if (actual != expected)
+        printf("error in test__muldf3vfp(%f, %f) = %f, expected %f\n",
+               a, b, actual, expected);
+    return actual != expected;
+}
+#endif
+
+int main()
+{
+#if __arm__
+    if (test__muldf3vfp(0.5, 10.0))
+        return 1;
+    if (test__muldf3vfp(-0.5, -2.0))
+        return 1;
+    if (test__muldf3vfp(HUGE_VALF, 0.25))
+        return 1;
+    if (test__muldf3vfp(-0.125, HUGE_VALF))
+        return 1;
+    if (test__muldf3vfp(0.0, -0.0))
+		return 1;
+#endif
+    return 0;
+}
diff --git a/test/Unit/mulsf3vfp.c b/test/Unit/mulsf3vfp.c
new file mode 100644
index 0000000..f706c47
--- /dev/null
+++ b/test/Unit/mulsf3vfp.c
@@ -0,0 +1,48 @@
+//===-- mulsf3vfp_test.c - Test __mulsf3vfp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __mulsf3vfp for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+extern float __mulsf3vfp(float a, float b);
+
+#if __arm__
+int test__mulsf3vfp(float a, float b)
+{
+    float actual = __mulsf3vfp(a, b);
+    float expected = a * b;
+    if (actual != expected)
+        printf("error in test__mulsf3vfp(%f, %f) = %f, expected %f\n",
+               a, b, actual, expected);
+    return actual != expected;
+}
+#endif
+
+int main()
+{
+#if __arm__
+    if (test__mulsf3vfp(0.5, 10.0))
+        return 1;
+    if (test__mulsf3vfp(-0.5, -2.0))
+        return 1;
+    if (test__mulsf3vfp(HUGE_VALF, 0.25))
+        return 1;
+    if (test__mulsf3vfp(-0.125, HUGE_VALF))
+        return 1;
+    if (test__mulsf3vfp(0.0, -0.0))
+        return 1;
+#endif
+    return 0;
+}
diff --git a/test/Unit/subdf3vfp.c b/test/Unit/subdf3vfp.c
new file mode 100644
index 0000000..ee5a492
--- /dev/null
+++ b/test/Unit/subdf3vfp.c
@@ -0,0 +1,46 @@
+//===-- subdf3vfp_test.c - Test __subdf3vfp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __subdf3vfp for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+#if __arm__
+extern double __subdf3vfp(double a, double b);
+
+int test__subdf3vfp(double a, double b)
+{
+    double actual = __subdf3vfp(a, b);
+    double expected = a - b;
+    if (actual != expected)
+        printf("error in test__subdf3vfp(%f, %f) = %f, expected %f\n",
+               a, b, actual, expected);
+    return actual != expected;
+}
+#endif
+
+int main()
+{
+#if __arm__
+    if (test__subdf3vfp(1.0, 1.0))
+        return 1;
+    if (test__subdf3vfp(1234.567, 765.4321))
+        return 1;
+    if (test__subdf3vfp(-123.0, -678.0))
+        return 1;
+    if (test__subdf3vfp(0.0, -0.0))
+        return 1;
+#endif
+    return 0;
+}
diff --git a/test/Unit/subsf3vfp.c b/test/Unit/subsf3vfp.c
new file mode 100644
index 0000000..f6853e3
--- /dev/null
+++ b/test/Unit/subsf3vfp.c
@@ -0,0 +1,46 @@
+//===-- subsf3vfp_test.c - Test __subsf3vfp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests __subsf3vfp for the compiler_rt library.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+extern float __subsf3vfp(float a, float b);
+
+#if __arm__
+int test__subsf3vfp(float a, float b)
+{
+    float actual = __subsf3vfp(a, b);
+    float expected = a - b;
+    if (actual != expected)
+        printf("error in test__subsf3vfp(%f, %f) = %f, expected %f\n",
+               a, b, actual, expected);
+    return actual != expected;
+}
+#endif
+
+int main()
+{
+#if __arm__
+    if (test__subsf3vfp(1.0, 1.0))
+        return 1;
+    if (test__subsf3vfp(1234.567, 765.4321))
+        return 1;
+    if (test__subsf3vfp(-123.0, -678.0))
+        return 1;
+    if (test__subsf3vfp(0.0, -0.0))
+        return 1;
+#endif
+    return 0;
+}
diff --git a/test/Unit/test b/test/Unit/test
index e5f540e..0ec771c 100755
--- a/test/Unit/test
+++ b/test/Unit/test
@@ -1,9 +1,17 @@
 #!/usr/bin/env bash
 
 ARCHS='<host>'
+REMOTE=0
 if test `uname` = "Darwin"; then
-  ARCHS="i386 x86_64 ppc"
-  LIBS="-lSystem"
+  if test "$1" = "armv6"; then
+    ARCHS="armv6"
+	LIBS="-lSystem"
+	REMOTE=1
+	mkdir -p remote
+  else
+    ARCHS="i386 x86_64 ppc"
+    LIBS="-lSystem"
+  fi
 else
   LIBS="-lc -lm"
 fi
@@ -30,20 +38,30 @@
       # this test requires an extra compiler option
       EXTRA="-fnested-functions"
     fi
-    if gcc $CFLAGS $FILE ../../Release/libcompiler_rt.Optimized.a $LIBS $EXTRA
-    then
-      echo "Testing $FILE for $ARCH"
-      if ./a.out
+	if test $REMOTE
+	then 
+      if gcc $CFLAGS $FILE ../../Release/libcompiler_rt.Optimized.a $LIBS $EXTRA -o ./remote/$FILE.exe
       then
-        rm ./a.out
+        echo "Built $FILE.exe for $ARCH"
+	  else
+        echo "$FILE failed to compile"
+	  fi
+	else
+      if gcc $CFLAGS $FILE ../../Release/libcompiler_rt.Optimized.a $LIBS $EXTRA
+      then
+        echo "Testing $FILE for $ARCH"
+        if ./a.out
+        then
+          rm ./a.out
+        else
+          echo "fail"
+          exit 1
+        fi
       else
-        echo "fail"
+        echo "$FILE failed to compile"
         exit 1
       fi
-    else
-      echo "$FILE failed to compile"
-      exit 1
-    fi
+	fi
   done
 done
 echo "pass"