Date: Tue, 14 Oct 2014 14:27:52 +0000 (UTC) From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r273088 - head/lib/libc/arm/aeabi Message-ID: <201410141427.s9EERqQ5062216@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201410141427.s9EERqQ5062216>