summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/include
diff options
context:
space:
mode:
authorPeter Valchev <pvalchev@cvs.openbsd.org>2002-04-28 20:55:15 +0000
committerPeter Valchev <pvalchev@cvs.openbsd.org>2002-04-28 20:55:15 +0000
commitac8277407eec4f1f45a73b8462b4a807928dd1f0 (patch)
treee97e090b84d170144eb0ed99eeba0d7e1ab1ed5d /sys/arch/alpha/include
parent4433d79654bae3b6a03df679b3ace77f4b639331 (diff)
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
Diffstat (limited to 'sys/arch/alpha/include')
-rw-r--r--sys/arch/alpha/include/cpu.h54
-rw-r--r--sys/arch/alpha/include/fpu.h121
-rw-r--r--sys/arch/alpha/include/ieeefp.h39
-rw-r--r--sys/arch/alpha/include/pcb.h3
-rw-r--r--sys/arch/alpha/include/proc.h23
-rw-r--r--sys/arch/alpha/include/sysarch.h69
6 files changed, 295 insertions, 14 deletions
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 <ieeefp.h>. 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 <sys/param.h>
+#include <sys/proc.h>
+#include <machine/fpu.h>
+#include <machine/cpu.h>
+
+/* 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 <machine/bus.h>
+#include <machine/ieeefp.h>
+
+/*
+ * 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_ */