From: ceriel Date: Tue, 25 Jul 1989 14:21:09 +0000 (+0000) Subject: many changes, to use IEEE format X-Git-Tag: release-5-5~2325 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=f7360f0fec6e8b77940e37566c34532af288e686;p=ack.git many changes, to use IEEE format --- diff --git a/mach/proto/fp/FP_bias.h b/mach/proto/fp/FP_bias.h index fae2987ef..db17a4132 100644 --- a/mach/proto/fp/FP_bias.h +++ b/mach/proto/fp/FP_bias.h @@ -9,7 +9,6 @@ include file for floating point package */ -#ifdef IEEEFORMAT /* FLOAT FORMAT EXPONENT BIAS */ #define SGL_BIAS 127 /* excess 128 notation used */ @@ -21,29 +20,9 @@ /* VARIOUS MAX AND MIN VALUES */ /* 1) FOR THE DIFFERENT FORMATS */ -#define SGL_MAX 255 /* standard definition */ +#define SGL_MAX 254 /* standard definition */ #define SGL_MIN 1 /* standard definition */ -#define DBL_MAX 2047 /* standard definition */ +#define DBL_MAX 2046 /* standard definition */ #define DBL_MIN 1 /* standard definition */ -#define EXT_MAX 16384 /* standard minimum */ -#define EXT_MIN -16383 /* standard minimum */ -#else - - /* FLOAT FORMAT EXPONENT BIAS */ - -#define SGL_BIAS 127 /* excess 128 notation used */ -#define DBL_BIAS 127 /* excess 128 notation used */ -#define EXT_BIAS 0 /* 2s-complement notation used */ - /* this is possible because the */ - /* sign is in a seperate word */ - - /* VARIOUS MAX AND MIN VALUES */ - /* 1) FOR THE DIFFERENT FORMATS */ - -#define SGL_MAX 255 /* standard definition */ -#define SGL_MIN 1 /* standard definition */ -#define DBL_MAX 255 /* standard definition */ -#define DBL_MIN 1 /* standard definition */ -#define EXT_MAX 16384 /* standard minimum */ -#define EXT_MIN -16383 /* standard minimum */ -#endif +#define EXT_MAX 16383 /* standard minimum */ +#define EXT_MIN -16382 /* standard minimum */ diff --git a/mach/proto/fp/FP_shift.h b/mach/proto/fp/FP_shift.h index f713b881e..5b685636f 100644 --- a/mach/proto/fp/FP_shift.h +++ b/mach/proto/fp/FP_shift.h @@ -26,32 +26,13 @@ #define SGL_MASK 0x007fffffL /* parameters for Double Precision */ -#ifndef IEEEFORMAT - -#define DBL_EXPSHIFT SGL_EXPSHIFT -#define DBL_M1LEFT SGL_M1LEFT - -#define DBL_LPACK DBL_RUNPACK -#define DBL_RPACK DBL_LUNPACK - -#define DBL_ZERO SGL_ZERO -#define DBL_EXACT SGL_EXACT - -#define DBL_RUNPACK DBL_M1LEFT -#define DBL_LUNPACK 32-DBL_M1LEFT - -#define DBL_ROUNDUP SGL_ROUNDUP -#define DBL_CARRYOUT SGL_CARRYOUT -#define DBL_MASK SGL_MASK - -#else /* used in extend.c */ #define DBL_EXPSHIFT 4 #define DBL_M1LEFT 11 -#define DBL_RPACK 32-DBL_M1LEFT +#define DBL_RPACK (32-DBL_M1LEFT) #define DBL_LPACK DBL_M1LEFT /* used in compact.c */ @@ -61,10 +42,8 @@ #define DBL_EXACT 0x7ff #define DBL_RUNPACK DBL_M1LEFT -#define DBL_LUNPACK 32-DBL_RUNPACK +#define DBL_LUNPACK (32-DBL_RUNPACK) #define DBL_ROUNDUP 0x400 #define DBL_CARRYOUT 0x00200000L #define DBL_MASK 0x000fffffL - -#endif IEEEFORMAT diff --git a/mach/proto/fp/Makefile b/mach/proto/fp/Makefile index d8ae5cc3d..b83adde88 100644 --- a/mach/proto/fp/Makefile +++ b/mach/proto/fp/Makefile @@ -8,47 +8,43 @@ CFLAGS= # # $Header$ # -# various flags that can be used during compilation -# define DEBUG -# define PRT_ADD -# define PRT_ALL -# define PRT_DBL -# define PRT_ENTRY -# define PRT_EXIT -# define PRT_EXT -# define PRT_EXT2 -# define PRT_LONG -# define PRT_RNDMSG -# define PRT_STDERR -# define PRT_TRAP -# -# DFLAGS=-DPRT_ADD -DPRT_ALL -DPRT_DBL -DPRT_ENTRY -DPRT_EXIT -DPRT_EXT -DPRT_EXT2 -DPRT_LONG -DPRT_RNDMSG -DPRT_STDERR -DPRT_TRAP -DFLAGS= -EMFLAGS= -L -LIB -I. $(DFLAGS) -O $(CFLAGS) +EMFLAGS= -L -LIB -I. -O $(CFLAGS) # AS=ack -m$(MACH) -c.$(SUF) # CC=ack -m$(MACH) -c.s # CCFLAGS=$(EMFLAGS) CDIR=$(EMHOME)/mach/proto/fp -LIST = cff4.$(SUF) cff8.$(SUF) cfu.$(SUF) cmf4.$(SUF) cmf8.$(SUF)\ +LIST = cff4.$(SUF) cff8.$(SUF)\ + cfu.$(SUF)\ + cmf4.$(SUF) cmf8.$(SUF)\ cuf4.$(SUF) cuf8.$(SUF)\ - dvf4.$(SUF) dvf8.$(SUF) fef4.$(SUF) fef8.$(SUF)\ + dvf4.$(SUF) dvf8.$(SUF)\ + fef4.$(SUF) fef8.$(SUF)\ fif4.$(SUF) fif8.$(SUF)\ - cfi.$(SUF) cif4.$(SUF) cif8.$(SUF) mlf4.$(SUF) mlf8.$(SUF)\ - ngf4.$(SUF)\ - ngf8.$(SUF) sbf4.$(SUF) sbf8.$(SUF) adf4.$(SUF) adf8.$(SUF)\ + cfi.$(SUF)\ + cif4.$(SUF) cif8.$(SUF)\ + mlf4.$(SUF) mlf8.$(SUF)\ + ngf4.$(SUF) ngf8.$(SUF)\ + sbf4.$(SUF) sbf8.$(SUF)\ + adf4.$(SUF) adf8.$(SUF)\ zrf4.$(SUF) zrf8.$(SUF)\ extend.$(SUF) compact.$(SUF)\ add_ext.$(SUF) div_ext.$(SUF) mul_ext.$(SUF) nrm_ext.$(SUF)\ sft_ext.$(SUF) sub_ext.$(SUF) zrf_ext.$(SUF)\ adder.$(SUF) shifter.$(SUF) fptrp.$(SUF) -SLIST = cff4.s cff8.s cfu.s cmf4.s cmf8.s\ +SLIST = cff4.s cff8.s\ + cfu.s\ + cmf4.s cmf8.s\ cuf4.s cuf8.s\ - dvf4.s dvf8.s fef4.s fef8.s\ + dvf4.s dvf8.s\ + fef4.s fef8.s\ fif4.s fif8.s\ - cfi.s cif4.s cif8.s mlf4.s mlf8.s\ - ngf4.s\ - ngf8.s sbf4.s sbf8.s adf4.s adf8.s\ + cfi.s\ + cif4.s cif8.s\ + mlf4.s mlf8.s\ + ngf4.s ngf8.s\ + sbf4.s sbf8.s\ + adf4.s adf8.s\ zrf4.s zrf8.s\ extend.s compact.s\ add_ext.s div_ext.s mul_ext.s nrm_ext.s\ @@ -56,13 +52,19 @@ SLIST = cff4.s cff8.s cfu.s cmf4.s cmf8.s\ adder.s shifter.s fptrp.s SRC = FP_bias.h FP_shift.h FP_trap.h FP_types.h adder.h get_put.h\ - cff4.c cff8.c cfu.c cmf4.c cmf8.c\ + cff4.c cff8.c\ + cfu.c\ + cmf4.c cmf8.c\ cuf4.c cuf8.c\ - dvf4.c dvf8.c fef4.c fef8.c\ + dvf4.c dvf8.c\ + fef4.c fef8.c\ fif4.c fif8.c\ - cfi.c cif4.c cif8.c mlf4.c mlf8.c\ - ngf4.c\ - ngf8.c sbf4.c sbf8.c adf4.c adf8.c\ + cfi.c\ + cif4.c cif8.c\ + mlf4.c mlf8.c\ + ngf4.c ngf8.c\ + sbf4.c sbf8.c\ + adf4.c adf8.c\ zrf4.c zrf8.c\ extend.c compact.c\ add_ext.c div_ext.c mul_ext.c nrm_ext.c\ diff --git a/mach/proto/fp/add_ext.c b/mach/proto/fp/add_ext.c index 07a55c43d..43f15656e 100644 --- a/mach/proto/fp/add_ext.c +++ b/mach/proto/fp/add_ext.c @@ -27,12 +27,15 @@ register EXTEND *e1,*e2; if (e2->m1 > e1->m1 || (e2->m1 == e1->m1 && e2->m2 > e1->m2)) { /* abs(e2) > abs(e1) */ - if (e1->m2 > e2->m2) { - e2->m1 -= 1; /* carry in */ + EXTEND x; + + x = *e1; + *e1 = *e2; + if (x.m2 > e1->m2) { + e1->m1 -= 1; /* carry in */ } - e2->m1 -= e1->m1; - e2->m2 -= e1->m2; - *e1 = *e2; + e1->m1 -= x.m1; + e1->m2 -= x.m2; } else { if (e2->m2 > e1->m2) diff --git a/mach/proto/fp/adf4.c b/mach/proto/fp/adf4.c index cb07cf452..c59b67399 100644 --- a/mach/proto/fp/adf4.c +++ b/mach/proto/fp/adf4.c @@ -29,5 +29,5 @@ _float s1,s2; extend((_double *)&s2,&e2,sizeof(SINGLE)); add_ext(&e1,&e2); compact(&e1,(_double *)&s1,sizeof(SINGLE)); - return(s1); + return s1; } diff --git a/mach/proto/fp/adf8.c b/mach/proto/fp/adf8.c index 540be95a3..6519f844c 100644 --- a/mach/proto/fp/adf8.c +++ b/mach/proto/fp/adf8.c @@ -29,5 +29,5 @@ _double s1,s2; extend(&s2,&e2,sizeof(_double)); add_ext(&e1,&e2); compact(&e1,&s1,sizeof(_double)); - return(s1); + return s1; } diff --git a/mach/proto/fp/cff4.c b/mach/proto/fp/cff4.c index d30a10509..d82ba6a72 100644 --- a/mach/proto/fp/cff4.c +++ b/mach/proto/fp/cff4.c @@ -17,6 +17,7 @@ #include "FP_types.h" +_float cff4(src) _double src; /* the source itself - THIS TIME it's DOUBLE */ { @@ -24,4 +25,5 @@ _double src; /* the source itself - THIS TIME it's DOUBLE */ extend(&src,&buf,8); /* no matter what */ compact(&buf,(_double *) &(src.__double[1]),4); + return *(_float *)&(src.__double[1]); } diff --git a/mach/proto/fp/cff8.c b/mach/proto/fp/cff8.c index 737d0346f..4e59d7802 100644 --- a/mach/proto/fp/cff8.c +++ b/mach/proto/fp/cff8.c @@ -17,11 +17,13 @@ #include "FP_types.h" +_double cff8(src) -_float src; /* the space on the stack is for a double - see cg/table */ +_float src; { EXTEND buf; extend((_double *) &src,&buf,4); /* no matter what */ - compact(&buf,&src,8); + compact(&buf,(_double *) &src,8); + return *(_double *) &src; } diff --git a/mach/proto/fp/cfi.c b/mach/proto/fp/cfi.c index 18a9c46f4..12d6cde51 100644 --- a/mach/proto/fp/cfi.c +++ b/mach/proto/fp/cfi.c @@ -15,6 +15,7 @@ #include "FP_trap.h" #include "FP_types.h" +#include "FP_shift.h" long cfi(ds,ss,src) @@ -24,21 +25,25 @@ _double src; /* assume worst case */ { EXTEND buf; long new; - short newint, max_exp; + short max_exp; extend(&src,&buf,ss); /* get extended format */ - buf.exp--; /* additional bias correction */ - if (buf.exp < 1) { /* no conversion needed */ + if (buf.exp < 0) { /* no conversion needed */ src.__double[ss == 8] = 0L; return(0L); } - max_exp = (ds << 3) - 1; /* signed numbers */ + max_exp = (ds << 3) - 2; /* signed numbers */ /* have more limited max_exp */ if (buf.exp > max_exp) { - trap(EIOVFL); /* integer overflow */ - buf.exp %= max_exp; /* truncate */ + if (buf.exp == max_exp+1 && buf.sign && buf.m1 == NORMBIT && + buf.m2 == 0L) { + } + else { + trap(EIOVFL); /* integer overflow */ + buf.exp %= max_exp; /* truncate */ + } } - new = buf.m1 >> (32-buf.exp); + new = buf.m1 >> (31-buf.exp); if (buf.sign) new = -new; done: diff --git a/mach/proto/fp/cfu.c b/mach/proto/fp/cfu.c index 8cb2bc8a7..ba36fa33d 100644 --- a/mach/proto/fp/cfu.c +++ b/mach/proto/fp/cfu.c @@ -27,17 +27,16 @@ _double src; /* assume worst case */ short newint, max_exp; extend(&src,&buf,ss); /* get extended format */ - buf.exp--; /* additional bias correction */ - if (buf.exp < 1) { /* no conversion needed */ + if (buf.exp < 0) { /* no conversion needed */ src.__double[ss == 8] = 0L; return(0L); } - max_exp = (ds << 3); + max_exp = (ds << 3) - 1; if (buf.exp > max_exp) { trap(EIOVFL); /* integer overflow */ buf.exp %= max_exp; } - new = buf.m1 >> (32-buf.exp); + new = buf.m1 >> (31-buf.exp); done: src.__double[ss == 8] = new; return(new); diff --git a/mach/proto/fp/cif4.c b/mach/proto/fp/cif4.c index cec5c9c81..19d78c546 100644 --- a/mach/proto/fp/cif4.c +++ b/mach/proto/fp/cif4.c @@ -28,14 +28,14 @@ long src; /* largest possible integer to convert */ zrf_ext(&buf); if (ss == sizeof(long)) { - buf.exp = 33; + buf.exp = 31; i_src = src; result = (_float *) &src; } else { ipt = (short *) &src; i_src = (long) *ipt; - buf.exp = 17; + buf.exp = 15; result = (_float *) &ss; } if (i_src == 0) { diff --git a/mach/proto/fp/cif8.c b/mach/proto/fp/cif8.c index 374ae823f..545e17dae 100644 --- a/mach/proto/fp/cif8.c +++ b/mach/proto/fp/cif8.c @@ -29,13 +29,13 @@ long src; /* largest possible integer to convert */ result = (_double *) &ss; /* always */ zrf_ext(&buf); if (ss == sizeof(long)) { - buf.exp = 33; + buf.exp = 31; i_src = src; } else { ipt = (short *) &src; i_src = (long) *ipt; - buf.exp = 17; + buf.exp = 15; } if (i_src == 0) { zrf8(result); diff --git a/mach/proto/fp/cmf4.c b/mach/proto/fp/cmf4.c index b04ca6b30..0611e332b 100644 --- a/mach/proto/fp/cmf4.c +++ b/mach/proto/fp/cmf4.c @@ -12,6 +12,7 @@ #include "FP_types.h" #include "get_put.h" +int cmf4(f1,f2) _float f1,f2; { diff --git a/mach/proto/fp/cmf8.c b/mach/proto/fp/cmf8.c index 85b563966..8fa51c53d 100644 --- a/mach/proto/fp/cmf8.c +++ b/mach/proto/fp/cmf8.c @@ -34,14 +34,13 @@ _double d1,d2; rv = l1 < l2 ? 1 : -1; } else { /* decide in 2nd half */ - l1 = get4(((char *)&d1 + 4)); - l2 = get4(((char *)&d2 + 4)); - if (l1 == l2) + unsigned long u1, u2; + u1 = get4(((char *)&d1 + 4)); + u2 = get4(((char *)&d2 + 4)); + if (u1 == u2) return(0); - if (l1 >= 0) - rv = l1 < l2 || l2 < 0 ? 1 : -1; - else if (l2 >= 0) rv = -1; - else rv = l1 < l2 ? 1 : -1; + if (u1 < u2) rv = 1; + else rv = -1; } return sign1 * rv; } diff --git a/mach/proto/fp/compact.c b/mach/proto/fp/compact.c index ffc42f29e..34b8fd579 100644 --- a/mach/proto/fp/compact.c +++ b/mach/proto/fp/compact.c @@ -35,18 +35,19 @@ int size; f->exp += DBL_BIAS; /* restore proper bias */ if (f->exp > DBL_MAX) { dbl_over: trap(EFOVFL); - f->exp = DBL_MAX; - f->m1 = 0xffffffffL; - f->m2 = DBL_ZERO; + f->exp = DBL_MAX+1; + f->m1 = 0; + f->m2 = 0; if (error++) return; } else if (f->exp < DBL_MIN) { - trap(EFUNFL); - f->exp = DBL_MIN; - f->m1 = f->m2 = 0L; - if (error++) - return; + b64_rsft(&(f->m1)); + if (f->exp < 0) { + b64_sft(&(f->m1), -f->exp); + f->exp = 0; + } + /* underflow ??? */ } /* local CAST conversion */ @@ -121,18 +122,19 @@ dbl_over: trap(EFOVFL); f->exp += SGL_BIAS; /* restore bias */ if (f->exp > SGL_MAX) { sgl_over: trap(EFOVFL); - f->exp = SGL_MAX; - f->m1 = SGL_ZERO; + f->exp = SGL_MAX+1; + f->m1 = 0L; f->m2 = 0L; if (error++) return; } else if (f->exp < SGL_MIN) { - trap(EFUNFL); - f->exp = SGL_MIN; - f->m1 = f->m2 = 0L; - if (error++) - return; + b64_rsft(&(f->m1)); + if (f->exp < 0) { + b64_sft(&(f->m1), -f->exp); + f->exp = 0; + } + /* underflow ??? */ } /* shift mantissa and store */ diff --git a/mach/proto/fp/cuf4.c b/mach/proto/fp/cuf4.c index 891ac169d..a83d10126 100644 --- a/mach/proto/fp/cuf4.c +++ b/mach/proto/fp/cuf4.c @@ -28,14 +28,14 @@ long src; /* largest possible integer to convert */ zrf_ext(&buf); if (ss == sizeof(long)) { - buf.exp = 33; + buf.exp = 31; i_src = src; result = (_float *) &src; } else { ipt = (short *) &src; i_src = (long) *ipt; - buf.exp = 17; + buf.exp = 15; result = (_float *) &ss; } if (i_src == 0) { diff --git a/mach/proto/fp/cuf8.c b/mach/proto/fp/cuf8.c index 619ab5e2e..d4da6b997 100644 --- a/mach/proto/fp/cuf8.c +++ b/mach/proto/fp/cuf8.c @@ -16,6 +16,7 @@ #include "FP_types.h" +_double cuf8(ss,src) int ss; /* source size */ long src; /* largest possible integer to convert */ @@ -26,13 +27,13 @@ long src; /* largest possible integer to convert */ zrf_ext(&buf); if (ss == sizeof(long)) { - buf.exp = 33; + buf.exp = 31; i_src = src; } else { ipt = (short *) &src; i_src = (long) *ipt; - buf.exp = 17; + buf.exp = 15; } if (i_src == 0) { zrf8(&ss); @@ -50,4 +51,5 @@ long src; /* largest possible integer to convert */ /* adjust mantissa field */ nrm_ext(&buf); compact(&buf,(_double *) &ss,8); + return *((_double *) &ss); } diff --git a/mach/proto/fp/div_ext.c b/mach/proto/fp/div_ext.c index c58be1781..9f135c6b5 100644 --- a/mach/proto/fp/div_ext.c +++ b/mach/proto/fp/div_ext.c @@ -68,25 +68,6 @@ EXTEND *e1,*e2; /* check for underflow, divide by zero, etc */ e1->sign ^= e2->sign; e1->exp -= e2->exp; - e1->exp += 2; /* bias correction */ - if (e1->exp < EXT_MIN) { - /* - * Exception 8.4 - Underflow - */ - trap(EFUNFL); /* underflow */ - e1->exp = EXT_MIN; - e1->m1 = e1->m2 = 0L; - return; - } - if (e1->exp >= EXT_MAX) { - /* - * Exception 8.3 - Overflow - */ - trap(EFOVFL); /* overflow */ - e1->exp = EXT_MAX; - e1->m1 = e1->m2 = 0L; - return; - } #ifndef USE_DIVIDE /* do division of mantissas */ @@ -264,4 +245,22 @@ EXTEND *e1,*e2; e1->m2 = result[1]; nrm_ext(e1); + if (e1->exp < EXT_MIN) { + /* + * Exception 8.4 - Underflow + */ + trap(EFUNFL); /* underflow */ + e1->exp = EXT_MIN; + e1->m1 = e1->m2 = 0L; + return; + } + if (e1->exp >= EXT_MAX) { + /* + * Exception 8.3 - Overflow + */ + trap(EFOVFL); /* overflow */ + e1->exp = EXT_MAX; + e1->m1 = e1->m2 = 0L; + return; + } } diff --git a/mach/proto/fp/dvf4.c b/mach/proto/fp/dvf4.c index 0c11e61e5..9569d42a3 100644 --- a/mach/proto/fp/dvf4.c +++ b/mach/proto/fp/dvf4.c @@ -11,6 +11,7 @@ #include "FP_types.h" +_float dvf4(s2,s1) _float s1,s2; { @@ -22,4 +23,5 @@ _float s1,s2; /* do a divide */ div_ext(&e1,&e2); compact(&e1,(_double *)&s1,sizeof(_float)); + return s1; } diff --git a/mach/proto/fp/dvf8.c b/mach/proto/fp/dvf8.c index 0a40c075e..4891796e9 100644 --- a/mach/proto/fp/dvf8.c +++ b/mach/proto/fp/dvf8.c @@ -11,6 +11,7 @@ #include "FP_types.h" +_double dvf8(s2,s1) _double s1,s2; { @@ -22,4 +23,5 @@ _double s1,s2; /* do a divide */ div_ext(&e1,&e2); compact(&e1,&s1,sizeof(_double)); + return s1; } diff --git a/mach/proto/fp/extend.c b/mach/proto/fp/extend.c index 9f1a40bd6..84e1559fc 100644 --- a/mach/proto/fp/extend.c +++ b/mach/proto/fp/extend.c @@ -80,6 +80,8 @@ zero: zrf_ext(to); } to->m1 |= NORMBIT; /* set bit L */ - if (leadbit == 0) /* set or clear Leading Bit */ + if (leadbit == 0) { /* set or clear Leading Bit */ to->m1 &= ~NORMBIT; /* clear bit L */ + nrm_ext(to); /* and normalize */ + } } diff --git a/mach/proto/fp/fef4.c b/mach/proto/fp/fef4.c index 6552ed584..b781507b8 100644 --- a/mach/proto/fp/fef4.c +++ b/mach/proto/fp/fef4.c @@ -16,14 +16,17 @@ struct fef4_returns { _float f; }; -fef4(s1) +fef4(r,s1) _float s1; +struct fef4_returns *r; { - struct fef4_returns *r = (struct fef4_returns *) &s1; EXTEND buf; + register struct fef4_returns *p = r; /* make copy; r might refer + to itself (see table) + */ extend((_double *) &s1,&buf,sizeof(_float)); - r->e = buf.exp-1; - buf.exp = 1; - compact(&buf,(_double *) &r->f,sizeof(_float)); + p->e = buf.exp+1; + buf.exp = -1; + compact(&buf,(_double *) &p->f,sizeof(_float)); } diff --git a/mach/proto/fp/fef8.c b/mach/proto/fp/fef8.c index f4d7da861..e261411ba 100644 --- a/mach/proto/fp/fef8.c +++ b/mach/proto/fp/fef8.c @@ -16,14 +16,17 @@ struct fef8_returns { _double f; }; -fef8(s1) +fef8(r, s1) _double s1; +struct fef8_returns *r; { EXTEND buf; - struct fef8_returns *r = (struct fef8_returns *) &s1; + register struct fef8_returns *p = r; /* make copy, r might refer + to itself (see table) + */ extend(&s1,&buf,sizeof(_double)); - r->e = buf.exp - 1; - buf.exp = 1; - compact(&buf,&r->f,sizeof(_double)); + p->e = buf.exp + 1; + buf.exp = -1; + compact(&buf,&p->f,sizeof(_double)); } diff --git a/mach/proto/fp/fif4.c b/mach/proto/fp/fif4.c index 1142dbb73..aa8a3d12f 100644 --- a/mach/proto/fp/fif4.c +++ b/mach/proto/fp/fif4.c @@ -14,8 +14,14 @@ _float sbf4(); -fif4(x,y) +struct fif4_returns { + _float ipart; + _float fpart; +}; + +fif4(p,x,y) _float x,y; +struct fif4_returns *p; { EXTEND e1,e2; @@ -26,19 +32,18 @@ _float x,y; mul_ext(&e1,&e2); e2 = e1; compact(&e2, (_double *)&y, sizeof(_float)); - e1.exp--; /* additional bias correction */ - if (e1.exp < 1) { - x = 0; + if (e1.exp < 0) { + p->ipart = 0; + p->fpart = y; return; } - if (e1.exp > 31 - SGL_M1LEFT) { - x = y; - y = 0; + if (e1.exp > 30 - SGL_M1LEFT) { + p->ipart = y; + p->fpart = 0; return; } b64_sft(&e1.m1, 64 - e1.exp); b64_sft(&e1.m1, e1.exp - 64); /* "loose" low order bits */ - e1.exp++; - compact(&e1,(_double *) &x, sizeof(SINGLE)); - y = sbf4(x, y); + compact(&e1,(_double *) &(p->ipart), sizeof(SINGLE)); + p->fpart = sbf4(p->ipart, y); } diff --git a/mach/proto/fp/fif8.c b/mach/proto/fp/fif8.c index 6a938cc2e..40ed77534 100644 --- a/mach/proto/fp/fif8.c +++ b/mach/proto/fp/fif8.c @@ -14,8 +14,14 @@ _double sbf8(); -fif8(x,y) +struct fif8_returns { + _double ipart; + _double fpart; +}; + +fif8(p,x,y) _double x,y; +struct fif8_returns *p; { EXTEND e1,e2; @@ -26,22 +32,20 @@ _double x,y; mul_ext(&e1,&e2); e2 = e1; compact(&e2, &y, sizeof(_double)); - e1.exp--; /* additional bias correction */ - if (e1.exp < 1) { - x.__double[0] = 0; - x.__double[1] = 0; + if (e1.exp < 0) { + p->ipart.__double[0] = 0; + p->ipart.__double[1] = 0; + p->fpart = y; return; } - if (e1.exp > 63 - DBL_M1LEFT) { - x.__double[0] = y.__double[0]; - x.__double[1] = y.__double[1]; - y.__double[0] = 0; - y.__double[1] = 0; + if (e1.exp > 62 - DBL_M1LEFT) { + p->ipart = y; + p->fpart.__double[0] = 0; + p->fpart.__double[1] = 0; return; } b64_sft(&e1.m1, 64 - e1.exp); b64_sft(&e1.m1, e1.exp - 64); /* "loose" low order bits */ - e1.exp++; - compact(&e1, &x, sizeof(DOUBLE)); - y = sbf8(x, y); + compact(&e1, &(p->ipart), sizeof(DOUBLE)); + p->fpart = sbf8(p->ipart, y); } diff --git a/mach/proto/fp/mul_ext.c b/mach/proto/fp/mul_ext.c index 3d30ffcd1..9a5d507a4 100644 --- a/mach/proto/fp/mul_ext.c +++ b/mach/proto/fp/mul_ext.c @@ -13,69 +13,22 @@ # include "FP_bias.h" # include "FP_trap.h" # include "FP_types.h" +# include "FP_shift.h" mul_ext(e1,e2) EXTEND *e1,*e2; { register int i,j; /* loop control */ - short unsigned mp[4]; /* multiplier */ - short unsigned mc[4]; /* multipcand */ - short unsigned result[8]; /* result */ - B64 tmp64; + unsigned short mp[4]; /* multiplier */ + unsigned short mc[4]; /* multipcand */ + unsigned short result[8]; /* result */ register unsigned short *pres; /* first save the sign (XOR) */ - e1->sign ^= e2->sign; - /********************************************************/ - /* INCREASE EXPONENT BY ONE (1) */ - /* */ - /* the nature of the multiplication algorithm used */ - /* results in an exponent that is small by an additive */ - /* factor of one (1); */ - /* if the maximum bit is set it will not be subtracted */ - /* during normalization -> this is correct and can be */ - /* expected often with normalized numbers */ - /* HOWEVER, it is also possible that unnormalized */ - /* numbers are used. Rather than shifting here */ - /* always(!) (unless L bit is set) I chose to */ - /* increase the exponent by one - a simple (FAST) */ - /* process - and to decrease it later during */ - /* normalization. */ - /* */ - /********************************************************/ - /* The effects of bias (as used here) */ - /* and the multiplication algorithm used cancel */ - /* so these statements are commented out */ - /* August 1985 - if changing the Leading Bit (or NORMBIT) */ - /* this problem with the multiplication algorithm no longer */ - /* exists - bias must be subtracted now */ - /* */ - /* e1->exp++; */ - /********************************************************/ - - /* next add the exponents */ - - e1->exp += e2->exp; - e1->exp -= 1; /* correction for bias */ - - /* check for overflow */ - if (e1->exp >= EXT_MAX) { - trap(EFOVFL); - /* if caught */ - /* return signed infinity */ - e1->exp = EXT_MAX; -infinity: e1->m1 = e1->m2 =0L; - return; - } - /* check for underflow */ - if (e1->exp < EXT_MIN) { - trap(EFUNFL); - e1->exp = EXT_MIN; - goto infinity; - } - + /* compute new exponent */ + e1->exp += e2->exp + 1; /* 128 bit multiply of mantissas */ /* assign unknown long formats */ @@ -105,7 +58,15 @@ infinity: e1->m1 = e1->m2 =0L; } pres[-1] = k; } - + if (! (result[0] & 0x8000)) { + e1->exp--; + for (i = 0; i <= 3; i++) { + result[i] <<= 1; + if (result[i+1]&0x8000) result[i] |= 1; + } + result[4] <<= 1; + } + /* * combine the registers to a total */ @@ -113,8 +74,25 @@ infinity: e1->m1 = e1->m2 =0L; e1->m2 = ((unsigned long)(result[2]) << 16) + result[3]; if (result[4] & 0x8000) { if (++e1->m2 == 0) - e1->m1++; + if (++e1->m1 == 0) { + e1->m1 = NORMBIT; + e1->exp++; + } } - nrm_ext(e1); + /* check for overflow */ + if (e1->exp >= EXT_MAX) { + trap(EFOVFL); + /* if caught */ + /* return signed infinity */ + e1->exp = EXT_MAX; +infinity: e1->m1 = e1->m2 =0L; + return; + } + /* check for underflow */ + if (e1->exp < EXT_MIN) { + trap(EFUNFL); + e1->exp = EXT_MIN; + goto infinity; + } } diff --git a/mach/proto/fp/ngf4.c b/mach/proto/fp/ngf4.c index 2ef0abaa6..f8633eb83 100644 --- a/mach/proto/fp/ngf4.c +++ b/mach/proto/fp/ngf4.c @@ -16,13 +16,15 @@ #include "FP_types.h" +_float ngf4(f) _float f; { - char unsigned *p; + unsigned char *p; if (f != (_float) 0) { - p = (char unsigned *) &f; + p = (unsigned char *) &f; *p ^= 0x80; } + return f; } diff --git a/mach/proto/fp/ngf8.c b/mach/proto/fp/ngf8.c index d014d39fa..91aa46f4c 100644 --- a/mach/proto/fp/ngf8.c +++ b/mach/proto/fp/ngf8.c @@ -16,6 +16,7 @@ #include "FP_types.h" +_double ngf8(f) _double f; { @@ -25,5 +26,5 @@ _double f; p = (unsigned char *) &f; *p ^= 0x80; } + return f; } - diff --git a/mach/proto/fp/sbf4.c b/mach/proto/fp/sbf4.c index 844880ecf..e6a3aa484 100644 --- a/mach/proto/fp/sbf4.c +++ b/mach/proto/fp/sbf4.c @@ -17,16 +17,13 @@ _float sbf4(s2,s1) _float s1,s2; { - /* changing the sign directly */ - /* is faster than the code: */ - /* s2 = -s2 */ - char unsigned *p; + unsigned char *p; _float *result = &s1; /* s1 may not be in a register! */ if (s2 == (_float) 0) { return s1; } - p = (char unsigned *) &s2; + p = (unsigned char *) &s2; *p ^= 0x80; /* change sign of s2 */ *result = adf4(s2,s1); return(s1); /* add and return result */ diff --git a/mach/proto/fp/sbf8.c b/mach/proto/fp/sbf8.c index 76d437250..f2b711230 100644 --- a/mach/proto/fp/sbf8.c +++ b/mach/proto/fp/sbf8.c @@ -17,16 +17,13 @@ _double sbf8(s2,s1) _double s1,s2; { - /* changing the sign directly */ - /* is faster than the code line */ - /* s2 = -s2; */ - char unsigned *p; /* sufficient to access sign bit */ + unsigned char *p; /* sufficient to access sign bit */ _double *result = &s1; /* s1 may not be in a register! */ if (s2.__double[0] == 0 && s2.__double[1] == 0) { return s1; } - p = (char unsigned *) &s2; + p = (unsigned char *) &s2; *p ^= 0x80; /* change sign of s2 */ *result = adf8(s2,s1); /* add and return result */ return(s1); diff --git a/mach/proto/fp/sub_ext.c b/mach/proto/fp/sub_ext.c index 4a511a2c8..81e91b8c5 100644 --- a/mach/proto/fp/sub_ext.c +++ b/mach/proto/fp/sub_ext.c @@ -10,6 +10,7 @@ */ #include "FP_types.h" + sub_ext(e1,e2) EXTEND *e1,*e2; { diff --git a/mach/proto/fp/zrf4.c b/mach/proto/fp/zrf4.c index dd78c7a5b..eb02cb785 100644 --- a/mach/proto/fp/zrf4.c +++ b/mach/proto/fp/zrf4.c @@ -9,8 +9,6 @@ return a zero float (ZRF 4) */ -#include "FP_types.h" - zrf4(l) long *l; {