Module Name: src
Committed By: christos
Date: Thu Dec 24 14:12:39 UTC 2015
Modified Files:
src/sys/arch/m68k/include: Makefile
Added Files:
src/sys/arch/m68k/include: fenv.h
Log Message:
fenv for m68k
To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/arch/m68k/include/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/arch/m68k/include/fenv.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/m68k/include/Makefile
diff -u src/sys/arch/m68k/include/Makefile:1.28 src/sys/arch/m68k/include/Makefile:1.29
--- src/sys/arch/m68k/include/Makefile:1.28 Wed Jul 17 01:42:02 2013
+++ src/sys/arch/m68k/include/Makefile Thu Dec 24 09:12:39 2015
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.28 2013/07/17 05:42:02 matt Exp $
+# $NetBSD: Makefile,v 1.29 2015/12/24 14:12:39 christos Exp $
INCSDIR= /usr/include/m68k
@@ -7,7 +7,7 @@ INCS= ansi.h aout_machdep.h asm.h asm_si
cacheops.h cacheops_20.h cacheops_30.h cacheops_40.h cacheops_60.h \
cdefs.h cpu.h cpuframe.h \
elf_machdep.h endian.h endian_machdep.h \
- float.h fpreg.h frame.h \
+ fenv.h float.h fpreg.h frame.h \
ieee.h ieeefp.h \
int_const.h int_fmtio.h int_limits.h int_mwgwtypes.h int_types.h \
kcore.h \
Added files:
Index: src/sys/arch/m68k/include/fenv.h
diff -u /dev/null src/sys/arch/m68k/include/fenv.h:1.1
--- /dev/null Thu Dec 24 09:12:39 2015
+++ src/sys/arch/m68k/include/fenv.h Thu Dec 24 09:12:39 2015
@@ -0,0 +1,302 @@
+/* $NetBSD: fenv.h,v 1.1 2015/12/24 14:12:39 christos Exp $ */
+
+/*-
+ * Copyright (c) 2015 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#ifndef _M68K_FENV_H_
+#define _M68K_FENV_H_
+
+#include <sys/stdint.h>
+#include <m68k/float.h>
+#include <m68k/fpreg.h>
+
+#ifndef __fenv_static
+#define __fenv_static static
+#endif
+
+/* Exception bits, from FPSR */
+#define FE_INEXACT FPSR_AINEX
+#define FE_DIVBYZERO FPSR_ADZ
+#define FE_UNDERFLOW FPSR_AUNFL
+#define FE_OVERFLOW FPSR_AOVFL
+#define FE_INVALID FPSR_AIOP
+
+#define FE_ALL_EXCEPT \
+ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
+
+/* Rounding modes, from FPSR */
+#define FE_TONEAREST FPCR_NEAR
+#define FE_TOWARDZERO FPCR_ZERO
+#define FE_DOWNWARD FPCR_MINF
+#define FE_UPWARD FPCR_PINF
+
+#define _ROUND_MASK \
+ (FE_TONEAREST | FE_TOWARDZERO | FE_DOWNWARD | FE_UPWARD)
+
+typedef uint32_t fexcept_t;
+
+/* same layout as fmovem */
+typedef struct {
+ uint32_t fpcr;
+ uint32_t fpsr;
+ uint32_t fppc;
+} fenv_t;
+
+#define FE_DFL_ENV ((fenv_t *) -1)
+
+#define __get_fpcr(__fpcr) \
+ __asm__ __volatile__ ("fmove%.l %!,%0" : "=dm" (__fpcr))
+#define __set_fpcr(__fpcr) \
+ __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (__fpcr))
+
+#define __get_fpsr(__fpsr) \
+ __asm__ __volatile__ ("fmove%.l %/fpsr,%0" : "=dm" (__fpsr))
+#define __set_fpsr(__fpsr) \
+ __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (__fpsr))
+
+#define __fmul(__s, __t, __d) \
+ do { \
+ __t d = __d; \
+ __asm__ __volatile__ ("fmul" __s "; fnop" : "=f" (d) : "0" (d)); \
+ } while (/*CONSTCOND*/0)
+
+#define __fdiv(__s, __t, __d) \
+ do { \
+ __t d = __d; \
+ __asm__ __volatile__ ("fdiv" __s "; fnop" : "=f" (d) : "0" (d)); \
+ } while (/*CONSTCOND*/0)
+
+#define __fetox(__s, __t, __d) \
+ do { \
+ __t d = __d; \
+ __asm__ __volatile__ ("fetox" __s "; fnop" : "=f" (d) : "0" (d)); \
+ } while (/*CONSTCOND*/0)
+
+#define __fgetenv(__envp) \
+ __asm__ __volatile__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (__envp))
+
+#define __fsetenv(__envp) \
+ __asm__ __volatile__ ("fmovem%.l %0,%/fpcr/%/fpsr/%/fpiar" : : "m" (__envp))
+
+__fenv_static inline int
+feclearexcept(int __excepts)
+{
+ fexcept_t __fpsr;
+
+ __excepts &= FE_ALL_EXCEPT;
+
+ __get_fpsr(__fpsr);
+ __fpsr &= ~__excepts;
+ __set_fpsr(__fpsr);
+
+ return 0;
+}
+
+__fenv_static inline int
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+ fexcept_t __fpsr;
+
+ __get_fpsr(__fpsr);
+
+ *__flagp = __fpsr & __excepts & FE_ALL_EXCEPT;
+
+ return 0;
+}
+
+__fenv_static inline int
+fesetexceptflag(const fexcept_t *__flagp, int __excepts)
+{
+ fexcept_t __fpsr;
+
+ __get_fpsr(__fpsr);
+
+ __fpsr &= ~(__excepts & FE_ALL_EXCEPT);
+ __fpsr |= *__flagp & __excepts & FE_ALL_EXCEPT;
+
+ __set_fpsr(__fpsr);
+
+ return 0;
+}
+
+__fenv_static inline int
+feraiseexcept(int __excepts)
+{
+ if (__excepts & FE_INVALID) /* Inf * 0 */
+ __fmul("%.s %#0r0,%0", double, __builtin_huge_val());
+
+ if (__excepts & FE_DIVBYZERO) /* 1.0 / 0 */
+ __fdiv("%.s %#0r0,%0", double, 1.0);
+
+ if (__excepts & FE_OVERFLOW) /* MAX * MAX */
+ __fmul("%.x %0,%0", long double, LDBL_MAX);
+
+ if (__excepts & FE_UNDERFLOW) /* e ^ -MAX */
+ __fetox("%.x %0", long double, -LDBL_MAX);
+
+ if (__excepts & FE_INEXACT) /* 1 / 3 */
+ __fdiv("%.s %#0r3,%0", long double, 1.0);
+
+ return 0;
+}
+
+__fenv_static inline int
+fetestexcept(int __excepts)
+{
+ fexcept_t __fpsr;
+
+ __get_fpsr(__fpsr);
+
+ return __fpsr & __excepts & FE_ALL_EXCEPT;
+}
+
+__fenv_static inline int
+fegetround(void)
+{
+ fexcept_t __fpcr;
+
+ __get_fpcr(__fpcr);
+ return __fpcr & _ROUND_MASK;
+}
+
+__fenv_static inline int
+fesetround(int __round)
+{
+ fexcept_t __fpcr;
+
+ if (__round & ~_ROUND_MASK)
+ return -1;
+
+ __get_fpcr(__fpcr);
+
+ __fpcr &= ~_ROUND_MASK;
+ __fpcr |= __round;
+
+ __set_fpcr(__fpcr);
+
+ return 0;
+}
+
+__fenv_static inline int
+fegetenv(fenv_t *__envp)
+{
+ __fgetenv(__envp);
+
+ return 0;
+}
+
+__fenv_static inline int
+feholdexcept(fenv_t *__envp)
+{
+ fexcept_t __fpcr, __fpsr;
+
+ __fgetenv(__envp);
+ __fpsr = __envp->fpsr & ~FE_ALL_EXCEPT;
+ __fset_fpsr(__fpsr); /* clear all */
+ __fpcr = __envp->fpcr & ~(FE_ALL_EXCEPT << 6);
+ __fset_fpcr(__fpcr); /* set non/stop */
+
+ return 0;
+}
+
+__fenv_static inline int
+fesetenv(const fenv_t *__envp)
+{
+ fenv_t __tenv;
+
+ __fgetenv(__tenv);
+
+ if (__envp == FE_DFL_ENV) {
+ __tenv.fpcr |=
+ __envp->fpcr & ((FE_ALL_EXCEPT << 6) | FE_UPWARD);
+ __tenv.fpsr |= __envp->fpsr & FE_ALL_EXCEPT;
+ }
+
+ __fsetenv(__tenv);
+
+ return 0;
+}
+
+__fenv_static inline int
+feupdateenv(const fenv_t *__envp)
+{
+ fexcept_t __fpsr;
+
+ __get_fpsr(__fpsr);
+ __fpsr &= FE_ALL_EXCEPT;
+ fesetenv(__envp);
+ feraiseexcept((int)__fpsr);
+ return 0;
+}
+
+#if defined(_NETBSD_SOURCE) || defined(_GNU_SOURCE)
+
+/* We currently provide no external definitions of the functions below. */
+
+static inline int
+feenableexcept(int __mask)
+{
+ fexcept_t __fpsr, __oldmask;
+
+ __get_fpsr(__fpsr);
+ __oldmask = __fpsr & FE_ALL_EXCEPT;
+ __fpsr |= __mask & FE_ALL_EXCEPT;
+ __set_fpsr(__fpsr);
+
+ return __oldmask;
+}
+
+static inline int
+fedisableexcept(int __mask)
+{
+ fexcept_t __fpsr, __oldmask;
+
+ __get_fpsr(__fpsr);
+ __oldmask = __fpsr & FE_ALL_EXCEPT;
+ __fpsr &= ~(__mask & FE_ALL_EXCEPT);
+ __set_fpsr(__fpsr);
+
+ return __oldmask;
+}
+
+static inline int
+fegetexcept(void)
+{
+ fexcept_t __fpsr;
+
+ __get_fpsr(__fpsr);
+
+ return __fpsr & FE_ALL_EXCEPT;
+}
+
+#endif /* _NETBSD_SOURCE || _GNU_SOURCE */
+
+__END_DECLS
+
+#endif /* _M68K_FENV_H_ */