From 25cd28e8c17473039735b01fdd5e06a7c8bf7825 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Thu, 2 Aug 2018 19:59:30 -0400 Subject: [PATCH] posix: Add initial ARM64 headers. Almost directly copied from jpelczar's work. --- headers/posix/arch/arm64/fenv.h | 248 ++++++++++++++++++++++++++++++ headers/posix/arch/arm64/signal.h | 29 ++++ 2 files changed, 277 insertions(+) create mode 100644 headers/posix/arch/arm64/fenv.h create mode 100644 headers/posix/arch/arm64/signal.h diff --git a/headers/posix/arch/arm64/fenv.h b/headers/posix/arch/arm64/fenv.h new file mode 100644 index 0000000000..1d197f0b01 --- /dev/null +++ b/headers/posix/arch/arm64/fenv.h @@ -0,0 +1,248 @@ +/*- + * Copyright (c) 2004-2005 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$ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include +#include +#include + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef uint64_t fenv_t; +typedef uint64_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x00000001 +#define FE_DIVBYZERO 0x00000002 +#define FE_OVERFLOW 0x00000004 +#define FE_UNDERFLOW 0x00000008 +#define FE_INEXACT 0x00000010 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* + * Rounding modes + * + * We can't just use the hardware bit values here, because that would + * make FE_UPWARD and FE_DOWNWARD negative, which is not allowed. + */ +#define FE_TONEAREST 0x0 +#define FE_UPWARD 0x1 +#define FE_DOWNWARD 0x2 +#define FE_TOWARDZERO 0x3 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) +#define _ROUND_SHIFT 22 + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _FPUSW_SHIFT 8 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) + +#define __mrs_fpcr(__r) __asm __volatile("mrs %0, fpcr" : "=r" (__r)) +#define __msr_fpcr(__r) __asm __volatile("msr fpcr, %0" : : "r" (__r)) + +#define __mrs_fpsr(__r) __asm __volatile("mrs %0, fpsr" : "=r" (__r)) +#define __msr_fpsr(__r) __asm __volatile("msr fpsr, %0" : : "r" (__r)) + +__fenv_static __inline int +feclearexcept(int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + __r &= ~__excepts; + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + *__flagp = __r & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + __r &= ~__excepts; + __r |= *__flagp & __excepts; + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + __r |= __excepts; + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + return (__r & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fenv_t __r; + + __mrs_fpcr(__r); + return ((__r >> _ROUND_SHIFT) & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fenv_t __r; + + if (__round & ~_ROUND_MASK) + return (-1); + __mrs_fpcr(__r); + __r &= ~(_ROUND_MASK << _ROUND_SHIFT); + __r |= __round << _ROUND_SHIFT; + __msr_fpcr(__r); + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + fenv_t __r; + + __mrs_fpcr(__r); + *__envp = __r & _ENABLE_MASK; + + __mrs_fpsr(__r); + *__envp |= __r & (FE_ALL_EXCEPT | (_ROUND_MASK << _ROUND_SHIFT)); + + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __r; + + __mrs_fpcr(__r); + *__envp = __r & _ENABLE_MASK; + __r &= ~(_ENABLE_MASK); + __msr_fpcr(__r); + + __mrs_fpsr(__r); + *__envp |= __r & (FE_ALL_EXCEPT | (_ROUND_MASK << _ROUND_SHIFT)); + __r &= ~(_ENABLE_MASK); + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __msr_fpcr((*__envp) & _ENABLE_MASK); + __msr_fpsr((*__envp) & (FE_ALL_EXCEPT | (_ROUND_MASK << _ROUND_SHIFT))); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + fesetenv(__envp); + feraiseexcept(__r & FE_ALL_EXCEPT); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +static inline int +feenableexcept(int __mask) +{ + fenv_t __old_r, __new_r; + + __mrs_fpcr(__old_r); + __new_r = __old_r | ((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); + __msr_fpcr(__new_r); + return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __old_r, __new_r; + + __mrs_fpcr(__old_r); + __new_r = __old_r & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); + __msr_fpcr(__new_r); + return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fegetexcept(void) +{ + fenv_t __r; + + __mrs_fpcr(__r); + return ((__r & _ENABLE_MASK) >> _FPUSW_SHIFT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/headers/posix/arch/arm64/signal.h b/headers/posix/arch/arm64/signal.h new file mode 100644 index 0000000000..96bfc51d59 --- /dev/null +++ b/headers/posix/arch/arm64/signal.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Jaroslaw Pelczar + * Distributed under the terms of the MIT License. + */ + +#ifndef _ARCH_SIGNAL_H_ +#define _ARCH_SIGNAL_H_ + + +/* + * Architecture-specific structure passed to signal handlers + */ + +#if defined(__arm64__) +struct vregs +{ + ulong x[30]; + ulong lr; + ulong sp; + ulong elr; + ulong spsr; + __uint128_t fp_q[32]; + u_int fpsr; + u_int fpcr; +}; +#endif /* defined(__arm64__) */ + + +#endif /* _ARCH_SIGNAL_H_ */