From b7f762137adea9d0338ed8f3299f25b2be737af1 Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Wed, 23 Dec 1998 11:50:52 +0000 Subject: [PATCH] Implement fpsetmask() and other fp*() functions. Programs should use #include to access these functions instead of the i386 specific #include Submitted by: Hidetoshi Shimokawa --- include/Makefile | 4 +-- include/ieeefp.h | 25 +++++++++++++++++ lib/libc/alpha/SYS.h | 4 +-- lib/libc/alpha/gen/Makefile.inc | 8 ++---- lib/libc/alpha/gen/fpgetmask.c | 11 ++++++-- lib/libc/alpha/gen/fpgetround.c | 7 ++--- lib/libc/alpha/gen/fpgetsticky.c | 10 +++++-- lib/libc/alpha/gen/fpsetmask.c | 12 ++++++-- lib/libc/alpha/gen/fpsetround.c | 17 +++++------- lib/libc/alpha/gen/fpsetsticky.c | 16 +++++++++-- lib/libc/alpha/sys/cerror.S | 6 ++-- lib/msun/Makefile | 3 +- sys/alpha/alpha/machdep.c | 43 ++++++++++++++++++++++++++++- sys/alpha/alpha/sys_machdep.c | 47 +++++++++++++++++++++++++++++++- sys/alpha/include/alpha_cpu.h | 8 ++++-- sys/alpha/include/fpu.h | 12 +++++++- sys/alpha/include/ieeefp.h | 16 ++++++----- sys/alpha/include/sysarch.h | 6 ++-- 18 files changed, 205 insertions(+), 50 deletions(-) create mode 100644 include/ieeefp.h diff --git a/include/Makefile b/include/Makefile index 55e9f0ff9d08..89d825d9762a 100644 --- a/include/Makefile +++ b/include/Makefile @@ -1,5 +1,5 @@ # @(#)Makefile 8.2 (Berkeley) 1/4/94 -# $Id: Makefile,v 1.87 1998/10/17 15:52:48 bde Exp $ +# $Id: Makefile,v 1.88 1998/12/19 00:21:13 dt Exp $ # # Doing a make install builds /usr/include # @@ -10,7 +10,7 @@ CLEANFILES= osreldate.h version vers.c SUBDIR= rpcsvc FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \ dlfcn.h elf.h err.h fnmatch.h fstab.h \ - fts.h glob.h grp.h strhash.h histedit.h iso646.h \ + fts.h glob.h grp.h strhash.h histedit.h ieeefp.h iso646.h \ kvm.h limits.h link.h locale.h malloc.h memory.h mpool.h \ ndbm.h netdb.h nl_types.h nlist.h objformat.h \ paths.h pthread.h pthread_np.h pwd.h \ diff --git a/include/ieeefp.h b/include/ieeefp.h new file mode 100644 index 000000000000..83db9a5574fe --- /dev/null +++ b/include/ieeefp.h @@ -0,0 +1,25 @@ +/* $NetBSD: ieeefp.h,v 1.4 1998/01/09 08:03:43 perry Exp $ */ + +/* + * Written by J.T. Conklin, Apr 6, 1995 + * Public domain. + */ + +#ifndef _IEEEFP_H_ +#define _IEEEFP_H_ + +#include +#include + +#ifdef i386 +#include +#else +extern fp_rnd fpgetround __P((void)); +extern fp_rnd fpsetround __P((fp_rnd)); +extern fp_except fpgetmask __P((void)); +extern fp_except fpsetmask __P((fp_except)); +extern fp_except fpgetsticky __P((void)); +extern fp_except fpsetsticky __P((fp_except)); +#endif /* i386 */ + +#endif /* _IEEEFP_H_ */ diff --git a/lib/libc/alpha/SYS.h b/lib/libc/alpha/SYS.h index cfc0909d8d32..15b7f8b9e853 100644 --- a/lib/libc/alpha/SYS.h +++ b/lib/libc/alpha/SYS.h @@ -1,4 +1,4 @@ -/* $Id: SYS.h,v 1.2 1998/06/09 22:43:34 jb Exp $ */ +/* $Id: SYS.h,v 1.3 1998/08/08 02:24:03 jb Exp $ */ /* From: NetBSD: SYS.h,v 1.5 1997/05/02 18:15:15 kleink Exp */ /* @@ -41,7 +41,7 @@ LLABEL(name,0): \ LDGP(gp); \ beq a3, LLABEL(name,1); \ - jmp zero, cerror; \ + jmp zero, .cerror; \ LLABEL(name,1): diff --git a/lib/libc/alpha/gen/Makefile.inc b/lib/libc/alpha/gen/Makefile.inc index 3ff99f001439..cc7a87c10cff 100644 --- a/lib/libc/alpha/gen/Makefile.inc +++ b/lib/libc/alpha/gen/Makefile.inc @@ -1,10 +1,8 @@ -# $Id: Makefile.inc,v 1.3 1998/08/08 02:18:07 jb Exp $ +# $Id: Makefile.inc,v 1.4 1998/08/17 03:38:54 jb Exp $ SRCS+= _setjmp.S fabs.S frexp.c infinity.c isinf.c ldexp.c modf.c setjmp.S -SRCS+= flt_rounds.c - -#SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ -# fpsetround.c fpsetsticky.c +SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ + fpsetround.c fpsetsticky.c SRCS+= sigsetjmp.S SRCS+= __divqu.S __divq.S __divlu.S __divl.S diff --git a/lib/libc/alpha/gen/fpgetmask.c b/lib/libc/alpha/gen/fpgetmask.c index c52a7ef07112..516ae981d55c 100644 --- a/lib/libc/alpha/gen/fpgetmask.c +++ b/lib/libc/alpha/gen/fpgetmask.c @@ -31,12 +31,19 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include +#include + +struct params { + u_int64_t mask; +}; fp_except fpgetmask() { + struct params p; - /* XXX */ - abort(); + sysarch(ALPHA_GET_FPMASK, (char *) &p); + return((fp_except) p.mask); } diff --git a/lib/libc/alpha/gen/fpgetround.c b/lib/libc/alpha/gen/fpgetround.c index 39b9b4744a6b..46976c2e4c11 100644 --- a/lib/libc/alpha/gen/fpgetround.c +++ b/lib/libc/alpha/gen/fpgetround.c @@ -33,6 +33,7 @@ #include #include +#include fp_rnd fpgetround() @@ -40,10 +41,8 @@ fpgetround() double fpcrval; u_int64_t old; - __asm__("trapb"); - __asm__("mf_fpcr %0" : "=f" (fpcrval)); - __asm__("trapb"); + GET_FPCR(fpcrval); old = *(u_int64_t *)&fpcrval; - return ((old >> 58) & 0x3); + return ((old & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT); } diff --git a/lib/libc/alpha/gen/fpgetsticky.c b/lib/libc/alpha/gen/fpgetsticky.c index c36db3913d5f..c0ff4d75c88a 100644 --- a/lib/libc/alpha/gen/fpgetsticky.c +++ b/lib/libc/alpha/gen/fpgetsticky.c @@ -31,12 +31,18 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include +#include fp_except fpgetsticky() { + double fpcrval; + u_int64_t old; - /* XXX */ - abort(); + GET_FPCR(fpcrval); + old = *(u_int64_t *)&fpcrval; + return (((old >> IEEE_STATUS_TO_FPCR_SHIFT) & IEEE_STATUS_MASK) + >> IEEE_STATUS_TO_EXCSUM_SHIFT); } diff --git a/lib/libc/alpha/gen/fpsetmask.c b/lib/libc/alpha/gen/fpsetmask.c index 87fc5a2f4b4c..05201ce81d40 100644 --- a/lib/libc/alpha/gen/fpsetmask.c +++ b/lib/libc/alpha/gen/fpsetmask.c @@ -31,13 +31,21 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include +#include + +struct params { + u_int64_t mask; +}; fp_except fpsetmask(mask) fp_except mask; { + struct params p; - /* XXX */ - abort(); + p.mask = (u_int64_t) mask; + sysarch(ALPHA_SET_FPMASK, (char *) &p); + return ((fp_except) p.mask); } diff --git a/lib/libc/alpha/gen/fpsetround.c b/lib/libc/alpha/gen/fpsetround.c index c28093cad87c..0d8f40af6d65 100644 --- a/lib/libc/alpha/gen/fpsetround.c +++ b/lib/libc/alpha/gen/fpsetround.c @@ -33,6 +33,7 @@ #include #include +#include fp_rnd fpsetround(rnd_dir) @@ -41,18 +42,14 @@ fpsetround(rnd_dir) double fpcrval; u_int64_t old, new; - __asm__("trapb"); - __asm__("mf_fpcr %0" : "=f" (fpcrval)); - __asm__("trapb"); + GET_FPCR(fpcrval); old = *(u_int64_t *)&fpcrval; - new = old & ~(long)0x0c00000000000000; - new = (long)rnd_dir << 58; + new = old & (~FPCR_DYN_MASK); + new |= ((long) rnd_dir << FPCR_DYN_SHIFT) & FPCR_DYN_MASK; + *(u_int64_t *)&fpcrval = new; + SET_FPCR(fpcrval); - __asm__("trapb"); - __asm__("mt_fpcr %0" : : "f" (fpcrval)); - __asm__("trapb"); - - return ((old >> 58) & 0x3); + return ((old & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT); } diff --git a/lib/libc/alpha/gen/fpsetsticky.c b/lib/libc/alpha/gen/fpsetsticky.c index 90a993ee642a..ae0d742f79f0 100644 --- a/lib/libc/alpha/gen/fpsetsticky.c +++ b/lib/libc/alpha/gen/fpsetsticky.c @@ -31,13 +31,25 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include +#include fp_except fpsetsticky(sticky) fp_except sticky; { + double fpcrval; + u_int64_t old,new ; - /* XXX */ - abort(); + GET_FPCR(fpcrval); + old = *(u_int64_t *)&fpcrval; + new = old & ~ (IEEE_STATUS_MASK << IEEE_STATUS_TO_FPCR_SHIFT); + new |= ((sticky << IEEE_STATUS_TO_EXCSUM_SHIFT) & IEEE_STATUS_MASK) + << IEEE_STATUS_TO_FPCR_SHIFT; + *(u_int64_t *)&fpcrval = new; + SET_FPCR(fpcrval); + + return (((old >> IEEE_STATUS_TO_FPCR_SHIFT) & IEEE_STATUS_MASK) + >> IEEE_STATUS_TO_EXCSUM_SHIFT); } diff --git a/lib/libc/alpha/sys/cerror.S b/lib/libc/alpha/sys/cerror.S index cce30068de6c..a3d2b1a24097 100644 --- a/lib/libc/alpha/sys/cerror.S +++ b/lib/libc/alpha/sys/cerror.S @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $Id: cerror.S,v 1.2 1998/06/09 22:56:24 jb Exp $ */ /* From: NetBSD: cerror.S,v 1.4 1996/11/08 00:52:46 cgd Exp */ /* @@ -34,7 +34,7 @@ #define FRAME_RA_OFFSET 0 #define FRAME_V0_OFFSET 8 -NESTED(cerror, 0, FRAME_SIZE, ra, IM_RA|IM_V0, 0) +NESTED(.cerror, 0, FRAME_SIZE, ra, IM_RA|IM_V0, 0) br t0, L1 L1: LDGP(t0) @@ -51,4 +51,4 @@ L1: LDGP(t0) ldq ra, FRAME_RA_OFFSET(sp) lda sp, FRAME_SIZE(sp) RET -END(cerror) +END(.cerror) diff --git a/lib/msun/Makefile b/lib/msun/Makefile index a0ca7405fbd7..c62ee87d0cac 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -1,5 +1,5 @@ # @(#)Makefile 5.1beta 93/09/24 -# $Id: Makefile,v 1.19 1997/04/15 14:05:28 bde Exp $ +# $Id: Makefile,v 1.20 1998/02/20 07:44:29 jb Exp $ # # ==================================================== # Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. @@ -48,6 +48,7 @@ ARCH_SRCS = s_copysign.S s_copysignf.S # XXX Comment from NetBSD/Alpha: # XXX LINT SIGFPEs in e_exp.c's strtod(). FP underflow/denorm software # handling is broken (doesn't exist!) on the Alpha port. +CFLAGS += -mtrap-precision=i -mfp-trap-mode=su .elif ${MACHINE_ARCH} == "i386" ARCH= i387 ARCH_PREFIX= ${ARCH}_ diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index e8240f15b702..39090de0c42d 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: machdep.c,v 1.26 1998/12/04 22:54:42 archie Exp $ + * $Id: machdep.c,v 1.27 1998/12/16 16:28:56 bde Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -492,6 +492,21 @@ alpha_unknown_sysname() static void identifycpu(void) { + u_int64_t type, major, minor; + u_int64_t amask; + struct pcs *pcsp; + char *cpuname[] = { + "unknown", /* 0 */ + "EV3", /* 1 */ + "EV4 (21064)", /* 2 */ + "Simulation", /* 3 */ + "LCA Family", /* 4 */ + "EV5 (21164)", /* 5 */ + "EV45 (21064A)", /* 6 */ + "EV56 (21164A)", /* 7 */ + "EV6 (21264)", /* 8 */ + "PCA56 (21164PC)" /* 9 */ + }; /* * print out CPU identification information. @@ -509,6 +524,32 @@ identifycpu(void) printf("variation: 0x%lx, revision 0x%lx\n", hwrpb->rpb_variation, *(long *)hwrpb->rpb_revision); #endif + pcsp = LOCATE_PCS(hwrpb, hwrpb->rpb_primary_cpu_id); + /* cpu type */ + type = pcsp->pcs_proc_type; + major = (type & PCS_PROC_MAJOR) >> PCS_PROC_MAJORSHIFT; + minor = (type & PCS_PROC_MINOR) >> PCS_PROC_MINORSHIFT; + if (major < sizeof(cpuname)/sizeof(char *)) + printf("CPU: %s major=%lu minor=%lu", + cpuname[major], major, minor); + else + printf("CPU: major=%lu minor=%lu\n", major, minor); + /* amask */ + if (major >= PCS_PROC_EV56) { + amask = 0xffffffff; /* 32 bit for printf */ + amask = (~alpha_amask(amask)) & amask; + printf(" extensions=0x%b\n", (u_int32_t) amask, + "\020" + "\001BWX" + "\002FIX" + "\003CIX" + "\011MVI" + "\012PRECISE" + ); + } else + printf("\n"); + /* PAL code */ + printf("OSF PAL rev: 0x%lx\n", pcsp->pcs_palrevisions[PALvar_OSF1]); } extern char kernel_text[], _end[]; diff --git a/sys/alpha/alpha/sys_machdep.c b/sys/alpha/alpha/sys_machdep.c index 6ff5956f6591..0d89b8fbba96 100644 --- a/sys/alpha/alpha/sys_machdep.c +++ b/sys/alpha/alpha/sys_machdep.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)sys_machdep.c 5.5 (Berkeley) 1/19/91 - * $Id: sys_machdep.c,v 1.1 1998/06/10 10:53:27 dfr Exp $ + * $Id: sys_machdep.c,v 1.2 1998/11/15 18:25:15 dfr Exp $ * */ @@ -54,6 +54,8 @@ #include /* for kernel_map */ +#include + #ifndef _SYS_SYSPROTO_H_ struct sysarch_args { int op; @@ -62,6 +64,8 @@ struct sysarch_args { #endif static int alpha_sethae(struct proc *p, char *args); +static int alpha_get_fpmask(struct proc *p, char *args); +static int alpha_set_fpmask(struct proc *p, char *args); int sysarch(p, uap) @@ -74,6 +78,12 @@ sysarch(p, uap) case ALPHA_SETHAE: error = alpha_sethae(p, uap->parms); break; + case ALPHA_GET_FPMASK: + error = alpha_get_fpmask(p, uap->parms); + break; + case ALPHA_SET_FPMASK: + error = alpha_set_fpmask(p, uap->parms); + break; default: error = EINVAL; @@ -106,3 +116,38 @@ alpha_sethae(struct proc *p, char *args) return (0); } + +struct alpha_fpmask_args { + u_int64_t mask; +}; + +static int +alpha_get_fpmask(struct proc *p, char *args) +{ + int error; + struct alpha_fpmask_args ua; + + ua.mask = p->p_addr->u_pcb.pcb_fp_control; + error = copyout(&ua, args, sizeof(struct alpha_fpmask_args)); + + return (error); +} + +static int +alpha_set_fpmask(struct proc *p, char *args) +{ + int error; + u_int64_t oldmask, *fp_control; + struct alpha_fpmask_args ua; + + if (error = copyin(args, &ua, sizeof(struct alpha_fpmask_args))) + return (error); + + fp_control = &p->p_addr->u_pcb.pcb_fp_control; + oldmask = *fp_control; + *fp_control = ua.mask & IEEE_TRAP_ENABLE_MASK; + ua.mask = oldmask; + + error = copyout(&ua, args, sizeof(struct alpha_fpmask_args)); + return (error); +} diff --git a/sys/alpha/include/alpha_cpu.h b/sys/alpha/include/alpha_cpu.h index 5107274ff18b..4bd105066045 100644 --- a/sys/alpha/include/alpha_cpu.h +++ b/sys/alpha/include/alpha_cpu.h @@ -1,4 +1,4 @@ -/* $Id: alpha_cpu.h,v 1.2 1998/06/10 10:54:21 dfr Exp $ */ +/* $Id: alpha_cpu.h,v 1.3 1998/06/14 13:45:10 dfr Exp $ */ /* From: NetBSD: alpha_cpu.h,v 1.15 1997/09/20 19:02:34 mjacob Exp */ /* @@ -273,8 +273,10 @@ typedef unsigned long alpha_pt_entry_t; */ #define ALPHA_AMASK_BWX 0x0001 /* byte/word extension */ -#define ALPHA_AMASK_CIX 0x0002 /* count extension */ -#define ALPHA_AMASK_MAX 0x0100 /* multimedia extension */ +#define ALPHA_AMASK_FIX 0x0002 /* sqrt and f <-> i conversion extension */ +#define ALPHA_AMASK_CIX 0x0004 /* count extension */ +#define ALPHA_AMASK_MVI 0x0100 /* multimedia extension */ +#define ALPHA_AMASK_PRECISE 0x0200 /* Precise arithmetic traps */ /* * Chip family IDs returned by implver instruction diff --git a/sys/alpha/include/fpu.h b/sys/alpha/include/fpu.h index d4a767e66ebd..c9efceed0293 100644 --- a/sys/alpha/include/fpu.h +++ b/sys/alpha/include/fpu.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: fpu.h,v 1.1 1998/12/04 10:52:48 dfr Exp $ */ #ifndef _MACHINE_FPU_H_ @@ -105,6 +105,16 @@ #define IEEE_INHERIT (1LL << 63) /* inherit on fork */ +/* read and write floating point control register */ +#define GET_FPCR(x) \ + __asm__("trapb"); \ + __asm__("mf_fpcr %0" : "=f" (x)); \ + __asm__("trapb") +#define SET_FPCR(x) \ + __asm__("trapb"); \ + __asm__("mt_fpcr %0" : : "f" (x)); \ + __asm__("trapb") + #ifdef KERNEL extern int fp_software_completion(u_int64_t regmask, struct proc *p); diff --git a/sys/alpha/include/ieeefp.h b/sys/alpha/include/ieeefp.h index c0f4c2f4035c..a838e9891955 100644 --- a/sys/alpha/include/ieeefp.h +++ b/sys/alpha/include/ieeefp.h @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $Id: ieeefp.h,v 1.1.1.1 1998/03/09 05:43:16 jb Exp $ */ /* From: NetBSD: ieeefp.h,v 1.2 1997/04/06 08:47:28 cgd Exp */ /* @@ -10,12 +10,14 @@ #define _ALPHA_IEEEFP_H_ typedef int fp_except; -#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_INV (1LL << 1) /* invalid operation exception */ +#define FP_X_DZ (1LL << 2) /* divide-by-zero exception */ +#define FP_X_OFL (1LL << 3) /* overflow exception */ +#define FP_X_UFL (1LL << 4) /* underflow exception */ +#define FP_X_IMP (1LL << 5) /* imprecise(inexact) exception */ +#if 0 +#define FP_X_IOV (1LL << 6) /* integer overflow XXX? */ +#endif typedef enum { FP_RZ=0, /* round to zero (truncate) */ diff --git a/sys/alpha/include/sysarch.h b/sys/alpha/include/sysarch.h index 61806f80e1c0..e0e0a6b9b617 100644 --- a/sys/alpha/include/sysarch.h +++ b/sys/alpha/include/sysarch.h @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: sysarch.h,v 1.1 1998/11/17 10:40:07 dfr Exp $ */ /* @@ -39,7 +39,9 @@ #ifndef _MACHINE_SYSARCH_H_ #define _MACHINE_SYSARCH_H_ -#define ALPHA_SETHAE 0 +#define ALPHA_SETHAE 0 +#define ALPHA_GET_FPMASK 1 +#define ALPHA_SET_FPMASK 2 #ifndef KERNEL #include