svn commit: r273088 - head/lib/libc/arm/aeabi

Andrew Turner andrew at FreeBSD.org
Tue Oct 14 14:27:54 UTC 2014


Author: andrew
Date: Tue Oct 14 14:27:51 2014
New Revision: 273088
URL: https://svnweb.freebsd.org/changeset/base/273088

Log:
  Add support for the __aeabi_c*cmp* functions. These are similar to the
  existing functions with the exception they use the condition flags to
  store the result.
  
  Differential Revision:	https://reviews.freebsd.org/D872
  Silence from:	current@ and numerics@
  MFC after:	1 week

Added:
  head/lib/libc/arm/aeabi/aeabi_asm_double.S   (contents, props changed)
  head/lib/libc/arm/aeabi/aeabi_asm_float.S   (contents, props changed)
Modified:
  head/lib/libc/arm/aeabi/Makefile.inc
  head/lib/libc/arm/aeabi/Symbol.map
  head/lib/libc/arm/aeabi/aeabi_double.c
  head/lib/libc/arm/aeabi/aeabi_float.c
  head/lib/libc/arm/aeabi/aeabi_vfp_double.S
  head/lib/libc/arm/aeabi/aeabi_vfp_float.S

Modified: head/lib/libc/arm/aeabi/Makefile.inc
==============================================================================
--- head/lib/libc/arm/aeabi/Makefile.inc	Tue Oct 14 13:31:47 2014	(r273087)
+++ head/lib/libc/arm/aeabi/Makefile.inc	Tue Oct 14 14:27:51 2014	(r273088)
@@ -6,7 +6,9 @@ SRCS+=	aeabi_atexit.c		\
 	aeabi_unwind_cpp.c	\
 	aeabi_unwind_exidx.c
 .if ${MACHINE_ARCH:Marm*hf*} == ""
-SRCS+=	aeabi_double.c		\
+SRCS+=	aeabi_asm_double.S	\
+	aeabi_asm_float.S	\
+	aeabi_double.c		\
 	aeabi_float.c
 .endif
 .if ${MACHINE_ARCH:Marmv6*}

Modified: head/lib/libc/arm/aeabi/Symbol.map
==============================================================================
--- head/lib/libc/arm/aeabi/Symbol.map	Tue Oct 14 13:31:47 2014	(r273087)
+++ head/lib/libc/arm/aeabi/Symbol.map	Tue Oct 14 14:27:51 2014	(r273088)
@@ -17,6 +17,10 @@ FBSDprivate_1.0 {
 	__aeabi_dcmpgt;
 	__aeabi_dcmpun;
 
+	__aeabi_cdcmpeq;
+	__aeabi_cdcmple;
+	__aeabi_cdrcmple;
+
 	__aeabi_d2iz;
 	__aeabi_d2f;
 
@@ -33,6 +37,10 @@ FBSDprivate_1.0 {
 	__aeabi_fcmpgt;
 	__aeabi_fcmpun;
 
+	__aeabi_cfcmpeq;
+	__aeabi_cfcmple;
+	__aeabi_cfrcmple;
+
 	__aeabi_f2iz;
 	__aeabi_f2d;
 

Added: head/lib/libc/arm/aeabi/aeabi_asm_double.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/arm/aeabi/aeabi_asm_double.S	Tue Oct 14 14:27:51 2014	(r273088)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2014 Andrew Turner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+#define	PCR_Z	(1 << 30)
+#define	PCR_C	(1 << 29)
+
+/*
+ * These functions return the result in the CPSR register.
+ *
+ * For __aeabi_cdcmple:
+ *      Z C
+ *   LT 0 0
+ *   EQ 1 1
+ * else 0 1
+ *
+ * __aeabi_cdrcmple is the same as __aeabi_cdcmple, however the arguments
+ * have been swapped.
+ */
+ENTRY(__aeabi_cdcmple)
+	push	{r4, r5, r6, r7, ip, lr}
+
+	/* Backup the input registers */
+	mov	r4, r0
+	mov	r5, r1
+	mov	r6, r2
+	mov	r7, r3
+	/* Is it less than? */
+	bl	__aeabi_dcmplt
+	cmp	r0, #1
+	bne	1f
+	/* Yes, clear Z and C */
+	msr	cpsr_c, #(0)
+	b	99f
+
+1:
+	/* Restore the input regsters for the next function call */
+	mov	r0, r4
+	mov	r1, r5
+	mov	r2, r6
+	mov	r3, r7
+	/* Is it equal? */
+	bl	__aeabi_dcmpeq
+	cmp	r0, #1
+	bne	2f
+	/* Yes, set Z and C */
+	msr	cpsr_c, #(PCR_Z | PCR_C)
+	b 99f
+
+2:
+	/* Not less than or equal, set C and clear Z */
+	msr	cpsr_c, #(PCR_C)
+
+99:
+	pop	{r4, r5, r6, r7, ip, pc}
+END(__aeabi_cdcmple)
+
+ENTRY(__aeabi_cdrcmple)
+	/* Swap the first half of the arguments */
+	mov	ip, r0
+	mov	r0, r2
+	mov	r2, ip
+
+	/* And the second half */
+	mov	ip, r1
+	mov	r1, r3
+	mov	r3, ip
+
+	b	__aeabi_cdcmple
+END(__aeabi_cdrcmple)
+
+/*
+ * This is just like __aeabi_cdcmple except it will not throw an exception
+ * in the presence of a quiet NaN. If either argument is a signalling NaN we
+ * will still signal.
+ */
+ENTRY(__aeabi_cdcmpeq)
+	/* Check if we can call __aeabi_cfcmple safely */
+	push	{r0, r1, r2, r3, r4, lr}
+	bl	__aeabi_cdcmpeq_helper
+	cmp	r0, #1
+	pop	{r0, r1, r2, r3, r4, lr}
+	beq	1f
+
+	bl	__aeabi_cdcmple
+	RET
+
+1:
+	msr	cpsr_c, #(PCR_C)
+	RET
+END(__aeabi_cdcmpeq)

Added: head/lib/libc/arm/aeabi/aeabi_asm_float.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/arm/aeabi/aeabi_asm_float.S	Tue Oct 14 14:27:51 2014	(r273088)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 Andrew Turner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+#define	PCR_Z	(1 << 30)
+#define	PCR_C	(1 << 29)
+
+/*
+ * These functions return the result in the CPSR register.
+ *
+ * For __aeabi_cfcmple:
+ *      Z C
+ *   LT 0 0
+ *   EQ 1 1
+ * else 0 1
+ *
+ * __aeabi_cfrcmple is the same as __aeabi_cfcmple, however the arguments
+ * have been swapped.
+ */
+ENTRY(__aeabi_cfcmple)
+	push	{r4, r5, ip, lr}
+
+	/* Backup the input registers */
+	mov	r4, r0
+	mov	r5, r1
+	/* Is it less than? */
+	bl	__aeabi_fcmplt
+	cmp	r0, #1
+	bne	1f
+	/* Yes, clear Z and C */
+	msr	cpsr_c, #(0)
+	b	99f
+
+1:
+	/* Restore the input regsters for the next function call */
+	mov	r0, r4
+	mov	r1, r5
+	/* Is it equal? */
+	bl	__aeabi_fcmpeq
+	cmp	r0, #1
+	bne	2f
+	/* Yes, set Z and C */
+	msr	cpsr_c, #(PCR_Z | PCR_C)
+	b 99f
+
+2:
+	/* Not less than or equal, set C and clear Z */
+	msr	cpsr_c, #(PCR_C)
+
+99:
+	pop	{r4, r5, ip, pc}
+END(__aeabi_cfcmple)
+
+ENTRY(__aeabi_cfrcmple)
+	/* Swap the arguments */
+	mov	ip, r0
+	mov	r0, r1
+	mov	r1, ip
+
+	b	__aeabi_cfcmple
+END(__aeabi_cfrcmple)
+
+/*
+ * This is just like __aeabi_cfcmple except it will not throw an exception
+ * in the presence of a quiet NaN. If either argument is a signalling NaN we
+ * will still signal.
+ */
+ENTRY(__aeabi_cfcmpeq)
+	/* Check if we can call __aeabi_cfcmple safely */
+	push	{r0, r1, r2, lr}
+	bl	__aeabi_cfcmpeq_helper
+	cmp	r0, #1
+	pop	{r0, r1, r2, lr}
+	beq	1f
+
+	bl	__aeabi_cfcmple
+	RET
+
+1:
+	msreq	cpsr_c, #(PCR_C)
+	RET
+END(__aeabi_cfcmpeq)

Modified: head/lib/libc/arm/aeabi/aeabi_double.c
==============================================================================
--- head/lib/libc/arm/aeabi/aeabi_double.c	Tue Oct 14 13:31:47 2014	(r273087)
+++ head/lib/libc/arm/aeabi/aeabi_double.c	Tue Oct 14 14:27:51 2014	(r273088)
@@ -74,3 +74,28 @@ float64 AEABI_FUNC2(ddiv, float64, float
 float64 AEABI_FUNC2(dmul, float64, float64_mul)
 float64 AEABI_FUNC2(dsub, float64, float64_sub)
 
+int
+__aeabi_cdcmpeq_helper(float64 a, float64 b)
+{
+	int quiet = 0;
+
+	/* Check if a is a NaN */
+	if ((a << 1) > 0xffe0000000000000ull) {
+		/* If it's a signalling NaN we will always signal */
+		if ((a & 0x0008000000000000ull) == 0)
+			return (0);
+
+		quiet = 1;
+	}
+
+	/* Check if b is a NaN */
+	if ((b << 1) > 0xffe0000000000000ull) {
+		/* If it's a signalling NaN we will always signal */
+		if ((b & 0x0008000000000000ull) == 0)
+			return (0);
+
+		quiet = 1;
+	}
+
+	return (quiet);
+}

Modified: head/lib/libc/arm/aeabi/aeabi_float.c
==============================================================================
--- head/lib/libc/arm/aeabi/aeabi_float.c	Tue Oct 14 13:31:47 2014	(r273087)
+++ head/lib/libc/arm/aeabi/aeabi_float.c	Tue Oct 14 14:27:51 2014	(r273088)
@@ -74,3 +74,28 @@ float32 AEABI_FUNC2(fdiv, float32, float
 float32 AEABI_FUNC2(fmul, float32, float32_mul)
 float32 AEABI_FUNC2(fsub, float32, float32_sub)
 
+int
+__aeabi_cfcmpeq_helper(float32 a, float32 b)
+{
+	int quiet = 0;
+
+	/* Check if a is a NaN */
+	if ((a << 1) > 0xff000000u) {
+		/* If it's a signalling NaN we will always signal */
+		if ((a & 0x00400000u) == 0)
+			return (0);
+
+		quiet = 1;
+	}
+
+	/* Check if b is a NaN */
+	if ((b << 1) > 0xff000000u) {
+		/* If it's a signalling NaN we will always signal */
+		if ((b & 0x00400000u) == 0)
+			return (0);
+
+		quiet = 1;
+	}
+
+	return (quiet);
+}

Modified: head/lib/libc/arm/aeabi/aeabi_vfp_double.S
==============================================================================
--- head/lib/libc/arm/aeabi/aeabi_vfp_double.S	Tue Oct 14 13:31:47 2014	(r273087)
+++ head/lib/libc/arm/aeabi/aeabi_vfp_double.S	Tue Oct 14 14:27:51 2014	(r273088)
@@ -33,6 +33,33 @@ __FBSDID("$FreeBSD$");
 .fpu	vfp
 .syntax	unified
 
+/* void __aeabi_cdcmpeq(double, double) */
+AEABI_ENTRY(cdcmpeq)
+	LOAD_DREG(d0, r0, r1)
+	LOAD_DREG(d1, r2, r3)
+	vcmp.f64	d0, d1
+	vmrs		APSR_nzcv, fpscr
+	RET
+AEABI_END(cdcmpeq)
+
+/* void __aeabi_cdcmple(double, double) */
+AEABI_ENTRY(cdcmple)
+	LOAD_DREG(d0, r0, r1)
+	LOAD_DREG(d1, r2, r3)
+	vcmpe.f64	d0, d1
+	vmrs		APSR_nzcv, fpscr
+	RET
+AEABI_END(cdcmple)
+
+/* void __aeabi_cdrcmple(double, double) */
+AEABI_ENTRY(cdrcmple)
+	LOAD_DREG(d0, r0, r1)
+	LOAD_DREG(d1, r2, r3)
+	vcmpe.f64	d1, d0
+	vmrs		APSR_nzcv, fpscr
+	RET
+AEABI_END(cdrcmple)
+
 /* int __aeabi_dcmpeq(double, double) */
 AEABI_ENTRY(dcmpeq)
 	LOAD_DREG(d0, r0, r1)

Modified: head/lib/libc/arm/aeabi/aeabi_vfp_float.S
==============================================================================
--- head/lib/libc/arm/aeabi/aeabi_vfp_float.S	Tue Oct 14 13:31:47 2014	(r273087)
+++ head/lib/libc/arm/aeabi/aeabi_vfp_float.S	Tue Oct 14 14:27:51 2014	(r273088)
@@ -33,6 +33,30 @@ __FBSDID("$FreeBSD$");
 .fpu	vfp
 .syntax	unified
 
+/* void __aeabi_cfcmpeq(float, float) */
+AEABI_ENTRY(cfcmpeq)
+	LOAD_SREGS(s0, s1, r0, r1)
+	vcmp.f32	s0, s1
+	vmrs     	APSR_nzcv, fpscr
+	RET
+AEABI_END(cfcmpeq)
+
+/* void __aeabi_cfcmple(float, float) */
+AEABI_ENTRY(cfcmple)
+	LOAD_SREGS(s0, s1, r0, r1)
+	vcmpe.f32	s0, s1
+	vmrs     	APSR_nzcv, fpscr
+	RET
+AEABI_END(cfcmple)
+
+/* void __aeabi_cfrcmple(float, float) */
+AEABI_ENTRY(cfrcmple)
+	LOAD_SREGS(s0, s1, r0, r1)
+	vcmpe.f32	s1, s0
+	vmrs     	APSR_nzcv, fpscr
+	RET
+AEABI_END(cfrcmple)
+
 /* int __aeabi_fcmpeq(float, float) */
 AEABI_ENTRY(fcmpeq)
 	LOAD_SREGS(s0, s1, r0, r1)


More information about the svn-src-all mailing list