add comparison functions for ARM

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@81597 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/arm/bswapdi2.S b/lib/arm/bswapdi2.S
new file mode 100644
index 0000000..7e1aeb1
--- /dev/null
+++ b/lib/arm/bswapdi2.S
@@ -0,0 +1,22 @@
+//===------- bswapdi2 - Implement bswapdi2 ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern uint64_t __bswapdi2(uint64_t);
+//
+// Reverse all the bytes in a 64-bit integer.
+//
+		.globl ___bswapdi2
+___bswapdi2:
+	rev	r2, r1		// reverse bytes in high 32-bits into temp2
+	rev	r3, r0		// reverse bytes in low 32-bit into temp3
+	mov	r0, r2		// set low 32-bits of result to temp2
+	mov	r1, r3		// set high 32-bits of result to temp3
+	bx	lr
diff --git a/lib/arm/bswapsi2.S b/lib/arm/bswapsi2.S
new file mode 100644
index 0000000..92851b1
--- /dev/null
+++ b/lib/arm/bswapsi2.S
@@ -0,0 +1,19 @@
+//===------- bswapsi2 - Implement bswapsi2 ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern uint32_t __bswapsi2(uint32_t);
+//
+// Reverse all the bits in a 32-bit integer.
+//
+		.globl ___bswapsi2
+___bswapsi2:
+	rev	r0, r0		// reverse bytes in parameter and put into result register
+	bx	lr
diff --git a/lib/arm/eqdf2vfp.S b/lib/arm/eqdf2vfp.S
new file mode 100644
index 0000000..8111a0d
--- /dev/null
+++ b/lib/arm/eqdf2vfp.S
@@ -0,0 +1,26 @@
+//===-- eqdf2vfp.S - Implement eqdf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __eqdf2vfp(double a, double b);
+//
+// Returns one iff a == b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed 
+// like in GPR pairs.
+//
+	.globl ___eqdf2vfp
+___eqdf2vfp:
+	fmdrr	d6, r0, r1	// load r0/r1 pair in double register
+	fmdrr	d7, r2, r3	// load r2/r3 pair in double register
+	fcmpd	d6, d7		
+	fmstat
+	moveq	r0, #1		// set result register to 1 if equal
+	movne	r0, #0
+	bx	lr
diff --git a/lib/arm/eqsf2vfp.S b/lib/arm/eqsf2vfp.S
new file mode 100644
index 0000000..7d995b5
--- /dev/null
+++ b/lib/arm/eqsf2vfp.S
@@ -0,0 +1,27 @@
+//===-- eqsf2vfp.S - Implement eqsf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __eqsf2vfp(float a, float b);
+//
+// Returns one iff a == b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed 
+// like 32-bit ints
+//
+	.globl ___eqsf2vfp
+___eqsf2vfp:
+	fmsr	s14, r0     // move from GPR 0 to float register
+	fmsr	s15, r1	    // move from GPR 1 to float register
+	fcmps	s14, s15
+	fmstat
+	moveq	r0, #1      // set result register to 1 if equal
+	movne	r0, #0
+	bx	lr
+
diff --git a/lib/arm/gedf2vfp.S b/lib/arm/gedf2vfp.S
new file mode 100644
index 0000000..77d07bd
--- /dev/null
+++ b/lib/arm/gedf2vfp.S
@@ -0,0 +1,26 @@
+//===-- gedf2vfp.S - Implement gedf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __gedf2vfp(double a, double b);
+//
+// Returns one iff a >= b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed 
+// like in GPR pairs.
+//
+	.globl ___gedf2vfp
+___gedf2vfp:
+	fmdrr	d6, r0, r1	// load r0/r1 pair in double register
+	fmdrr	d7, r2, r3	// load r2/r3 pair in double register
+	fcmpd	d6, d7		
+	fmstat
+	movge	r0, #1      // set result register to 1 if greater than or equal
+	movlt	r0, #0
+	bx	lr
diff --git a/lib/arm/gesf2vfp.S b/lib/arm/gesf2vfp.S
new file mode 100644
index 0000000..205c365
--- /dev/null
+++ b/lib/arm/gesf2vfp.S
@@ -0,0 +1,27 @@
+//===-- gesf2vfp.S - Implement gesf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __gesf2vfp(float a, float b);
+//
+// Returns one iff a >= b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed 
+// like 32-bit ints
+//
+	.globl ___gesf2vfp
+___gesf2vfp:
+	fmsr	s14, r0	    // move from GPR 0 to float register
+	fmsr	s15, r1	    // move from GPR 1 to float register
+	fcmps	s14, s15
+	fmstat
+	movge	r0, #1      // set result register to 1 if greater than or equal
+	movlt	r0, #0
+	bx	lr
+
diff --git a/lib/arm/gtdf2vfp.S b/lib/arm/gtdf2vfp.S
new file mode 100644
index 0000000..8d6ebcf
--- /dev/null
+++ b/lib/arm/gtdf2vfp.S
@@ -0,0 +1,26 @@
+//===-- gtdf2vfp.S - Implement gtdf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern double __gtdf2vfp(double a, double b);
+//
+// Returns one iff a > b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed 
+// like in GPR pairs.
+//
+	.globl ___gtdf2vfp
+___gtdf2vfp:
+	fmdrr	d6, r0, r1	// load r0/r1 pair in double register
+	fmdrr	d7, r2, r3	// load r2/r3 pair in double register
+	fcmpd	d6, d7		
+	fmstat
+	movgt	r0, #1		// set result register to 1 if equal
+	movle	r0, #0
+	bx	lr
diff --git a/lib/arm/gtsf2vfp.S b/lib/arm/gtsf2vfp.S
new file mode 100644
index 0000000..745a7c6
--- /dev/null
+++ b/lib/arm/gtsf2vfp.S
@@ -0,0 +1,27 @@
+//===-- gtsf2vfp.S - Implement gtsf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __gtsf2vfp(float a, float b);
+//
+// Returns one iff a > b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed 
+// like 32-bit ints
+//
+	.globl ___gtsf2vfp
+___gtsf2vfp:
+	fmsr	s14, r0		// move from GPR 0 to float register
+	fmsr	s15, r1		// move from GPR 1 to float register
+	fcmps	s14, s15
+	fmstat
+	movgt	r0, #1		// set result register to 1 if equal
+	movle	r0, #0
+	bx	lr
+
diff --git a/lib/arm/ledf2vfp.S b/lib/arm/ledf2vfp.S
new file mode 100644
index 0000000..4dc9f47
--- /dev/null
+++ b/lib/arm/ledf2vfp.S
@@ -0,0 +1,26 @@
+//===-- ledf2vfp.S - Implement ledf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern double __ledf2vfp(double a, double b);
+//
+// Returns one iff a <= b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed 
+// like in GPR pairs.
+//
+	.globl ___ledf2vfp
+___ledf2vfp:
+	fmdrr	d6, r0, r1	// load r0/r1 pair in double register
+	fmdrr	d7, r2, r3	// load r2/r3 pair in double register
+	fcmpd	d6, d7		
+	fmstat
+	movls	r0, #1		// set result register to 1 if equal
+	movhi	r0, #0
+	bx	lr
diff --git a/lib/arm/lesf2vfp.S b/lib/arm/lesf2vfp.S
new file mode 100644
index 0000000..b0a17af
--- /dev/null
+++ b/lib/arm/lesf2vfp.S
@@ -0,0 +1,27 @@
+//===-- lesf2vfp.S - Implement lesf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __lesf2vfp(float a, float b);
+//
+// Returns one iff a <= b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed 
+// like 32-bit ints
+//
+	.globl ___lesf2vfp
+___lesf2vfp:
+	fmsr	s14, r0     // move from GPR 0 to float register
+	fmsr	s15, r1     // move from GPR 1 to float register
+	fcmps	s14, s15
+	fmstat
+	movls	r0, #1      // set result register to 1 if equal
+	movhi	r0, #0
+	bx	lr
+
diff --git a/lib/arm/ltdf2vfp.S b/lib/arm/ltdf2vfp.S
new file mode 100644
index 0000000..315bb6f
--- /dev/null
+++ b/lib/arm/ltdf2vfp.S
@@ -0,0 +1,26 @@
+//===-- ltdf2vfp.S - Implement ltdf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern double __ltdf2vfp(double a, double b);
+//
+// Returns one iff a < b and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed 
+// like in GPR pairs.
+//
+	.globl ___ltdf2vfp
+___ltdf2vfp:
+	fmdrr	d6, r0, r1	// load r0/r1 pair in double register
+	fmdrr	d7, r2, r3	// load r2/r3 pair in double register
+	fcmpd	d6, d7		
+	fmstat
+	movmi	r0, #1		// set result register to 1 if equal
+	movpl	r0, #0
+	bx	lr
diff --git a/lib/arm/ltsf2vfp.S b/lib/arm/ltsf2vfp.S
new file mode 100644
index 0000000..18a1cc5
--- /dev/null
+++ b/lib/arm/ltsf2vfp.S
@@ -0,0 +1,27 @@
+//===-- ltsf2vfp.S - Implement ltsf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __ltsf2vfp(float a, float b);
+//
+// Returns one iff a < b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed 
+// like 32-bit ints
+//
+	.globl ___ltsf2vfp
+___ltsf2vfp:
+	fmsr	s14, r0     // move from GPR 0 to float register
+	fmsr	s15, r1     // move from GPR 1 to float register
+	fcmps	s14, s15
+	fmstat
+	movmi	r0, #1      // set result register to 1 if equal
+	movpl	r0, #0
+	bx	lr
+
diff --git a/lib/arm/nedf2vfp.S b/lib/arm/nedf2vfp.S
new file mode 100644
index 0000000..8cf4dc2
--- /dev/null
+++ b/lib/arm/nedf2vfp.S
@@ -0,0 +1,26 @@
+//===-- nedf2vfp.S - Implement nedf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern double __nedf2vfp(double a, double b);
+//
+// Returns zero if a and b are unequal and neither is NaN.
+// Uses Darwin calling convention where double precision arguments are passsed 
+// like in GPR pairs.
+//
+	.globl ___nedf2vfp
+___nedf2vfp:
+	fmdrr	d6, r0, r1	// load r0/r1 pair in double register
+	fmdrr	d7, r2, r3	// load r2/r3 pair in double register
+	fcmpd	d6, d7		
+	fmstat
+	movne	r0, #1		// set result register to 0 if unequal
+	moveq	r0, #0
+	bx	lr
diff --git a/lib/arm/negdf2vfp.S b/lib/arm/negdf2vfp.S
new file mode 100644
index 0000000..b047ccc
--- /dev/null
+++ b/lib/arm/negdf2vfp.S
@@ -0,0 +1,20 @@
+//===-- negdf2vfp.S - Implement negdf2vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern double __negdf2vfp(double a, double b);
+//
+// Returns the negation a double precision floating point numbers using the 
+// Darwin calling convention where double arguments are passsed in GPR pairs.
+//
+	.globl ___negdf2vfp
+___negdf2vfp:
+	eor	r1, r1, #-2147483648	// flip sign bit on double in r0/r1 pair
+	bx	lr
diff --git a/lib/arm/negsf2vfp.S b/lib/arm/negsf2vfp.S
new file mode 100644
index 0000000..1b0f3d6
--- /dev/null
+++ b/lib/arm/negsf2vfp.S
@@ -0,0 +1,20 @@
+//===-- negsf2vfp.S - Implement negsf2vfp ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern float __negsf2vfp(float a);
+//
+// Returns the negation of a single precision floating point numbers using the 
+// Darwin calling convention where single arguments are passsed like 32-bit ints
+//
+	.globl ___negsf2vfp
+___negsf2vfp:
+	eor	r0, r0, #-2147483648	// flip sign bit on float in r0
+	bx	lr
diff --git a/lib/arm/nesf2vfp.S b/lib/arm/nesf2vfp.S
new file mode 100644
index 0000000..da0eef6
--- /dev/null
+++ b/lib/arm/nesf2vfp.S
@@ -0,0 +1,27 @@
+//===-- nesf2vfp.S - Implement nesf2vfp -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __nesf2vfp(float a, float b);
+//
+// Returns one iff a != b and neither is NaN.
+// Uses Darwin calling convention where single precision arguments are passsed 
+// like 32-bit ints
+//
+	.globl ___nesf2vfp
+___nesf2vfp:
+	fmsr	s14, r0	    // move from GPR 0 to float register
+	fmsr	s15, r1	    // move from GPR 1 to float register
+	fcmps	s14, s15
+	fmstat
+	movne	r0, #1      // set result register to 1 if unequal
+	moveq	r0, #0
+	bx	lr
+
diff --git a/lib/arm/unorddf2vfp.S b/lib/arm/unorddf2vfp.S
new file mode 100644
index 0000000..e458eb8
--- /dev/null
+++ b/lib/arm/unorddf2vfp.S
@@ -0,0 +1,26 @@
+//===-- unorddf2vfp.S - Implement unorddf2vfp ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __unorddf2vfp(double a, double b);
+//
+// Returns one iff a or b is NaN
+// Uses Darwin calling convention where double precision arguments are passsed 
+// like in GPR pairs.
+//
+	.globl ___unorddf2vfp
+___unorddf2vfp:
+	fmdrr	d6, r0, r1	// load r0/r1 pair in double register
+	fmdrr	d7, r2, r3	// load r2/r3 pair in double register
+	fcmpd	d6, d7		
+	fmstat
+	movvs	r0, #1      // set result register to 1 if "overflow" (any NaNs)
+	movvc	r0, #0
+	bx	lr
diff --git a/lib/arm/unordsf2vfp.S b/lib/arm/unordsf2vfp.S
new file mode 100644
index 0000000..6b69080
--- /dev/null
+++ b/lib/arm/unordsf2vfp.S
@@ -0,0 +1,27 @@
+//===-- unordsf2vfp.S - Implement unordsf2vfp -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+//
+// extern int __unordsf2vfp(float a, float b);
+//
+// Returns one iff a or b is NaN
+// Uses Darwin calling convention where single precision arguments are passsed 
+// like 32-bit ints
+//
+	.globl ___unordsf2vfp
+___unordsf2vfp:
+	fmsr	s14, r0     // move from GPR 0 to float register
+	fmsr	s15, r1	    // move from GPR 1 to float register
+	fcmps	s14, s15
+	fmstat
+	movvs	r0, #1      // set result register to 1 if "overflow" (any NaNs)
+	movvc	r0, #0
+	bx	lr
+