From ac8277407eec4f1f45a73b8462b4a807928dd1f0 Mon Sep 17 00:00:00 2001 From: Peter Valchev Date: Sun, 28 Apr 2002 20:55:15 +0000 Subject: IEEE 754 floating point completion code, and implementation of the FP_C (Floating Point Control Quadword). From ross@NetBSD. Added a way to disable it with option NO_IEEE, which appears on the ramdisks to save space. This affects only programs compiled with -mieee, and what it essentially does is enabling infinities and NaNs, instead of generating SIGFPE on division by zero, overflow, etc. ok art, deraadt --- sys/arch/alpha/include/cpu.h | 54 +++++++++++++++-- sys/arch/alpha/include/fpu.h | 121 +++++++++++++++++++++++++++++++++++++++ sys/arch/alpha/include/ieeefp.h | 39 +++++++++++-- sys/arch/alpha/include/pcb.h | 3 +- sys/arch/alpha/include/proc.h | 23 +++++++- sys/arch/alpha/include/sysarch.h | 69 ++++++++++++++++++++++ 6 files changed, 295 insertions(+), 14 deletions(-) create mode 100644 sys/arch/alpha/include/fpu.h create mode 100644 sys/arch/alpha/include/sysarch.h (limited to 'sys/arch/alpha/include') diff --git a/sys/arch/alpha/include/cpu.h b/sys/arch/alpha/include/cpu.h index b599120df2e..4a4ff665401 100644 --- a/sys/arch/alpha/include/cpu.h +++ b/sys/arch/alpha/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.15 2001/11/06 18:41:09 art Exp $ */ +/* $OpenBSD: cpu.h,v 1.16 2002/04/28 20:55:14 pvalchev Exp $ */ /* $NetBSD: cpu.h,v 1.45 2000/08/21 02:03:12 thorpej Exp $ */ /*- @@ -83,6 +83,22 @@ #ifndef _ALPHA_CPU_H_ #define _ALPHA_CPU_H_ +#ifndef NO_IEEE +typedef union alpha_s_float { + u_int32_t i; + u_int32_t frac: 23, + exp: 8, + sign: 1; +} s_float; + +typedef union alpha_t_float { + u_int64_t i; + u_int64_t frac: 52, + exp: 11, + sign: 1; +} t_float; +#endif + /* * Exported definitions unique to Alpha cpu support. */ @@ -100,7 +116,11 @@ struct reg; struct rpb; struct trapframe; +extern u_long cpu_implver; /* from IMPLVER instruction */ +extern u_long cpu_amask; /* from AMASK instruction */ extern int bootdev_debug; +extern int alpha_fp_sync_complete; +extern int alpha_unaligned_print, alpha_unaligned_fix, alpha_unaligned_sigbus; void XentArith(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */ void XentIF(u_int64_t, u_int64_t, u_int64_t); /* MAGIC */ @@ -195,6 +215,11 @@ struct cpu_info { #define CPUF_PRIMARY 0x01 /* CPU is primary CPU */ #define CPUF_PRESENT 0x02 /* CPU is present */ #define CPUF_RUNNING 0x04 /* CPU is running */ +#define CPUF_PAUSED 0x08 /* CPU is paused */ +#define CPUF_FPUSAVE 0x10 /* CPU is currently in fpusave_cpu() */ + +void fpusave_cpu(struct cpu_info *, int); +void fpusave_proc(struct proc *, int); #if defined(MULTIPROCESSOR) extern __volatile u_long cpus_running; @@ -218,9 +243,6 @@ extern struct cpu_info cpu_info_store; #define fpcurproc curcpu()->ci_fpcurproc #define curpcb curcpu()->ci_curpcb -extern u_long cpu_implver; /* from IMPLVER instruction */ -extern u_long cpu_amask; /* from AMASK instruction */ - /* * definitions of cpu-dependent requirements * referenced in generic code @@ -309,8 +331,9 @@ do { \ #define CPU_UNALIGNED_FIX 4 /* int: fix unaligned accesses */ #define CPU_UNALIGNED_SIGBUS 5 /* int: SIGBUS unaligned accesses */ #define CPU_BOOTED_KERNEL 6 /* string: booted kernel name */ -#define CPU_CHIPSET 7 /* chipset information */ -#define CPU_MAXID 8 /* 6 valid machdep IDs */ +#define CPU_FP_SYNC_COMPLETE 7 /* int: always fixup sync fp traps */ +#define CPU_MAXID 8 /* 7 valid machdep IDs */ +#define CPU_CHIPSET 9 /* chipset information */ #define CPU_CHIPSET_MEM 1 /* PCI memory address */ #define CPU_CHIPSET_BWX 2 /* PCI supports BWX */ @@ -328,6 +351,7 @@ do { \ { "unaligned_sigbus", CTLTYPE_INT }, \ { "booted_kernel", CTLTYPE_STRING }, \ { "chipset", CTLTYPE_NODE }, \ + { "fp_sync_complete", CTLTYPE_INT }, \ } #ifdef _KERNEL @@ -338,5 +362,23 @@ struct reg; struct rpb; struct trapframe; +/* IEEE and VAX FP completion */ + +#ifndef NO_IEEE +void alpha_sts(int, s_float *); /* MAGIC */ +void alpha_stt(int, t_float *); /* MAGIC */ +void alpha_lds(int, s_float *); /* MAGIC */ +void alpha_ldt(int, t_float *); /* MAGIC */ + +uint64_t alpha_read_fpcr(void); /* MAGIC */ +void alpha_write_fpcr(u_int64_t); /* MAGIC */ + +u_int64_t alpha_read_fp_c(struct proc *); +void alpha_write_fp_c(struct proc *, u_int64_t); + +void alpha_enable_fp(struct proc *, int); +int alpha_fp_complete(u_long, u_long, struct proc *, u_int64_t *); +#endif + #endif /* _KERNEL */ #endif /* _ALPHA_CPU_H_ */ diff --git a/sys/arch/alpha/include/fpu.h b/sys/arch/alpha/include/fpu.h new file mode 100644 index 00000000000..1aa71c1e765 --- /dev/null +++ b/sys/arch/alpha/include/fpu.h @@ -0,0 +1,121 @@ +/* $OpenBSD: fpu.h,v 1.1 2002/04/28 20:55:14 pvalchev Exp $ */ +/* $NetBSD: fpu.h,v 1.4 2001/04/26 03:10:46 ross Exp $ */ + +/*- + * Copyright (c) 2001 Ross Harvey + * All rights reserved. + * + * This software was written for NetBSD. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 _ALPHA_FPU_H_ +#define _ALPHA_FPU_H_ + +#define _FP_C_DEF(n) (1UL << (n)) + +/* + * Most of these next definitions were moved from . Apparently the + * names happen to match those exported by Compaq and Linux from their fpu.h + * files. + */ + +#define FPCR_SUM _FP_C_DEF(63) +#define FPCR_INED _FP_C_DEF(62) +#define FPCR_UNFD _FP_C_DEF(61) +#define FPCR_UNDZ _FP_C_DEF(60) +#define FPCR_DYN(rm) ((unsigned long)(rm) << 58) +#define FPCR_IOV _FP_C_DEF(57) +#define FPCR_INE _FP_C_DEF(56) +#define FPCR_UNF _FP_C_DEF(55) +#define FPCR_OVF _FP_C_DEF(54) +#define FPCR_DZE _FP_C_DEF(53) +#define FPCR_INV _FP_C_DEF(52) +#define FPCR_OVFD _FP_C_DEF(51) +#define FPCR_DZED _FP_C_DEF(50) +#define FPCR_INVD _FP_C_DEF(49) +#define FPCR_DNZ _FP_C_DEF(48) +#define FPCR_DNOD _FP_C_DEF(47) + +#define FPCR_MIRRORED (FPCR_INE | FPCR_UNF | FPCR_OVF | FPCR_DZE | FPCR_INV) +#define FPCR_MIR_START 52 + +/* + * The AARM specifies the bit positions of the software word used for + * user mode interface to the control and status of the kernel completion + * routines. Although it largely just redefines the FPCR, it shuffles + * the bit order. The names of the bits are defined in the AARM, and + * the definition prefix can easily be determined from public domain + * programs written to either the Compaq or Linux interfaces, which + * appear to be identical. + */ + +#define IEEE_STATUS_DNO _FP_C_DEF(22) +#define IEEE_STATUS_INE _FP_C_DEF(21) +#define IEEE_STATUS_UNF _FP_C_DEF(20) +#define IEEE_STATUS_OVF _FP_C_DEF(19) +#define IEEE_STATUS_DZE _FP_C_DEF(18) +#define IEEE_STATUS_INV _FP_C_DEF(17) + +#define IEEE_TRAP_ENABLE_DNO _FP_C_DEF(6) +#define IEEE_TRAP_ENABLE_INE _FP_C_DEF(5) +#define IEEE_TRAP_ENABLE_UNF _FP_C_DEF(4) +#define IEEE_TRAP_ENABLE_OVF _FP_C_DEF(3) +#define IEEE_TRAP_ENABLE_DZE _FP_C_DEF(2) +#define IEEE_TRAP_ENABLE_INV _FP_C_DEF(1) + +#define IEEE_INHERIT _FP_C_DEF(14) +#define IEEE_MAP_UMZ _FP_C_DEF(13) +#define IEEE_MAP_DMZ _FP_C_DEF(12) + +#define FP_C_MIRRORED (IEEE_STATUS_INE | IEEE_STATUS_UNF | IEEE_STATUS_OVF\ + | IEEE_STATUS_DZE | IEEE_STATUS_INV) +#define FP_C_MIR_START 17 + +#ifdef _KERNEL + +#define FLD_MASK(len) ((1UL << (len)) - 1) +#define FLD_CLEAR(obj, origin, len) \ + ((obj) & ~(FLD_MASK(len) << (origin))) +#define FLD_INSERT(obj, origin, len, value) \ + (FLD_CLEAR(obj, origin, len) | (value) << origin) + +#define FP_C_TO_OPENBSD_MASK(fp_c) ((fp_c) >> 1 & 0x3f) +#define FP_C_TO_OPENBSD_FLAG(fp_c) ((fp_c) >> 17 & 0x3f) +#define OPENBSD_MASK_TO_FP_C(m) (((m) & 0x3f) << 1) +#define OPENBSD_FLAG_TO_FP_C(s) (((s) & 0x3f) << 17) +#define CLEAR_FP_C_MASK(fp_c) ((fp_c) & ~(0x3f << 1)) +#define CLEAR_FP_C_FLAG(fp_c) ((fp_c) & ~(0x3f << 17)) +#define SET_FP_C_MASK(fp_c, m) (CLEAR_FP_C_MASK(fp_c) | OPENBSD_MASK_TO_FP_C(m)) +#define SET_FP_C_FLAG(fp_c, m) (CLEAR_FP_C_FLAG(fp_c) | OPENBSD_FLAG_TO_FP_C(m)) + +#endif + +#endif diff --git a/sys/arch/alpha/include/ieeefp.h b/sys/arch/alpha/include/ieeefp.h index 4ebb20b0aa5..4cb8539a2c1 100644 --- a/sys/arch/alpha/include/ieeefp.h +++ b/sys/arch/alpha/include/ieeefp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieeefp.h,v 1.3 1996/10/30 22:39:08 niklas Exp $ */ +/* $OpenBSD: ieeefp.h,v 1.4 2002/04/28 20:55:14 pvalchev Exp $ */ /* $NetBSD: ieeefp.h,v 1.1 1995/04/29 01:09:17 cgd Exp $ */ /* @@ -10,18 +10,45 @@ #define _ALPHA_IEEEFP_H_ typedef int fp_except; + +#ifdef _KERNEL + +#include +#include +#include +#include + +/* FP_X_IOV is intentionally omitted from the architecture flags mask */ + +#define FP_AA_FLAGS (FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL | FP_X_IMP) + +#define float_raise(f) \ + do curproc->p_md.md_flags |= OPENBSD_FLAG_TO_FP_C(f); \ + while(0) + +#define float_set_inexact() float_raise(FP_X_IMP) +#define float_set_invalid() float_raise(FP_X_INV) +#define fpgetround() (alpha_read_fpcr() >> 58 & 3) + +#endif + #define FP_X_INV 0x01 /* invalid operation exception */ #define FP_X_DZ 0x02 /* divide-by-zero exception */ #define FP_X_OFL 0x04 /* overflow exception */ #define FP_X_UFL 0x08 /* underflow exception */ #define FP_X_IMP 0x10 /* imprecise (loss of precision; "inexact") */ -#define FP_X_IOV 0x20 /* integer overflow XXX? */ +#define FP_X_IOV 0x20 /* integer overflow */ +/* + * fp_rnd bits match the fpcr, below, as well as bits 12:11 + * in fp operate instructions + */ typedef enum { - FP_RZ=0, /* round to zero (truncate) */ - FP_RM=1, /* round toward negative infinity */ - FP_RN=2, /* round to nearest representable number */ - FP_RP=3 /* round toward positive infinity */ + FP_RZ = 0, /* round to zero (truncate) */ + FP_RM = 1, /* round toward negative infinity */ + FP_RN = 2, /* round to nearest representable number */ + FP_RP = 3, /* round toward positive infinity */ + _FP_DYNAMIC=FP_RP } fp_rnd; #endif /* _ALPHA_IEEEFP_H_ */ diff --git a/sys/arch/alpha/include/pcb.h b/sys/arch/alpha/include/pcb.h index f7eb89491af..b91bdf22438 100644 --- a/sys/arch/alpha/include/pcb.h +++ b/sys/arch/alpha/include/pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcb.h,v 1.5 2002/03/14 01:26:27 millert Exp $ */ +/* $OpenBSD: pcb.h,v 1.6 2002/04/28 20:55:14 pvalchev Exp $ */ /* $NetBSD: pcb.h,v 1.5 1996/11/13 22:21:00 cgd Exp $ */ /* @@ -52,6 +52,7 @@ struct pcb { struct fpreg pcb_fp; /* FP registers [SW] */ unsigned long pcb_onfault; /* for copy faults [SW] */ unsigned long pcb_accessaddr; /* for [fs]uswintr [SW] */ + struct cpu_info *__volatile pcb_fpcpu; /* CPU with our FP state[SW] */ }; /* diff --git a/sys/arch/alpha/include/proc.h b/sys/arch/alpha/include/proc.h index fd698f6f9e1..dab1d4c78c0 100644 --- a/sys/arch/alpha/include/proc.h +++ b/sys/arch/alpha/include/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.7 2002/03/14 01:26:27 millert Exp $ */ +/* $OpenBSD: proc.h,v 1.8 2002/04/28 20:55:14 pvalchev Exp $ */ /* $NetBSD: proc.h,v 1.2 1995/03/24 15:01:36 cgd Exp $ */ /* @@ -45,7 +45,28 @@ struct mdproc { struct mdbpt md_sstep[2]; /* two breakpoints for sstep */ }; +/* + * md_flags usage + * -------------- + * MDP_FPUSED + * A largely unused bit indicating the presence of FPU history. + * Cleared on exec. Set but not used by the fpu context switcher + * itself. + * + * MDP_FP_C + * The architected FP Control word. It should forever begin at bit 1, + * as the bits are AARM specified and this way it doesn't need to be + * shifted. + * + * Until C99 there was never an IEEE 754 API, making most of the + * standard useless. Because of overlapping AARM, OSF/1, NetBSD, and + * C99 API's, the use of the MDP_FP_C bits is defined variously in + * ieeefp.h and fpu.h. + */ #define MDP_FPUSED 0x0001 /* Process used the FPU */ +#ifndef NO_IEEE +#define MDP_FP_C 0x7ffffe /* Extended FP_C Quadword bits */ +#endif #define MDP_STEP1 0x0002 /* Single step normal */ #define MDP_STEP2 0x0003 /* Single step branch */ diff --git a/sys/arch/alpha/include/sysarch.h b/sys/arch/alpha/include/sysarch.h new file mode 100644 index 00000000000..a439c52c7e2 --- /dev/null +++ b/sys/arch/alpha/include/sysarch.h @@ -0,0 +1,69 @@ +/* $OpenBSD: sysarch.h,v 1.3 2002/04/28 20:55:14 pvalchev Exp $ */ +/* $NetBSD: sysarch.h,v 1.8 2001/04/26 03:10:46 ross Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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 _ALPHA_SYSARCH_H_ +#define _ALPHA_SYSARCH_H_ + +#include +#include + +/* + * Architecture specific syscalls (ALPHA) + */ + +#define ALPHA_FPGETMASK 0 +#define ALPHA_FPSETMASK 1 +#define ALPHA_FPSETSTICKY 2 +#define ALPHA_FPGETSTICKY 6 +#define ALPHA_GET_FP_C 7 +#define ALPHA_SET_FP_C 8 + +struct alpha_fp_except_args { + fp_except mask; +}; + +struct alpha_fp_c_args { + uint64_t fp_c; +}; + +#ifdef _KERNEL +int sysarch(int, void *); +#endif /* _KERNEL */ + +#endif /* !_ALPHA_SYSARCH_H_ */ -- cgit v1.2.3