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_ */

Reply via email to