From 644726ff5095a364a9eb32ea9c340acf9bdbc3e2 Mon Sep 17 00:00:00 2001 From: Sandy Urazayev Date: Sat, 2 Oct 2021 23:19:36 -0500 Subject: [PATCH] AP_Common: Added missing fenv exception functions from FreeBSD fenv tree Signed-off-by: Sandy Urazayev --- libraries/AP_Common/missing/fenv.h | 65 ++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/libraries/AP_Common/missing/fenv.h b/libraries/AP_Common/missing/fenv.h index cbcbef2f64..6c9b2ef27b 100644 --- a/libraries/AP_Common/missing/fenv.h +++ b/libraries/AP_Common/missing/fenv.h @@ -4,6 +4,7 @@ #ifndef HAVE_FEENABLEEXCEPT #if defined(__APPLE__) && defined(__MACH__) +#if defined __i386__ || defined __x86_64__ // Public domain polyfill for feenableexcept on OS X // http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c @@ -46,6 +47,70 @@ inline int fedisableexcept(unsigned int excepts) return fesetenv(&fenv) ? -1 : old_excepts; } +#elif defined __arm64__ + +/* + Yoinked and adapted this ARM64 implementation of floating point exceptions from + https://android.googlesource.com/platform/bionic/+/a147a1d/libm/arm64/fenv.c + */ + +/*- + * Copyright (c) 2004 David Schultz + * 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. + * + * $FreeBSD: libm/aarch64/fenv.c $ + */ + + +#define FPCR_EXCEPT_SHIFT 8 + +// FPCR, Floating-point Control Register. +#define __get_fpcr(__fpcr) __asm__ __volatile__("mrs %0,fpcr" : "=r" (__fpcr)) +#define __set_fpcr(__fpcr) __asm__ __volatile__("msr fpcr,%0" : :"ri" (__fpcr)) + +inline int feenableexcept(int mask) { + unsigned long long old_fpcr, new_fpcr; + __get_fpcr(old_fpcr); + new_fpcr = old_fpcr | ((mask & FE_ALL_EXCEPT) << FPCR_EXCEPT_SHIFT); + if (new_fpcr != old_fpcr) { + __set_fpcr(new_fpcr); + } + return ((old_fpcr >> FPCR_EXCEPT_SHIFT) & FE_ALL_EXCEPT); +} + +inline int fedisableexcept(int mask) { + unsigned long long old_fpcr, new_fpcr; + __get_fpcr(old_fpcr); + new_fpcr = old_fpcr & ~((mask & FE_ALL_EXCEPT) << FPCR_EXCEPT_SHIFT); + if (new_fpcr != old_fpcr) { + __set_fpcr(new_fpcr); + } + return ((old_fpcr >> FPCR_EXCEPT_SHIFT) & FE_ALL_EXCEPT); +} + +#endif + #else inline int feenableexcept(unsigned int excepts) {