From: ceriel Date: Thu, 7 Apr 1988 10:57:49 +0000 (+0000) Subject: Initial revision X-Git-Tag: release-5-5~3497 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=8a96f95c59ec8ee5d3959c41c7f17a5336218e9e;p=ack.git Initial revision --- diff --git a/mach/proto/fp/.distr b/mach/proto/fp/.distr new file mode 100644 index 000000000..d2e6d4b60 --- /dev/null +++ b/mach/proto/fp/.distr @@ -0,0 +1,48 @@ +FP.script +FP_bias.h +FP_shift.h +FP_trap.h +FP_types.h +Makefile +add_ext.c +adder.c +adder.h +adf4.c +adf8.c +cff4.c +cff8.c +cfi.c +cfu.c +cif4.c +cif8.c +cmf4.c +cmf8.c +compact.c +cuf4.c +cuf8.c +div_ext.c +dvf4.c +dvf8.c +extend.c +fef4.c +fef8.c +fif4.c +fif8.c +fptrp.e +get_put.h +mlf4.c +mlf8.c +mul_ext.c +ngf4.c +ngf8.c +nrm_ext.c +prt_dbl.c +prt_ext.c +sbf4.c +sbf8.c +sft_ext.c +shifter.c +sub_ext.c +zrf4.c +zrf8.c +zrf_ext.c diff --git a/mach/proto/fp/FP.script b/mach/proto/fp/FP.script new file mode 100644 index 000000000..45cb799ee --- /dev/null +++ b/mach/proto/fp/FP.script @@ -0,0 +1,42 @@ +g/_adf4/s//.adf4/g +g/_adf8/s//.adf8/g +g/_cff4/s//.cff4/g +g/_cff8/s//.cff8/g +g/_cfi/s//.cfi/g +g/_cfu/s//.cfu/g +g/_cif4/s//.cif4/g +g/_cif8/s//.cif8/g +g/_cmf4/s//.cmf4/g +g/_cmf8/s//.cmf8/g +g/_cuf4/s//.cuf4/g +g/_cuf8/s//.cuf8/g +g/_dvf4/s//.dvf4/g +g/_dvf8/s//.dvf8/g +g/_fef4/s//.fef4/g +g/_fef8/s//.fef8/g +g/_fif4/s//.fif4/g +g/_fif8/s//.fif8/g +g/_mlf4/s//.mlf4/g +g/_mlf8/s//.mlf8/g +g/_ngf4/s//.ngf4/g +g/_ngf8/s//.ngf8/g +g/_sbf4/s//.sbf4/g +g/_sbf8/s//.sbf8/g +g/_zrf4/s//.zrf4/g +g/_zrf8/s//.zrf8/g +g/_add_ext/s//.add_ext/g +g/_div_ext/s//.div_ext/g +g/_mul_ext/s//.mul_ext/g +g/_nrm_ext/s//.nrm_ext/g +g/_prt_ext/s//.prt_ext/g +g/_sft_ext/s//.sft_ext/g +g/_sub_ext/s//.sub_ext/g +g/_zrf_ext/s//.zrf_ext/g +g/_compact/s//.compact/g +g/_extend/s//.extend/g +g/_load4/s//.load4/g +g/_store4/s//.store4/g +g/_b32_add/s//.b32_add/g +g/_b64_add/s//.b64_add/g +w +q diff --git a/mach/proto/fp/FP_bias.h b/mach/proto/fp/FP_bias.h new file mode 100644 index 000000000..4c1a34a6a --- /dev/null +++ b/mach/proto/fp/FP_bias.h @@ -0,0 +1,42 @@ +/* + include file for floating point package +*/ + +#ifdef IEEEFORMAT + /* FLOAT FORMAT EXPONENT BIAS */ + +#define SGL_BIAS 127 /* excess 128 notation used */ +#define DBL_BIAS 1023 /* excess 1024 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 0 /* standard definition */ +#define DBL_MAX 2047 /* standard definition */ +#define DBL_MIN 0 /* 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 0 /* standard definition */ +#define DBL_MAX 255 /* standard definition */ +#define DBL_MIN 0 /* standard definition */ +#define EXT_MAX 16384 /* standard minimum */ +#define EXT_MIN -16383 /* standard minimum */ +#endif diff --git a/mach/proto/fp/FP_shift.h b/mach/proto/fp/FP_shift.h new file mode 100644 index 000000000..1d78c406a --- /dev/null +++ b/mach/proto/fp/FP_shift.h @@ -0,0 +1,63 @@ +/* + include file for floating point package +*/ + +# define CARRYBIT 0x80000000L +# define NORMBIT 0x80000000L +# define EXP_STORE 16 + + + /* parameters for Single Precision */ +#define SGL_EXPSHIFT 7 +#define SGL_M1LEFT 8 +#define SGL_ZERO 0xffffff80L +#define SGL_EXACT 0xff +#define SGL_RUNPACK SGL_M1LEFT + +#define SGL_ROUNDUP 0x80 +#define SGL_CARRYOUT 0x01000000L +#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_LPACK DBL_M1LEFT + + /* used in compact.c */ + +#define DBL_ZERO 0xfffffd00L + +#define DBL_EXACT 0x7ff + +#define DBL_RUNPACK DBL_M1LEFT +#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/FP_trap.h b/mach/proto/fp/FP_trap.h new file mode 100644 index 000000000..cd77b7968 --- /dev/null +++ b/mach/proto/fp/FP_trap.h @@ -0,0 +1,15 @@ +/* + include file for floating point package +*/ + + /* EM TRAPS */ + +#define EIOVFL 3 /* Integer Overflow */ +#define EFOVFL 4 /* Floating Overflow */ +#define EFUNFL 5 /* Floating Underflow */ +#define EIDIVZ 6 /* Integer Divide by 0 */ +#define EFDIVZ 7 /* Floating Divide by 0.0 */ +#define EIUND 8 /* Integer Undefined Number */ +#define EFUND 9 /* Floating Undefined Number */ +#define ECONV 10 /* Conversion Error */ +# define trap(x) _fptrp(x) diff --git a/mach/proto/fp/FP_types.h b/mach/proto/fp/FP_types.h new file mode 100644 index 000000000..e02534435 --- /dev/null +++ b/mach/proto/fp/FP_types.h @@ -0,0 +1,53 @@ +/********************************************************/ +/* + include file for floating point package +*/ +/********************************************************/ +/* + THESE STRUCTURES ARE USED TO ADDRESS THE INDIVIDUAL + PARTS OF THE FLOATING NUMBER REPRESENTATIONS. + + THREE STRUCTURES ARE DEFINED: + SINGLE: single precision floating format + DOUBLE: double precision floating format + EXTEND: double precision extended format +*/ +/********************************************************/ +typedef unsigned long _float; + +typedef union { + double _dbl; + unsigned long __double[2]; +} _double; + +typedef union { /* address parts of float */ + /* field to extract exponent */ + short sgl_exp[sizeof(float)/sizeof(short)]; + /* same as fract below */ + _float f[sizeof(float)/sizeof(_float)]; + unsigned long fract; +} SINGLE; + +typedef union { + /* field to extract exponent */ + short dbl_exp[sizeof(double)/sizeof(short)]; + /* for normal syntax use */ + _double _f8[sizeof(double)/sizeof(_double)]; + /* a float in a double - for returns */ + _float _f4[sizeof(double)/sizeof(_float)]; + /* to be deleted eventually */ + struct { /* address parts of float */ + SINGLE p1; /* part one */ + unsigned long p2; /* part two */ + } _s; +} DOUBLE; + +typedef struct { /* expanded float format */ + short sign; + short exp; + unsigned long m1; + unsigned long m2; /* includes guard byte */ +} EXTEND; +#ifdef PRT_EXT +#include +#endif diff --git a/mach/proto/fp/Makefile b/mach/proto/fp/Makefile new file mode 100644 index 000000000..6489695d7 --- /dev/null +++ b/mach/proto/fp/Makefile @@ -0,0 +1,296 @@ +EMHOME=../../.. +SUF=s +MACH=m68k4 +ASAR=arch +CFLAGS=-O +# must use -r option of make so that default rules +# are not loaded +# +# $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) $(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)\ + cuf4.$(SUF) cuf8.$(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)\ + 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)\ + prt_dbl.$(SUF)\ + fptrp.$(SUF) prt_ext.$(SUF) # debugging +SLIST = cff4.s cff8.s cfu.s cmf4.s cmf8.s\ + cuf4.s cuf8.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\ + zrf4.s zrf8.s\ + extend.s compact.s\ + add_ext.s div_ext.s mul_ext.s nrm_ext.s\ + sft_ext.s sub_ext.s zrf_ext.s\ + adder.s shifter.s\ + prt_dbl.s\ + fptrp.s prt_ext.s # debugging + +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\ + cuf4.c cuf8.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\ + zrf4.c zrf8.c\ + extend.c compact.c\ + add_ext.c div_ext.c mul_ext.c nrm_ext.c\ + sft_ext.c sub_ext.c zrf_ext.c\ + adder.c shifter.c\ + prt_dbl.c\ + fptrp.e prt_ext.c + +all: FP_$(MACH).a + +install: tail_fp + +tail_fp: FP_$(MACH).a + ../../install FP_$(MACH).a tail_fp + +clean: + rm -f $(LIST) FP_$(MACH).a + rm -f $(SLIST) + +opr: + make pr | opr + +pr: + @pr Makefile FP.script $(SRC) + +FP_$(MACH).a: $(LIST) + $(ASAR) rv $@ $? + +fptrp.$(SUF): $(CDIR)/fptrp.e + ack -m$(MACH) -L -LIB -c $(CDIR)/fptrp.e + +extend.$(SUF) compact.$(SUF): byte_order.h $(CDIR)/get_put.h + +cff4.$(SUF): $(CDIR)/cff4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cff4.c + ed - cff4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cff4.s + +cff8.$(SUF): $(CDIR)/cff8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cff8.c + ed - cff8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cff8.s + +cfu.$(SUF): $(CDIR)/cfu.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cfu.c + ed - cfu.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cfu.s + +cmf4.$(SUF): $(CDIR)/cmf4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cmf4.c + ed - cmf4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cmf4.s + +cmf8.$(SUF): $(CDIR)/cmf8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cmf8.c + ed - cmf8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cmf8.s + +cuf4.$(SUF): $(CDIR)/cuf4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cuf4.c + ed - cuf4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cuf4.s + +cuf8.$(SUF): $(CDIR)/cuf8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cuf8.c + ed - cuf8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cuf8.s + +dvf4.$(SUF): $(CDIR)/dvf4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/dvf4.c + ed - dvf4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) dvf4.s + +dvf8.$(SUF): $(CDIR)/dvf8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/dvf8.c + ed - dvf8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) dvf8.s + +fef4.$(SUF): $(CDIR)/fef4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/fef4.c + ed - fef4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) fef4.s + +fef8.$(SUF): $(CDIR)/fef8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/fef8.c + ed - fef8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) fef8.s + +fif4.$(SUF): $(CDIR)/fif4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/fif4.c + ed - fif4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) fif4.s + +fif8.$(SUF): $(CDIR)/fif8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/fif8.c + ed - fif8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) fif8.s + +cfi.$(SUF): $(CDIR)/cfi.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cfi.c + ed - cfi.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cfi.s + +cif4.$(SUF): $(CDIR)/cif4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cif4.c + ed - cif4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cif4.s + +cif8.$(SUF): $(CDIR)/cif8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/cif8.c + ed - cif8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) cif8.s + +mlf4.$(SUF): $(CDIR)/mlf4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/mlf4.c + ed - mlf4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) mlf4.s + +mlf8.$(SUF): $(CDIR)/mlf8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/mlf8.c + ed - mlf8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) mlf8.s + +ngf4.$(SUF): $(CDIR)/ngf4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/ngf4.c + ed - ngf4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) ngf4.s + +ngf8.$(SUF): $(CDIR)/ngf8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/ngf8.c + ed - ngf8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) ngf8.s + +sbf4.$(SUF): $(CDIR)/sbf4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/sbf4.c + ed - sbf4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) sbf4.s + +sbf8.$(SUF): $(CDIR)/sbf8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/sbf8.c + ed - sbf8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) sbf8.s + +adf4.$(SUF): $(CDIR)/adf4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/adf4.c + ed - adf4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) adf4.s + +adf8.$(SUF): $(CDIR)/adf8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/adf8.c + ed - adf8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) adf8.s + +zrf4.$(SUF): $(CDIR)/zrf4.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/zrf4.c + ed - zrf4.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) zrf4.s + +zrf8.$(SUF): $(CDIR)/zrf8.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/zrf8.c + ed - zrf8.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) zrf8.s + +extend.$(SUF): $(CDIR)/extend.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/extend.c + ed - extend.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) extend.s + +compact.$(SUF): $(CDIR)/compact.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/compact.c + ed - compact.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) compact.s + +add_ext.$(SUF): $(CDIR)/add_ext.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/add_ext.c + ed - add_ext.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) add_ext.s + +div_ext.$(SUF): $(CDIR)/div_ext.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/div_ext.c + ed - div_ext.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) div_ext.s + +mul_ext.$(SUF): $(CDIR)/mul_ext.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/mul_ext.c + ed - mul_ext.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) mul_ext.s + +nrm_ext.$(SUF): $(CDIR)/nrm_ext.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/nrm_ext.c + ed - nrm_ext.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) nrm_ext.s + +sft_ext.$(SUF): $(CDIR)/sft_ext.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/sft_ext.c + ed - sft_ext.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) sft_ext.s + +sub_ext.$(SUF): $(CDIR)/sub_ext.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/sub_ext.c + ed - sub_ext.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) sub_ext.s + +zrf_ext.$(SUF): $(CDIR)/zrf_ext.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/zrf_ext.c + ed - zrf_ext.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) zrf_ext.s + +adder.$(SUF): $(CDIR)/adder.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/adder.c + ed - adder.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) adder.s + +shifter.$(SUF): $(CDIR)/shifter.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/shifter.c + ed - shifter.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) shifter.s + +prt_dbl.$(SUF): $(CDIR)/prt_dbl.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/prt_dbl.c + ed - prt_dbl.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) prt_dbl.s + +prt_ext.$(SUF): $(CDIR)/prt_ext.c + ack -c.s -m$(MACH) $(EMFLAGS) $(CDIR)/prt_ext.c + ed - prt_ext.s <$(CDIR)/FP.script + ack -c -m$(MACH) $(EMFLAGS) prt_ext.s diff --git a/mach/proto/fp/add_ext.c b/mach/proto/fp/add_ext.c new file mode 100644 index 000000000..7b1fdb9c7 --- /dev/null +++ b/mach/proto/fp/add_ext.c @@ -0,0 +1,27 @@ +/* +#define PRT_EXT + ADD TWO EXTENDED FORMAT NUMBERS +*/ + +#include "FP_types.h" + +add_ext(e1,e2) +register EXTEND *e1,*e2; +{ +#ifdef PRT_EXT + prt_ext("before ADD #1:",e1); + prt_ext("before ADD #2:",e2); +#endif PRT_EXT + if (b64_add(&e1->m1,&e2->m1)) { /* addition carry */ + b64_sft(&e1->m1,1); /* shift mantissa one bit RIGHT */ + e1->m1 |= 0x80000000L; /* set max bit */ + e1->exp++; /* increase the exponent */ + } +#ifdef PRT_EXT + prt_ext("AFTER ADD :",e1); +#endif + nrm_ext(e1); +#ifdef PRT_EXT + prt_ext("AFTER NRM :",e1); +#endif +} diff --git a/mach/proto/fp/adder.c b/mach/proto/fp/adder.c new file mode 100644 index 000000000..aa7b5f65e --- /dev/null +++ b/mach/proto/fp/adder.c @@ -0,0 +1,81 @@ +/* + * these are the routines the routines to do 32 and 64-bit addition + */ + +# ifdef DEBUG +# include +# endif + +# include "adder.h" +# define UNKNOWN -1 +# define TRUE 1 +# define FALSE 0 +# define MAXBIT 0x80000000L + + /* + * add 64 bits + */ +b64_add(e1,e2) + /* + * pointers to 64 bit 'registers' + */ +register B64 *e1,*e2; +{ + register short overflow; + short carry; + + /* add higher pair of 32 bits */ + overflow = b32_add(&e1->h_32,&e2->h_32); + + /* add lower pair of 32 bits */ + carry = b32_add(&e1->l_32,&e2->l_32); +# ifdef DEBUG + printf("\t\t\t\t\tb64_add: overflow (%d); internal carry(%d)\n", + overflow,carry); + fflush(stdout); +# endif + if ((carry) && (++e1->h_32 == 0)) + return(TRUE); /* had a 64 bit overflow */ + else + return(overflow); /* return status from higher add */ +} + + /* + * add 32 bits (unsigned longs) + * and return the carry status + */ + +b32_add(e1,e2) +register unsigned long *e1,*e2; +{ + register short carry; + + if (*e1 & *e2 & MAXBIT) /* both max_bits are set */ + carry = TRUE; /* so there is a carry */ + else + carry = ((*e1 | *e2) & MAXBIT) + /* only one is set - might be a carry */ + ? UNKNOWN + /* both are clear - no carry */ + : FALSE; +# ifdef DEBUG + fflush(stdout); + printf("\t\t\t\t\tb32_add: overflow before add(%d) test(%d)\n", + carry,(*e1&MAXBIT)?FALSE:TRUE); + printf("%08X\n%08X\n",*e1,*e2); +# endif + + *e1 += *e2; +# ifdef DEBUG + printf("%08X\n",*e1); + fflush(stdout); +# endif + if (carry != UNKNOWN) + return(carry); + else + /* + * if maxbit in answer is set there is no carry + * return the NAND of this bit + */ + return((*e1&MAXBIT)?FALSE:TRUE); +} diff --git a/mach/proto/fp/adder.h b/mach/proto/fp/adder.h new file mode 100644 index 000000000..d09de1e90 --- /dev/null +++ b/mach/proto/fp/adder.h @@ -0,0 +1,8 @@ +/* + * include file for 32 & 64 bit addition + */ + +typedef struct { + unsigned long h_32; /* higher 32 bits of 64 */ + unsigned long l_32; /* lower 32 bits of 64 */ +} B64; diff --git a/mach/proto/fp/adf4.c b/mach/proto/fp/adf4.c new file mode 100644 index 000000000..c22779027 --- /dev/null +++ b/mach/proto/fp/adf4.c @@ -0,0 +1,48 @@ +/* + ADD TWO FLOATS - SINGLE +*/ + +#include "FP_types.h" + +_float +adf4(s2,s1) +_float s1,s2; +{ + EXTEND e1,e2; + int swap = 0; + + extend((_double *)&s1,&e1,sizeof(SINGLE)); + extend((_double *)&s2,&e2,sizeof(SINGLE)); + /* if signs differ do subtraction */ + /* result in e1 */ + if (e1.sign ^ e2.sign) { +#ifdef DEBUG + printf("\t\t\tADF calls SUBTRACT\n"); +#endif DEBUG + /* set sign of e1 to sign of largest */ + swap = (e2.exp > e1.exp) ? 1 : (e2.exp < e1.exp) ? 0 : + (e2.m1 > e1.m1 ) ? 1 : 0; + /* adjust mantissas to equal powers */ + sft_ext(&e1,&e2); + /* subtract the extended formats */ + if (swap) { +#ifdef DEBUG + printf("\t\t\t\tSWAP\n"); +#endif DEBUG + sub_ext(&e2,&e1); + e1 = e2; + } + else + sub_ext(&e1,&e2); + } + else { +#ifdef DEBUG + printf("\t\t\tADF calls ADDITION\n"); +#endif DEBUG + /* adjust mantissas to equal powers */ + sft_ext(&e1,&e2); + add_ext(&e1,&e2); + } + compact(&e1,(_double *)&s1,sizeof(SINGLE)); + return(s1); +} diff --git a/mach/proto/fp/adf8.c b/mach/proto/fp/adf8.c new file mode 100644 index 000000000..0a5b094c4 --- /dev/null +++ b/mach/proto/fp/adf8.c @@ -0,0 +1,49 @@ +/* + ADD TWO FLOATS - DOUBLE +*/ + +#include "FP_types.h" + +_double +adf8(s2,s1) +_double s1,s2; +{ + EXTEND e1,e2; + short swap; + extend(&s1,&e1,sizeof(_double)); + extend(&s2,&e2,sizeof(_double)); +#ifdef PRT_EXT + prt_ext("ADF8: e1",&e1); + prt_ext("ADF8: e2",&e2); +#endif + /* adjust mantissas to equal powers */ + if (e1.sign ^ e2.sign) { /* signs are different */ + /* determine which is largest number */ + swap = (e2.exp > e1.exp) ? 1 : (e2.exp < e1.exp) ? 0 : + (e2.m1 > e1.m1 ) ? 1 : (e2.m1 < e1.m1 ) ? 0 : + (e2.m2 > e1.m2 ) ? 1 : 0; + /* adjust mantissas to equal powers */ + sft_ext(&e1,&e2); + /* subtract the extended formats */ + if (swap) { /* &e2 is the largest number */ +#ifdef PRT_EXT + fprintf(stderr,"ADF8: swaps and subtracts extended\n"); +#endif + sub_ext(&e2,&e1); + e1 = e2; + } + else { + sub_ext(&e1,&e2); + } + } + else { + /* adjust mantissas to equal powers */ + sft_ext(&e1,&e2); + add_ext(&e1,&e2); + } +#ifdef PRT_EXT + prt_ext("ADF8: e1 result",&e1); +#endif + compact(&e1,&s1,sizeof(_double)); + return(s1); +} diff --git a/mach/proto/fp/cff4.c b/mach/proto/fp/cff4.c new file mode 100644 index 000000000..3d94b5579 --- /dev/null +++ b/mach/proto/fp/cff4.c @@ -0,0 +1,28 @@ +/* + CONVERT DOUBLE TO FLOAT + + This routine works quite simply. A floating point + of size 08 is converted to extended format. + This extended variable is converted back to + a floating point of size 04. + +*/ + +#include "FP_types.h" + +cff4(src) +_double src; /* the source itself - THIS TIME it's DOUBLE */ +{ + EXTEND buf; + + extend(&src,&buf,8); /* no matter what */ +#ifdef PRT_EXT + prt_ext("CFF4() entry:",&buf); + fprintf(stderr,"ds(%d),ss(%d),src(%08X%08X)\n",8,4,src.__double[0], + src.__double[1]); +#endif PRT_EXT + compact(&buf,(_double *) &(src.__double[1]),4); +#ifdef PRT_EXT + fprintf(stderr,"CFF4() exit : %08X\n",src.__double[1]); +#endif PRT_EXT +} diff --git a/mach/proto/fp/cff8.c b/mach/proto/fp/cff8.c new file mode 100644 index 000000000..d27332b16 --- /dev/null +++ b/mach/proto/fp/cff8.c @@ -0,0 +1,28 @@ +/* + CONVERT FLOAT TO DOUBLE + + This routine works quite simply. A floating point + of size 04 is converted to extended format. + This extended variable is converted back to + a floating point of size 08. + +*/ + +#include "FP_types.h" + +cff8(src) +_float src; /* the space on the stack is for a double - see cg/table */ +{ + EXTEND buf; + + extend((_double *) &src,&buf,4); /* no matter what */ +#ifdef PRT_EXT + prt_ext("CFF8() entry:",&buf); + fprintf(stderr,"ds(%d),ss(%d),src(%08X)\n",4,8,src); +#endif + compact(&buf,&src,8); +#ifdef DEBUG + fprintf(stderr,"CFF8() exit : %08X",src.__double[0]); + fprintf(stderr,"%08X\n",src.__double[1]); +#endif DEBUG +} diff --git a/mach/proto/fp/cfi.c b/mach/proto/fp/cfi.c new file mode 100644 index 000000000..c983be8fe --- /dev/null +++ b/mach/proto/fp/cfi.c @@ -0,0 +1,46 @@ +/* + CONVERT FLOAT TO UNSIGNED + + N.B. The caller must know what it is getting. + A LONG is always returned. If it is an + integer the high byte is cleared first. +*/ + +#include "FP_trap.h" +#include "FP_types.h" + +long +cfi(ds,ss,src) +int ds; /* destination size (2 or 4) */ +int ss; /* source size (4 or 8) */ +_double src; /* assume worst case */ +{ + EXTEND buf; + long new; + short newint, max_exp; + + extend(&src,&buf,ss); /* get extended format */ +#ifdef PRT_EXT + prt_ext("CFI() entry:",&buf); +#endif PRT_EXT + buf.exp--; /* additional bias correction */ + if (buf.exp < 1) { /* no conversion needed */ + src.__double[ss == 8] = 0L; + return(0L); + } + max_exp = (ds << 3) - 1; /* signed numbers */ + /* have more limited max_exp */ + if (buf.exp > max_exp) { +#ifdef PRT_EXT + prt_ext("CFI() INT OVERFLOW", &buf); +#endif PRT_EXT + trap(EIOVFL); /* integer overflow */ + buf.exp %= max_exp; /* truncate */ + } + new = buf.m1 >> (32-buf.exp); + if (buf.sign) + new = -new; +done: + src.__double[ss == 8] = new; + return(new); +} diff --git a/mach/proto/fp/cfu.c b/mach/proto/fp/cfu.c new file mode 100644 index 000000000..9b3ba6546 --- /dev/null +++ b/mach/proto/fp/cfu.c @@ -0,0 +1,43 @@ +/* + CONVERT FLOAT TO UNSIGNED + + N.B. The caller must know what it is getting. + A LONG is always returned. If it is an + integer the high byte is cleared first. +*/ + +#include "FP_trap.h" +#include "FP_types.h" + +long +cfu(ds,ss,src) +int ds; /* destination size (2 or 4) */ +int ss; /* source size (4 or 8) */ +_double src; /* assume worst case */ +{ + EXTEND buf; + long new; + short newint, max_exp; + + extend(&src,&buf,ss); /* get extended format */ +#ifdef PRT_EXT + prt_ext("CFU() entry:",&buf); +#endif PRT_EXT + buf.exp--; /* additional bias correction */ + if (buf.exp < 1) { /* no conversion needed */ + src.__double[ss == 8] = 0L; + return(0L); + } + max_exp = (ds << 3); + if (buf.exp > max_exp) { +#ifdef PRT_EXT + prt_ext("CFU() INT OVERFLOW",&buf); +#endif PRT_EXT + trap(EIOVFL); /* integer overflow */ + buf.exp %= max_exp; + } + new = buf.m1 >> (32-buf.exp); +done: + src.__double[ss == 8] = new; + return(new); +} diff --git a/mach/proto/fp/cif4.c b/mach/proto/fp/cif4.c new file mode 100644 index 000000000..f5264cf30 --- /dev/null +++ b/mach/proto/fp/cif4.c @@ -0,0 +1,56 @@ +/* + CONVERT INTEGER TO FLOAT + + THIS ROUTINE WORKS BY FILLING AN EXTENDED + WITH THE INTEGER VALUE IN EXTENDED FORMAT + AND USES COMPACT() TO PUT IT INTO THE PROPER + FLOATING POINT PRECISION. +*/ + +#include "FP_types.h" + +_float +cif4(ss,src) +int ss; /* source size */ +long src; /* largest possible integer to convert */ +{ + EXTEND buf; + short *ipt; + long i_src; + _float *result; + + zrf_ext(&buf); + if (ss == sizeof(long)) { + buf.exp = 33; + i_src = src; + result = (_float *) &src; + } + else { + ipt = (short *) &src; + i_src = (long) *ipt; + buf.exp = 17; + result = (_float *) &ss; + } +#ifdef PRT_STDERR + fprintf(stderr,"CIF4(ds(%d),ss(%d),src(%D))\n\n",4,ss,i_src); +#endif + if (i_src == 0) { + *result = (_float) 0L; + return(0L); + } + /* ESTABLISHED THAT src != 0 */ + /* adjust exponent field */ + buf.sign = (i_src < 0) ? 0x8000 : 0; + /* clear sign bit of integer */ + /* move to mantissa field */ + buf.m1 = (i_src < 0) ? -i_src : i_src; + /* adjust mantissa field */ + if (ss != sizeof(long)) + buf.m1 <<= 16; + nrm_ext(&buf); /* adjust mantissa field */ +#ifdef PRT_STDERR + fprintf(stderr,"CIF() buf.exp after nrm_ext() == %d\n\n",buf.exp); +#endif + compact(&buf,(_double *) result,4); /* put on stack */ + return(*result); +} diff --git a/mach/proto/fp/cif8.c b/mach/proto/fp/cif8.c new file mode 100644 index 000000000..031a6a573 --- /dev/null +++ b/mach/proto/fp/cif8.c @@ -0,0 +1,55 @@ +/* + CONVERT INTEGER TO FLOAT + + THIS ROUTINE WORKS BY FILLING AN EXTENDED + WITH THE INTEGER VALUE IN EXTENDED FORMAT + AND USES COMPACT() TO PUT IT INTO THE PROPER + FLOATING POINT PRECISION. +*/ + +#include "FP_types.h" + +_double +cif8(ss,src) +int ss; /* source size */ +long src; /* largest possible integer to convert */ +{ + EXTEND buf; + _double *result; /* for return value */ + short *ipt; + long i_src; + + result = (_double *) &ss; /* always */ + zrf_ext(&buf); + if (ss == sizeof(long)) { + buf.exp = 33; + i_src = src; + } + else { + ipt = (short *) &src; + i_src = (long) *ipt; + buf.exp = 17; + } +#ifdef PRT_STDERR + fprintf(stderr,"CIF8(ds(%d),ss(%d),src(%D))\n\n",8,ss,i_src); +#endif + if (i_src == 0) { + zrf8(result); + return(*result); + } + /* ESTABLISHED THAT src != 0 */ + /* adjust exponent field */ + buf.sign = (i_src < 0) ? 0x8000 : 0; + /* clear sign bit of integer */ + /* move to mantissa field */ + buf.m1 = (i_src < 0) ? -i_src : i_src; + /* adjust mantissa field */ + if (ss != sizeof(long)) + buf.m1 <<= 16; + nrm_ext(&buf); +#ifdef PRT_STDERR + fprintf(stderr,"CIF() buf.exp after nrm_ext() == %d\n\n",buf.exp); +#endif + compact(&buf,result,8); + return(*result); +} diff --git a/mach/proto/fp/cmf4.c b/mach/proto/fp/cmf4.c new file mode 100644 index 000000000..134ab0b93 --- /dev/null +++ b/mach/proto/fp/cmf4.c @@ -0,0 +1,30 @@ +/* + COMPARE DOUBLES +*/ + +#include "FP_types.h" +#include "get_put.h" + +short +cmf4(f1,f2) +_float f1,f2; +{ + /* + * return ((f1 < f2) ? 1 : (f1 - f2)) + */ +#define SIGN(x) (((x) < 0) ? -1 : 1) + int sign1,sign2; + long l1,l2; + + l1 = get4((char *) &f1); + l2 = get4((char *) &f2); + + if (l1 == l2) return 0; + + sign1 = SIGN(l1); + sign2 = SIGN(l2); + if (sign1 != sign2) + return ((sign1 > 0) ? -1 : 1); + + return (sign1 * ((l1 < l2) ? 1 : -1)); +} diff --git a/mach/proto/fp/cmf8.c b/mach/proto/fp/cmf8.c new file mode 100644 index 000000000..37bf94913 --- /dev/null +++ b/mach/proto/fp/cmf8.c @@ -0,0 +1,50 @@ +/* + COMPARE DOUBLES +*/ + +#include "FP_types.h" +#include "get_put.h" + +short +cmf8(d1,d2) +_double d1,d2; +{ +#define SIGN(x) (((x) < 0) ? -1 : 1) + /* + * return ((d1 < d2) ? 1 : (d1 > d2) ? -1 : 0)) + */ + long l1,l2; + unsigned short *s1,*s2; + int sign1,sign2; + + l1 = get4((char *)&d1); + l2 = get4((char *)&d2); + sign1 = SIGN(l1); + sign2 = SIGN(l2); + if (sign1 != sign2) + return ((sign1 > 0) ? -1 : 1); + if (l1 != l2) { /* we can decide here */ + s1 = (unsigned short *) &l1; + s2 = (unsigned short *) &l2; + /* set both signs positive */ + *s1 &= ~0x8000; + *s2 &= ~0x8000; + /* we already know they aren't equal so */ + return (sign1 * ((l1 < l2) ? 1 : -1)); + } + else { /* decide in 2nd half */ + l1 = get4(((char *)&d1 + 4)); + l2 = get4(((char *)&d2 + 4)); + if (l1 == l2) + return(0); + else { + s1 = (unsigned short *) &l1; + s2 = (unsigned short *) &l2; + if (*s1 == *s2) { + s1++; + s2++; + } + return (sign1 * ((*s1 < *s2) ? 1 : -1)); + } + } +} diff --git a/mach/proto/fp/compact.c b/mach/proto/fp/compact.c new file mode 100644 index 000000000..517032760 --- /dev/null +++ b/mach/proto/fp/compact.c @@ -0,0 +1,213 @@ +/* +#define PRT_EXIT +#define PRT_TRAP +#define PRT_ENTRY + COMPACT EXTEND FORMAT INTO FLOAT OF PROPER SIZE +*/ + +# include "FP_bias.h" +# include "FP_shift.h" +# include "FP_trap.h" +# include "FP_types.h" +# include "get_put.h" + +compact(f,to,size) +EXTEND *f; +_double *to; +int size; +{ + DOUBLE *DBL; + int error = 0; + SINGLE *SGL; + int exact; + +#ifdef PRT_ENTRY + prt_ext("enter compact:",f); +#endif PRT_ENTRY + if (size == sizeof(_double)) +/********************************************************/ +/* + COMPACT EXTENDED INTO DOUBLE +*/ +/********************************************************/ + { + if ((f->m1|(f->m2 & DBL_ZERO)) == 0L) { + zrf8(to); + goto leave; + } + f->exp += DBL_BIAS; /* restore proper bias */ + if (f->exp > DBL_MAX) { +dbl_over: trap(EFOVFL); +#ifdef PRT_TRAP + prt_ext("FCOMPACT DBL OVERFLOW",f); +#endif PRT_TRAP + f->exp = DBL_MAX; + f->m1 = f->m2 = 0L; + if (error++) + return; + } + else if (f->exp < DBL_MIN) { +#ifdef PRT_TRAP + prt_ext("FCOMPACT DBL UNDERFLOW",f); +#endif PRT_TRAP + trap(EFUNFL); + f->exp = DBL_MIN; + f->m1 = f->m2 = 0L; + if (error++) + return; + } + + /* local CAST conversion */ + DBL = (DOUBLE *) to; + /* check if answer is exact */ + /* (the last 11 bits are zero (0) */ + + exact = ((f->m2 & DBL_EXACT) == 0) ? 1 : 0; + + /* because of special format shift only 10 bits */ + /* bit shift mantissa 10 bits */ + + /* first align within words, then do store operation */ + + DBL->_s.p1.fract = f->m1 >> DBL_RUNPACK; /* plus 22 == 32 */ + DBL->_s.p2 = f->m2 >> DBL_RUNPACK; /* plus 22 == 32 */ + DBL->_s.p2 |= (f->m1 << DBL_LUNPACK); /* plus 10 == 32 */ + + /* if not exact then round to nearest */ + + if (!exact) { + /* INEXACT(); */ + if (f->m2 & DBL_ROUNDUP) { + DBL->_s.p2++; /* rounding up */ + if (DBL->_s.p2 == 0L) { /* carry out */ +#ifdef PRT_RNDMSG + write(2,"rounding up lsb\n",16); +#endif PRT_RNDMSG + DBL->_s.p1.fract++; + if (DBL->_s.p1.fract & DBL_CARRYOUT) { /* carry out */ +#ifdef PRT_RNDMSG + write(2,"shift due to rounding\n",22); +#endif PRT_RNDMSG + if (DBL->_s.p1.fract & 01) + DBL->_s.p2 = CARRYBIT; + DBL->_s.p1.fract >>= 1; + f->exp++; + } + } + } + } + /* check for overflow */ + if (f->exp >= DBL_MAX) + goto dbl_over; + + /* STORE EXPONENT: */ + + /* 1) clear leading bits (B4-B15) */ + DBL->_s.p1.fract &= DBL_MASK; + + /* 2) shift and store exponent */ + f->exp <<= DBL_EXPSHIFT; + DBL->_s.p1.fract |= ((long) f->exp << EXP_STORE); + } + else +/********************************************************/ +/* + COMPACT EXTENDED INTO FLOAT +*/ +/********************************************************/ + { + /* local CAST conversion */ + SGL = (SINGLE *) to; + if ((f->m1 & SGL_ZERO) == 0L) { + SGL->fract = 0L; + goto leave; + } + f->exp += SGL_BIAS; /* restore bias */ + if (f->exp > SGL_MAX) { +sgl_over: trap(EFOVFL); +#ifdef PRT_TRAP + prt_ext("FCOMPACT FLOAT OVERFLOW",f); +#endif PRT_TRAP + f->exp = SGL_MAX; + f->m1 = f->m2 = 0L; + if (error++) + return; + } + else if (f->exp < SGL_MIN) { +#ifdef PRT_TRAP + prt_ext("FCOMPACT FLOAT UNDERFLOW",f); +#endif PRT_TRAP + trap(EFUNFL); + f->exp = SGL_MIN; + f->m1 = f->m2 = 0L; + if (error++) + return; + } + /* check if the answer is exact */ + /* the last 40 bits are zero */ + /* check first last bits of mantissa 1 */ + exact = ((f->m1 & SGL_EXACT) == 0) ? 1 : 0; + + /* check last 32 bits in mantissa 2 */ + if (exact) /* first part masks to zero */ + exact = (f->m2 == 0L) ? 1 : 0; + + /* shift mantissa and store */ + SGL->fract = (f->m1 >> SGL_RUNPACK); + + /* check for rounding to nearest */ + if (!exact) { + /* INEXACT(); */ + if (f->m1 & SGL_ROUNDUP) { + SGL->fract++; +#ifdef PRT_RNDMSG + write(2,"rounding up lsb\n",16); +#endif PRT_RNDMSG + /* check normal */ + if (SGL->fract & SGL_CARRYOUT) { + SGL->fract >>= 1; + f->exp++; + } + } + } + if (f->exp >= SGL_MAX) + goto sgl_over; + + /* STORE EXPONENT */ + /* 1) clear leading bit of fraction */ + SGL->fract &= SGL_MASK; /* B23-B31 are 0 */ + + /* 2) shift and store exponent */ + f->exp <<= SGL_EXPSHIFT; + SGL->fract |= ((long) f->exp << EXP_STORE); + } + +/********************************************************/ +/* + STORE SIGN BIT +*/ +/********************************************************/ + if (f->sign) { + SGL = (SINGLE *) to; /* make sure */ + SGL->fract |= CARRYBIT; + } +/********************************************************/ +/* + STORE MANTISSA +/* +/********************************************************/ + + if (size == sizeof(_double)) { + put4(DBL->_s.p1.fract, (char *) &DBL->_s.p1.fract); + put4(DBL->_s.p2, (char *) &DBL->_s.p2); + } + else + put4(SGL->fract, (char *) &SGL->fract); + +leave: +#ifdef PRT_EXIT + prt_ext("exit compact:",f); + prt_dbl((DOUBLE *) to,size); getchar(); +#endif PRT_EXIT + ; /* end of print statement or null statement */ +} diff --git a/mach/proto/fp/cuf4.c b/mach/proto/fp/cuf4.c new file mode 100644 index 000000000..ed219c2b8 --- /dev/null +++ b/mach/proto/fp/cuf4.c @@ -0,0 +1,54 @@ +/* + CONVERT INTEGER TO FLOAT + + THIS ROUTINE WORKS BY FILLING AN EXTENDED + WITH THE INTEGER VALUE IN EXTENDED FORMAT + AND USES COMPACT() TO PUT IT INTO THE PROPER + FLOATING POINT PRECISION. +*/ + +#include "FP_types.h" + +cuf4(ss,src) +int ss; /* source size */ +long src; /* largest possible integer to convert */ +{ + EXTEND buf; + short *ipt; + _float *result; + long i_src; + + zrf_ext(&buf); + if (ss == sizeof(long)) { + buf.exp = 33; + i_src = src; + result = (_float *) &src; + } + else { + ipt = (short *) &src; + i_src = (long) *ipt; + buf.exp = 17; + result = (_float *) &ss; + } +#ifdef PRT_STDERR + fprintf(stderr,"CUF4(ds(%d),ss(%d),src(%D))\n\n",4,ss,i_src); +#endif + if (i_src == 0) { + src = 0L; + } + /* ESTABLISHED THAT src != 0 */ + + /* adjust exponent field */ + if (ss != sizeof(long)) + i_src <<= 16; + + /* move to mantissa field */ + buf.m1 = i_src; + + /* adjust mantissa field */ + nrm_ext(&buf); +#ifdef PRT_STDERR + fprintf(stderr,"CUF() buf.exp after nrm_ext() == %d\n\n",buf.exp); +#endif + compact(&buf,(_double *) result,4); +} diff --git a/mach/proto/fp/cuf8.c b/mach/proto/fp/cuf8.c new file mode 100644 index 000000000..1145fcedd --- /dev/null +++ b/mach/proto/fp/cuf8.c @@ -0,0 +1,52 @@ +/* + CONVERT INTEGER TO FLOAT + + THIS ROUTINE WORKS BY FILLING AN EXTENDED + WITH THE INTEGER VALUE IN EXTENDED FORMAT + AND USES COMPACT() TO PUT IT INTO THE PROPER + FLOATING POINT PRECISION. +*/ + +#include "FP_types.h" + +cuf8(ss,src) +int ss; /* source size */ +long src; /* largest possible integer to convert */ +{ + EXTEND buf; + short *ipt; + long i_src; + + zrf_ext(&buf); + if (ss == sizeof(long)) { + buf.exp = 33; + i_src = src; + } + else { + ipt = (short *) &src; + i_src = (long) *ipt; + buf.exp = 17; + } +#ifdef PRT_STDERR + fprintf(stderr,"CUF8(ds(%d),ss(%d),src(%D))\n\n",8,ss,i_src); +#endif + if (i_src == 0) { + zrf8(&src); + return; + } + /* ESTABLISHED THAT src != 0 */ + + /* adjust exponent field */ + if (ss != sizeof(long)) + i_src <<= 16; + + /* move to mantissa field */ + buf.m1 = i_src; + + /* adjust mantissa field */ + nrm_ext(&buf); +#ifdef PRT_STDERR + fprintf(stderr,"CUF() buf.exp after nrm_ext() == %d\n\n",buf.exp); +#endif + compact(&buf,(_double *) &ss,8); +} diff --git a/mach/proto/fp/div_ext.c b/mach/proto/fp/div_ext.c new file mode 100644 index 000000000..658b16113 --- /dev/null +++ b/mach/proto/fp/div_ext.c @@ -0,0 +1,179 @@ +/* +#define PRT_EXT +#define PRT_ALL + DIVIDE EXTENDED FORMAT +*/ + +#include "FP_bias.h" +#include "FP_trap.h" +#include "FP_types.h" + +/* + November 15, 1984 + + This is a routine to do the work. + It is based on the partial products method + and makes no use possible machine instructions + to divide (hardware dividers). It is intended + that it be rewritten to do so, but expedieancy + requires that something be written NOW - and + this is it. +*/ +/********************************************************/ + +div_ext(e1,e2) +EXTEND *e1,*e2; +{ + short count; + short error = 0; + unsigned long result[2]; + register unsigned long *lp; + +#ifdef PRT_EXT + fprintf("stderr:start div_ext:\n"); + prt_ext("dividend:",e1); + prt_ext("divisor :",e2); +#endif + if ((e1->m1 | e1->m2) == 0) { /* 0 / anything == 0 */ + e1->exp = 0; /* make sure */ + return; + } + /* + * numbers are right shifted one bit to make sure + * that m1 is quaranteed to be larger if its + * maximum bit is set + */ + b64_sft(&e1->m1,1); /* 64 bit shift right */ + b64_sft(&e2->m1,1); /* 64 bit shift right */ + e1->exp++; + e2->exp++; + /* 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) { + error++; +#ifdef PRT_EXT + prt_ext("DIV_EXT UNDERFLOW",e1); +#endif PRT_EXT + trap(EFUNFL); /* underflow */ + e1->exp = EXT_MIN; + e1->m1 = e1->m2 = 0L; + } + if ((e2->m1 | e2->m2) == 0) { + error++; +#ifdef PRT_EXT + prt_ext("DIV_EXT DIV 0.0",e2); +#endif PRT_EXT + trap(EFDIVZ); + e1->m1 = e1->m2 = 0L; + e1->exp = EXT_MAX; + } + if (error) + return; + + /* do division of mantissas */ + /* uses partial product method */ + /* init control variables */ + + count = 64; + lp = result; /* result[0] == high word */ + /* result[0] == low word */ + *lp++ = 0L; /* high word */ + *lp-- = 0L; /* low word */ + + /* partial product division loop */ + + while (count--) { + /* first left shift result 1 bit */ + /* this is ALWAYS done */ + + b64_sft(result,-1); + + /* compare dividend and divisor */ + /* if dividend >= divisor add a bit */ + /* and subtract divisior from dividend */ +#ifdef PRT_ALL + prt_ext("dividend:",e1); + prt_ext("divisor :",e2); +#endif + + if ( (e1->m1 < e2->m1) || + ((e1->m1 == e2->m1) && (e1->m2 < e2->m2) )) + ; /* null statement */ + /* i.e., don't add or subtract */ + else { + result[1]++; /* ADD */ + if (e2->m2 > e1->m2) + e1->m1 -= 1; /* carry in */ + e1->m1 -= e2->m1; /* do SUBTRACTION */ + e1->m2 -= e2->m2; /* SUBTRACTION */ +#ifdef PRT_ALL + prt_ext("result :",e1); +#endif + } +#ifdef PRT_ALL + fprintf(stderr,"div_ext %d %08X%08X\n\n",64-count, + result[0],result[1]); + fflush(stderr); +#endif + + /* shift dividend left one bit OR */ + /* IF it equals ZERO we can break out */ + /* of the loop, but still must shift */ + /* the quotient the remaining count bits */ + /* NB save the results of this test in error */ + /* if not zero, then the result is inexact. */ + /* this would be reported in IEEE standard */ + + /* lp points to dividend */ + lp = &e1->m1; + + error = ((*lp | *(lp+1)) != 0L) ? 1 : 0; + if (error) { /* more work */ + /* assume max bit == 0 (see above) */ + b64_sft(&e1->m1,-1); + continue; + } + else + break; /* leave loop */ + } /* end of divide by subtraction loop */ + + /* DISPLAY RESULTS FOR DEBUGGING */ +#ifdef PRT_ALL + prt_ext("dividend:",e1); + prt_ext("divisor :",e2); + fprintf(stderr,"div_ext %d %08X%08X\n",64-count, + result[0],result[1]); +#endif + + if (count > 0) { + lp = result; + if (count > 31) { /* move to higher word */ + *lp = *(lp+1); + count -= 32; + *(lp+1) = 0L; /* clear low word */ + } + if (*lp) + *lp <<= count; /* shift rest of way */ + lp++; /* == &result[1] */ + if (*lp) { + result[0] |= (*lp >> 32-count); + *lp <<= count; + } + } + /* + if (error) + INEXACT(); + */ + e1->m1 = result[0]; + e1->m2 = result[1]; +#ifdef PRT_EXT + prt_ext("result :",e1); +#endif + nrm_ext(e1); +#ifdef PRT_EXT + prt_ext("after nrm:",e1); + /*sleep(4);*/ +#endif +} diff --git a/mach/proto/fp/dvf4.c b/mach/proto/fp/dvf4.c new file mode 100644 index 000000000..234dedaa1 --- /dev/null +++ b/mach/proto/fp/dvf4.c @@ -0,0 +1,18 @@ +/* + DIVIDE TWO FLOATS - SINGLE Precision +*/ + +#include "FP_types.h" + +dvf4(s2,s1) +_float s1,s2; +{ + EXTEND e1,e2; + + extend((_double *)&s1,&e1,sizeof(_float)); + extend((_double *)&s2,&e2,sizeof(_float)); + + /* do a divide */ + div_ext(&e1,&e2); + compact(&e1,(_double *)&s1,sizeof(_float)); +} diff --git a/mach/proto/fp/dvf8.c b/mach/proto/fp/dvf8.c new file mode 100644 index 000000000..02cb011b3 --- /dev/null +++ b/mach/proto/fp/dvf8.c @@ -0,0 +1,18 @@ +/* + DIVIDE TWO FLOATS - DOUBLE Precision +*/ + +#include "FP_types.h" + +dvf8(s2,s1) +_double s1,s2; +{ + EXTEND e1,e2; + + extend(&s1,&e1,sizeof(_double)); + extend(&s2,&e2,sizeof(_double)); + + /* do a divide */ + div_ext(&e1,&e2); + compact(&e1,&s1,sizeof(_double)); +} diff --git a/mach/proto/fp/extend.c b/mach/proto/fp/extend.c new file mode 100644 index 000000000..8d17cae1a --- /dev/null +++ b/mach/proto/fp/extend.c @@ -0,0 +1,96 @@ +/* +#define PRT_EXIT +#define PRT_ENTRY +#define PRT_DBL + CONVERTS FLOATING POINT TO EXTENDED FORMAT + + Two sizes of FLOATING Point are known: + SINGLE and DOUBLE +*/ +/********************************************************/ +/* + It is not required to normalize in extended + format, but it has been chosen to do so. + Extended Format is as follows (at exit): + +->sign S000 0000 | 0000 0000 +->exp 0EEE EEEE | EEEE EEEE +->m1 LFFF FFFF | FFFF FFFF + FFFF FFFF | FFFF FFFF +->m2 FFFF FFFF | FFFF FFFF + FFFF F000 | 0000 0000 +*/ +/********************************************************/ + +#include "FP_bias.h" +#include "FP_shift.h" +#include "FP_types.h" +#include "get_put.h" +/********************************************************/ + +extend(from,to,size) +_double *from; +EXTEND *to; +int size; +{ + DOUBLE *f; + register char *cpt1,*cpt2; + unsigned long tmp; + int leadbit = 0; + +#ifdef PRT_ENTRY + write(2,"entry extend: ",14); +#ifdef PRT_DBL + prt_dbl(from,size); +#else + write(2,"\n",1); +#endif PRT_DBL +#endif PRT_ENTRY + f = (DOUBLE *) from; /* local cast conversion */ + if (f->_s.p1.fract == 0L) { + if (size == sizeof(SINGLE)) { +zero: zrf_ext(to); + goto ready; + } + else if (f->_s.p2 == 0L) + goto zero; + } +/* there is a number to convert so lets get started */ +/* first extract the exponent; its always in the first two bytes */ + + cpt1 = (char *) from; + to->exp = uget2(cpt1); + to->sign = (to->exp & 0x8000); /* set sign bit */ + to->exp ^= to->sign; + if (size == sizeof(DOUBLE)) + to->exp >>= DBL_EXPSHIFT; + else + to->exp >>= SGL_EXPSHIFT; + if (to->exp > 0) + leadbit++; /* will set Lead bit later */ + + to->m1 = get4(cpt1); + + if (size == sizeof(DOUBLE)) { + to->m1 <<= DBL_M1LEFT; /* shift */ + to->exp -= DBL_BIAS; /* remove bias */ + cpt1 += 4; + tmp = get4(cpt1); + to->m1 |= (tmp>>DBL_RPACK); /* plus 10 == 32 */ + to->m2 = (tmp<m1 <<= SGL_M1LEFT; /* shift */ + to->exp -= SGL_BIAS; /* remove bias */ + to->m2 = 0L; + } + + to->m1 |= NORMBIT; /* set bit L */ + if (leadbit == 0) /* set or clear Leading Bit */ + to->m1 &= ~NORMBIT; /* clear bit L */ +ready: +#ifdef PRT_EXIT + prt_ext("exit extend:",to) +#endif PRT_EXIT + ; /* end of print statement or null statement */ +} diff --git a/mach/proto/fp/fef4.c b/mach/proto/fp/fef4.c new file mode 100644 index 000000000..17906bb09 --- /dev/null +++ b/mach/proto/fp/fef4.c @@ -0,0 +1,22 @@ +/* + SEPERATE INTO EXPONENT AND FRACTION +*/ + +#include "FP_types.h" + +struct fef4_returns { + short e; + _float f; +}; + +fef4(s1) +_float s1; +{ + struct fef4_returns *r = (struct fef4_returns *) &s1; + EXTEND buf; + + extend((_double *) &s1,&buf,sizeof(_float)); + r->e = buf.exp-1; + buf.exp = 1; + compact(&buf,(_double *) &r->f,sizeof(_float)); +} diff --git a/mach/proto/fp/fef8.c b/mach/proto/fp/fef8.c new file mode 100644 index 000000000..7bf5ba615 --- /dev/null +++ b/mach/proto/fp/fef8.c @@ -0,0 +1,30 @@ +/* + SEPERATE DOUBLE INTO EXPONENT AND FRACTION +*/ + +#include "FP_types.h" + +struct fef8_returns { + short e; + _double f; +}; + +fef8(s1) +_double s1; +{ + EXTEND buf; + struct fef8_returns *r = (struct fef8_returns *) &s1; + +#ifdef DEBUG + printf("FEF8(): "); +#endif DEBUG + extend(&s1,&buf,sizeof(_double)); + r->e = buf.exp - 1; + buf.exp = 1; + compact(&buf,&r->f,sizeof(_double)); +#ifdef DEBUG + printf("exponent = %3d fraction = 0x%08X%08X: ", + r->f.__double[0],r->f.__double[1]); + printf("FEF8()\n"); +#endif DEBUG +} diff --git a/mach/proto/fp/fif4.c b/mach/proto/fp/fif4.c new file mode 100644 index 000000000..3cbaa1f2e --- /dev/null +++ b/mach/proto/fp/fif4.c @@ -0,0 +1,33 @@ +/* + MULTIPLY AND DISMEMBER PARTS +*/ + +#include "FP_types.h" +#include "FP_shift.h" + +_float mlf4(); +_float sbf4(); + +fif4(x,y) +_float x,y; +{ + EXTEND e; + + y = mlf4(x,y); + extend((_double *)&y,&e,sizeof(SINGLE)); + e.exp--; /* additional bias correction */ + if (e.exp < 1) { + x = 0; + return; + } + if (e.exp > 31 - SGL_M1LEFT) { + x = y; + y = 0; + return; + } + b64_sft(&e.m1, 64 - e.exp); + b64_sft(&e.m1, e.exp - 64); /* "loose" low order bits */ + e.exp++; + compact(&e,(_double *) &x, sizeof(SINGLE)); + y = sbf4(x, y); +} diff --git a/mach/proto/fp/fif8.c b/mach/proto/fp/fif8.c new file mode 100644 index 000000000..0b606f982 --- /dev/null +++ b/mach/proto/fp/fif8.c @@ -0,0 +1,36 @@ +/* + MULTIPLY AND DISMEMBER PARTS +*/ + +#include "FP_types.h" +#include "FP_shift.h" + +_double mlf8(); +_double sbf8(); + +fif8(x,y) +_double x,y; +{ + EXTEND e; + + y = mlf8(x,y); + extend((_double *)&y,&e,sizeof(DOUBLE)); + e.exp--; /* additional bias correction */ + if (e.exp < 1) { + x.__double[0] = 0; + x.__double[1] = 0; + return; + } + if (e.exp > 63 - DBL_M1LEFT) { + x.__double[0] = y.__double[0]; + x.__double[1] = y.__double[1]; + y.__double[0] = 0; + y.__double[1] = 0; + return; + } + b64_sft(&e.m1, 64 - e.exp); + b64_sft(&e.m1, e.exp - 64); /* "loose" low order bits */ + e.exp++; + compact(&e, &x, sizeof(DOUBLE)); + y = sbf8(x, y); +} diff --git a/mach/proto/fp/fptrp.e b/mach/proto/fp/fptrp.e new file mode 100644 index 000000000..91c762bda --- /dev/null +++ b/mach/proto/fp/fptrp.e @@ -0,0 +1,15 @@ +# + + mes 2,EM_WSIZE,EM_PSIZE + +#define TRAP 0 + +; _fptrp is called with one parameter: +; - trap number (TRAP) + + exp $_fptrp + pro $_fptrp,0 + lol TRAP + trp + ret 0 + end ? diff --git a/mach/proto/fp/get_put.h b/mach/proto/fp/get_put.h new file mode 100644 index 000000000..119e08345 --- /dev/null +++ b/mach/proto/fp/get_put.h @@ -0,0 +1,30 @@ +#include + +#if CHAR_UNSIGNED +#define Xchar(ch) (ch) +#else +#define Xchar(ch) ((ch) & 0377) +#endif + +#if ! BYTES_REVERSED +#define uget2(c) (Xchar((c)[1]) | ((unsigned) Xchar((c)[0]) << 8)) +#define Xput2(i, c) (((c)[1] = (i)), ((c)[0] = (i) >> 8)) +#define put2(i, c) { register int j = (i); Xput2(j, c); } +#else +#define uget2(c) (* ((unsigned short *) (c))) +#define Xput2(i, c) (* ((short *) (c)) = (i)) +#define put2(i, c) Xput2(i, c) +#endif + +#define get2(c) ((short) uget2(c)) + +#if WORDS_REVERSED || ! BYTES_REVERSED +#define get4(c) (uget2((c)+2) | ((long) uget2(c) << 16)) +#define put4(l, c) { register long x=(l); \ + Xput2((int)x,(c)+2); \ + Xput2((int)(x>>16),(c)); \ + } +#else +#define get4(c) (* ((long *) (c))) +#define put4(l, c) (* ((long *) (c)) = (l)) +#endif diff --git a/mach/proto/fp/mlf4.c b/mach/proto/fp/mlf4.c new file mode 100644 index 000000000..c5ed05f97 --- /dev/null +++ b/mach/proto/fp/mlf4.c @@ -0,0 +1,19 @@ +/* + * Multiply Single Precesion Float + */ + +#include "FP_types.h" + +_float +mlf4(s2,s1) +_float s1,s2; +{ + EXTEND e1,e2; + + extend((_double *)&s1,&e1,sizeof(_float)); + extend((_double *)&s2,&e2,sizeof(_float)); + /* do a multiply */ + mul_ext(&e1,&e2); + compact(&e1,(_double *)&s1,sizeof(_float)); + return(s1); +} diff --git a/mach/proto/fp/mlf8.c b/mach/proto/fp/mlf8.c new file mode 100644 index 000000000..a150a2ff0 --- /dev/null +++ b/mach/proto/fp/mlf8.c @@ -0,0 +1,19 @@ +/* + * Multiply Single Precesion Float + */ + +#include "FP_types.h" + +_double +mlf8(s2,s1) +_double s1,s2; +{ + EXTEND e1,e2; + + extend(&s1,&e1,sizeof(_double)); + extend(&s2,&e2,sizeof(_double)); + /* do a multiply */ + mul_ext(&e1,&e2); + compact(&e1,&s1,sizeof(_double)); + return(s1); +} diff --git a/mach/proto/fp/mul_ext.c b/mach/proto/fp/mul_ext.c new file mode 100644 index 000000000..959d51695 --- /dev/null +++ b/mach/proto/fp/mul_ext.c @@ -0,0 +1,199 @@ +/* + ROUTINE TO MULTIPLY TWO EXTENDED FORMAT NUMBERS +*/ + +# include "adder.h" +# include "FP_bias.h" +# include "FP_trap.h" +# include "FP_types.h" + +mul_ext(e1,e2) +EXTEND *e1,*e2; +{ + register short k,i,j; /* loop control */ + long unsigned *reg[7]; + long unsigned tmp[4]; + short unsigned mp[4]; /* multiplier */ + short unsigned mc[4]; /* multipcand */ + B64 low64,tmp64; /* 64 bit storage */ + +#ifdef PRT_EXT + prt_ext("before MUL_EXT() e1:",e1); + prt_ext("before MUL_EXT() e2:",e2); +#endif + /* 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) { +#ifdef PRT_EXT + prt_ext("EXT_MUL OVERFLOW",e1); +#endif + trap(EFOVFL); + /* if caught */ + /* return signed infinity */ + e1->exp = EXT_MAX; +infinity: e1->m1 = e1->m2 =0L; +#ifdef PRT_EXT + prt_ext("after MUL_EXT() e1:",e1); +#endif + return; + } + /* check for underflow */ + if (e1->exp < EXT_MIN) { +#ifdef PRT_EXT + prt_ext("EXT_MUL UNDERFLOW",e1); +#endif + trap(EFUNFL); + e1->exp = EXT_MIN; + goto infinity; + } + + /* 128 bit multiply of mantissas */ + + /* assign unknown long formats */ + /* to known unsigned word formats */ + mp[0] = e1->m1 >> 16; + mp[1] = (unsigned short) e1->m1; + mp[2] = e1->m2 >> 16; + mp[3] = (unsigned short) e1->m2; + mc[0] = e2->m1 >> 16; + mc[1] = (unsigned short) e2->m1; + mc[2] = e2->m2 >> 16; + mc[3] = (unsigned short) e2->m2; +# ifdef DEBUG + for(i=0;i<4;i++) + printf("%04x",mp[i]); + putchar('\r'); + putchar('\n'); + for(i=0;i<4;i++) + printf("%04x",mc[i]); + putchar('\r'); + putchar('\n'); +# endif + /* + * assign pointers + */ + reg[0] = &e1->m1; /* the answer goes here */ + reg[1] = &tmp[1]; + reg[2] = &e1->m2; /* and here */ + reg[3] = &tmp[2]; + reg[4] = &low64.h_32; + reg[5] = &tmp[3]; + reg[6] = &low64.l_32; + + /* + * zero registers + */ + for(i=7;i--;) + *reg[i] = 0; + + /* + * fill registers with their components + */ + for(i=4;i--;) if (mp[i]) + for(j=4;j--;) if (mc[j]) { + k = i+j; + tmp[0] = (long)mp[i] * (long)mc[j]; +# ifdef PRT_EXT2 + printf("%04x * %04x == %08X ",mp[i],mc[j],tmp[0]); + printf("index == %d ",k); + printf("register before add == %08X\n",*reg[k]); + fflush(stdout); +# endif +#ifdef PRT_ADD + printf("REGISTERS-----\n"); + printf("%08X %08X %08X %08X\n0000%04x %04x%04x %04x%04x %04x0000\n", + *reg[0],*reg[2],*reg[4],*reg[6], + (short)(*reg[1]>>16),(short)(*reg[1]),(short)(*reg[3]>>16), + (short)(*reg[3]),(short)(*reg[5]>>16),(short)(*reg[5])); +# endif + if (b32_add(reg[k],tmp)) { + for(tmp[0] = 0x10000L;k>0;) + if (b32_add(reg[--k],tmp) == 0) + break; +#ifdef PRT_ADD + printf("CARRY---------\n"); + printf("%08X %08X %08X %08X\n0000%04x %04x%04x %04x%04x %04x0000\n", + *reg[0],*reg[2],*reg[4],*reg[6], + (short)(*reg[1]>>16),(short)(*reg[1]),(short)(*reg[3]>>16), + (short)(*reg[3]),(short)(*reg[5]>>16),(short)(*reg[5])); +#endif + } + } + + /* + * combine the registers to a total + */ +#ifdef PRT_ADD + printf("%08X %08X %08X %08X\n0000%04x %04x%04x %04x%04x %04x0000\n", + *reg[0],*reg[2],*reg[4],*reg[6], + (short)(*reg[1]>>16),(short)(*reg[1]),(short)(*reg[3]>>16), + (short)(*reg[3]),(short)(*reg[5]>>16),(short)(*reg[5])); +# endif + tmp64.h_32 = (*reg[1]>>16); + tmp64.l_32 = (*reg[1]<<16) + (*reg[3]>>16); +# ifdef PRT_ALL + printf("%08X%08X tmp64\n",tmp64.h_32,tmp64.l_32); + fflush(stdout); + printf("%08X%08X e1->m1\n",e1->m1,e1->m2); + fflush(stdout); +# endif + b64_add((B64 *)&e1->m1,&tmp64); +# ifdef PRT_ALL + printf("b64_add:\n"); + printf("%08X%08X e1->m1\n",e1->m1,e1->m2); + fflush(stdout); +# endif + tmp64.l_32 = *reg[5]<<16; + tmp64.h_32 = (*reg[5]>>16) + (*reg[3]<<16); + if (b64_add(&low64,&tmp64)) + if (++e1->m2 == 0) + e1->m1++; + +# ifdef PRT_ADD + printf("%08X %08X %08X %08X\n",e1->m1,e1->m2,low64.h_32,low64.l_32); + fflush(stdout); +#endif +#ifdef PRT_EXT + prt_ext("after MUL_EXT() e1:",e1); +#endif PRT_EXT + nrm_ext(e1); +#ifdef PRT_EXT + prt_ext("after NRM_EXT() e1:",e1); + sleep(4); +#endif PRT_EXT +} diff --git a/mach/proto/fp/ngf4.c b/mach/proto/fp/ngf4.c new file mode 100644 index 000000000..03540f374 --- /dev/null +++ b/mach/proto/fp/ngf4.c @@ -0,0 +1,20 @@ +/* + NEGATE A FLOATING POINT +*/ +/********************************************************/ +/* + Assumes exponent is located in bytes 0 & 1 +*/ +/********************************************************/ + +#include "FP_types.h" + +ngf4(f) +_float f; +{ + char unsigned *p; + + p = (char unsigned *) &f; + *p ^= 0x80; +} + diff --git a/mach/proto/fp/ngf8.c b/mach/proto/fp/ngf8.c new file mode 100644 index 000000000..994ee5634 --- /dev/null +++ b/mach/proto/fp/ngf8.c @@ -0,0 +1,20 @@ +/* + NEGATE A FLOATING POINT +*/ +/********************************************************/ +/* + Assumes exponent is located in bytes 0 & 1 +*/ +/********************************************************/ + +#include "FP_types.h" + +ngf8(f) +_double f; +{ + unsigned char *p; + + p = (unsigned char *) &f; + *p ^= 0x80; +} + diff --git a/mach/proto/fp/nrm_ext.c b/mach/proto/fp/nrm_ext.c new file mode 100644 index 000000000..97530718d --- /dev/null +++ b/mach/proto/fp/nrm_ext.c @@ -0,0 +1,72 @@ +/********************************************************/ +/* + NORMALIZE an EXTENDED FORMAT NUMBER +*/ +/********************************************************/ + +#include "FP_shift.h" +#include "FP_types.h" + +nrm_ext(e1) +EXTEND *e1; +{ + register unsigned long *mant_1; + register unsigned long *mant_2; + + /* local CAST conversion */ +#ifdef PRT_EXT + prt_ext("before NRM_EXT() e1:",e1); +#endif PRT_EXT + mant_1 = (unsigned long *) &e1->m1; + /* + THIS RESULTS IN A BAD CODE !!!! + ANOTHER BUG IN EM CODE MAYBE???? + mant_2 = (unsigned long *) &e1->m2; + */ + /* statement that works */ + mant_2 = mant_1 + 1; + + /* we assume that the mantissa != 0 */ + /* if it is then just return */ + /* to let it be a problem elsewhere */ + /* THAT IS, The exponent is not set to */ + /* zero. If we don't test here an */ + /* infinite loop is generated when */ + /* mantissa is zero */ + + if ((*mant_1 | *mant_2) == 0L) + return; + + /* if top word is zero mov low word */ + /* to top word, adjust exponent value */ + if (*mant_1 == 0L) { + *mant_1++ = e1->m2; + *mant_1-- = 0L; + e1->exp -= 32; + } +#ifdef OLD + /* check that e1->m1 is not too large */ + if (*mant_1 & CARRYBIT) { /* carry occured */ + e1->exp++; /* increase exponent */ + *mant_2 >>= 1; /* right shift mantissa */ + if ((short) *mant_1 & 01) + *mant_2 |= CARRYBIT; + *mant_1 >>= 1; + } +#endif + + + while ((*mant_1 & NORMBIT) == 0) { + e1->exp--; + *mant_1 <<= 1; + if ((*mant_2 & CARRYBIT) == 0) + ; /* empty statement */ + else { + *mant_1 += 1; + } + *mant_2 <<= 1; + } +#ifdef PRT_EXT + prt_ext("after NRM_EXT() e1:",e1); +#endif PRT_EXT +} diff --git a/mach/proto/fp/prt_dbl.c b/mach/proto/fp/prt_dbl.c new file mode 100644 index 000000000..388e1e65a --- /dev/null +++ b/mach/proto/fp/prt_dbl.c @@ -0,0 +1,25 @@ +# include "FP_types.h" + +prt_dbl(dbl,size) +DOUBLE *dbl; +int size; +{ +#ifdef PRT_DBL + unsigned long *l; + + fprintf(stderr,"PRT_DBL SIZE = %d ",size); + fprintf(stderr,"_s.p1.fract = 0x%08X ",dbl->_s.p1.fract); + if (size == 8) + fprintf(stderr,"_s.p2 = 0x%08X",dbl->_s.p2); + l = (unsigned long *) dbl; +#ifdef PRT_LONG + fprintf(stderr,"\nl[0] = 0x%08X ",*l++); + if (size == 8) + fprintf(stderr,"l[1] = 0x%08X",*l); +#endif PRT_LONG + putc('\r',stderr); + putc('\n',stderr); + fflush(stderr); +#endif +} + diff --git a/mach/proto/fp/prt_ext.c b/mach/proto/fp/prt_ext.c new file mode 100644 index 000000000..9859365b6 --- /dev/null +++ b/mach/proto/fp/prt_ext.c @@ -0,0 +1,23 @@ +/********************************************************/ +/* + PRINT EXTENDED FORMAT AND MESSAGE + DEBUG ROUTINE +*/ +/********************************************************/ + +#include "FP_types.h" + +prt_ext(m,e) +char *m; +EXTEND *e; +{ +#ifdef PRT_EXT + fprintf(stderr,"%s ",m); + fprintf(stderr,"%c",(e->sign) ? '-' : '+'); + fprintf(stderr,"m1:0x%08X m2:0x%08X ^ %03d 0x%x\n", + e->m1,e->m2,e->exp,e->exp); + fprintf(stderr,"hit any key\n\r"); + fflush(stderr); + getchar(); +#endif +} diff --git a/mach/proto/fp/sbf4.c b/mach/proto/fp/sbf4.c new file mode 100644 index 000000000..0a747dcdc --- /dev/null +++ b/mach/proto/fp/sbf4.c @@ -0,0 +1,23 @@ +/* + SUBTRACT TWO FLOATS - SINGLE Precision +*/ + +#include "FP_types.h" + +extern _float adf4(); + +_float +sbf4(s2,s1) +_float s1,s2; +{ + /* changing the sign directly */ + /* is faster than the code: */ + /* s2 = -s2 */ + char unsigned *p; + + p = (char unsigned *) &s2; + *p ^= 0x80; /* change sign of s2 */ + s1 = adf4(s2,s1); + return(s1); /* add and return result */ +} + diff --git a/mach/proto/fp/sbf8.c b/mach/proto/fp/sbf8.c new file mode 100644 index 000000000..1194d66c4 --- /dev/null +++ b/mach/proto/fp/sbf8.c @@ -0,0 +1,26 @@ +/* + SUBTRACT TWO FLOATS - DOUBLE Precision +*/ + +#include "FP_types.h" + +extern _double adf8(); + +_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 */ + +#ifdef PRT_EXT + fprintf(stderr,"SBF8 ():\n"); +#endif + p = (char unsigned *) &s2; + *p ^= 0x80; /* change sign of s2 */ + s1 = adf8(s2,s1); /* add and return result */ + return(s1); +} + diff --git a/mach/proto/fp/sft_ext.c b/mach/proto/fp/sft_ext.c new file mode 100644 index 000000000..f74245a2b --- /dev/null +++ b/mach/proto/fp/sft_ext.c @@ -0,0 +1,62 @@ +/* +#define PRT_EXT + SHIFT TWO EXTENDED NUMBERS INTO PROPER + ALIGNMENT FOR ADDITION (exponents are equal) +*/ + +#include "FP_types.h" + +sft_ext(e1,e2) +EXTEND *e1,*e2; +{ + register EXTEND *s; + register short diff; + long tmp; + +#ifdef PRT_EXT + prt_ext("enter sft_ext e1:",e1); + prt_ext("enter sft_ext e2:",e2); +#endif PRT_EXT + diff = e1->exp - e2->exp; + + if (!diff) + return; /* exponents are equal */ + + if (diff < 0) { /* e2 is larger */ + /* shift e1 */ + diff = -diff; + s = e1; + } + else /* e1 is larger */ + /* shift e2 */ + s = e2; + + s->exp += diff; + + if (diff > 63) { /* no relative value */ + s->m1 = 0L; + s->m2 = 0L; + return; + } + + if (diff > 32) { + diff -= 32; + s->m2 = s->m1; + s->m1 = 0L; + } + if (diff) { + if (s->m1) { + tmp = s->m1; + tmp <<= (32-diff); + s->m1 >>= diff; + } + else + tmp = 0L; + s->m2 >>= diff; + s->m2 |= tmp; + } +#ifdef PRT_EXT + prt_ext("exit sft_ext e1:",e1); + prt_ext("exit sft_ext e2:",e2); +#endif PRT_EXT +} diff --git a/mach/proto/fp/shifter.c b/mach/proto/fp/shifter.c new file mode 100644 index 000000000..094cfa631 --- /dev/null +++ b/mach/proto/fp/shifter.c @@ -0,0 +1,20 @@ +# include "adder.h" + +b64_sft(e1,n) +B64 *e1; +short n; +{ + if (n>0) do { /* RIGHT shift n bits */ + e1->l_32 >>= 1; /* shift 64 bits */ + if (e1->h_32 & 1) + e1->l_32 |= 0x80000000L; + e1->h_32 >>= 1; + } while (--n); + else /* LEFT shift n bits */ + while (n++) { + e1->h_32 <<= 1; /* shift 64 bits */ + if (e1->l_32 & 0x80000000L) + e1->h_32 |= 1; + e1->l_32 <<= 1; + } +} diff --git a/mach/proto/fp/sub_ext.c b/mach/proto/fp/sub_ext.c new file mode 100644 index 000000000..a5a069e19 --- /dev/null +++ b/mach/proto/fp/sub_ext.c @@ -0,0 +1,28 @@ +/* +#define PRT_EXT + SUBTRACT EXTENDED FORMAT +*/ + /* assumes that e1 >= e2 on entry */ + /* no test is made to check this */ + /* so make sure yourself */ + +#include "FP_types.h" +sub_ext(e1,e2) +EXTEND *e1,*e2; +{ +#ifdef PRT_EXT + prt_ext("before SUB_EXT() e1:",e1); + prt_ext("before SUB_EXT() e2:",e2); +#endif PRT_EXT + if (e2->m2 > e1->m2) + e1->m1 -= 1; /* carry in */ + e1->m1 -= e2->m1; + e1->m2 -= e2->m2; +#ifdef PRT_EXT + prt_ext("after SUB_EXT() e1:",e1); +#endif PRT_EXT + nrm_ext(e1); +#ifdef PRT_EXT + prt_ext("after NRM_EXT() e1:",e1); +#endif PRT_EXT +} diff --git a/mach/proto/fp/x b/mach/proto/fp/x new file mode 100644 index 000000000..e69de29bb diff --git a/mach/proto/fp/zrf4.c b/mach/proto/fp/zrf4.c new file mode 100644 index 000000000..04946d388 --- /dev/null +++ b/mach/proto/fp/zrf4.c @@ -0,0 +1,11 @@ +/* + return a zero float +*/ + +#include "FP_types.h" + +zrf4(l) +long *l; +{ + *l = 0L; +} diff --git a/mach/proto/fp/zrf8.c b/mach/proto/fp/zrf8.c new file mode 100644 index 000000000..3b1db3074 --- /dev/null +++ b/mach/proto/fp/zrf8.c @@ -0,0 +1,13 @@ +/* + return a zero double +*/ + +#include "FP_types.h" + +zrf8(z) +_double *z; +{ + + z->__double[0] = 0L; + z->__double[1] = 0L; +} diff --git a/mach/proto/fp/zrf_ext.c b/mach/proto/fp/zrf_ext.c new file mode 100644 index 000000000..529ca0e80 --- /dev/null +++ b/mach/proto/fp/zrf_ext.c @@ -0,0 +1,20 @@ +/* + ZERO and return EXTEND FORMAT FLOAT +*/ + +#include "FP_types.h" + +zrf_ext(e) +EXTEND *e; +{ + register short *ipt; + register short i; + register short zero = 0; + + /* local CAST conversion */ + ipt = (short *) e; + + i = sizeof(EXTEND)/sizeof(short); + while (i--) + *ipt++ = zero; +}