ack subdir for combined ack/gcc library build

This commit is contained in:
Ben Gras 2005-10-10 15:27:47 +00:00
parent 04822e9cc9
commit 8c53e4007e
322 changed files with 17865 additions and 0 deletions

12
lib/ack/Makefile Normal file
View File

@ -0,0 +1,12 @@
SUBDIRS = \
float \
fphook \
i386 \
libm2 \
libp \
liby \
math \
rts \
include ../Makefile.inc

11
lib/ack/Makefile.ack Normal file
View File

@ -0,0 +1,11 @@
all:
cd float && make
cd fphook && make
cd `arch` && make
cd libm2 && make
cd libp && make
cd liby && make
cd math && make
cd rts && make

19
lib/ack/float/FP.compile Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
# Author: Kees J. Bot
# Compile one soft FP source file.
# (These files shouldn't be optimized normally, but the 16-bit C compiler
# only optimizes scratch register allocation a bit with -O. To the 32-bit
# compiler -O is a no-op.)
case $#:$1 in
1:*.fc) ;;
*) echo "$0: $1: not a FC file" >&2; exit 1
esac
base="`basename "$1" .fc`"
trap 'rm -f tmp.c tmp.s"; exit 1' 2
cp "$1" tmp.c &&
cc -O -I. -D_MINIX -D_POSIX_SOURCE -S tmp.c &&
sed -f FP.script tmp.s > "$base.s" &&
rm tmp.c tmp.s

39
lib/ack/float/FP.script Executable file
View File

@ -0,0 +1,39 @@
s/_adf4/.adf4/
s/_adf8/.adf8/
s/_cff4/.cff4/
s/_cff8/.cff8/
s/_cfi/.cfi/
s/_cfu/.cfu/
s/_cif4/.cif4/
s/_cif8/.cif8/
s/_cmf4/.cmf4/
s/_cmf8/.cmf8/
s/_cuf4/.cuf4/
s/_cuf8/.cuf8/
s/_dvf4/.dvf4/
s/_dvf8/.dvf8/
s/_fef4/.fef4/
s/_fef8/.fef8/
s/_fif4/.fif4/
s/_fif8/.fif8/
s/_mlf4/.mlf4/
s/_mlf8/.mlf8/
s/_ngf4/.ngf4/
s/_ngf8/.ngf8/
s/_sbf4/.sbf4/
s/_sbf8/.sbf8/
s/_zrf4/.zrf4/
s/_zrf8/.zrf8/
s/_add_ext/.add_ext/
s/_div_ext/.div_ext/
s/_mul_ext/.mul_ext/
s/_nrm_ext/.nrm_ext/
s/_sft_ext/.sft_ext/
s/_sub_ext/.sub_ext/
s/_zrf_ext/.zrf_ext/
s/_compact/.compact/
s/_extend/.extend/
s/_b64_add/.b64_add/
s/_b64_sft/.b64_sft/
s/_b64_rsft/.b64_rsft/
s/_b64_lsft/.b64_lsft/

28
lib/ack/float/FP_bias.h Executable file
View File

@ -0,0 +1,28 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
include file for floating point package
*/
/* 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 254 /* standard definition */
#define SGL_MIN 1 /* standard definition */
#define DBL_MAX 2046 /* standard definition */
#define DBL_MIN 1 /* standard definition */
#define EXT_MAX 16383 /* standard minimum */
#define EXT_MIN -16382 /* standard minimum */

49
lib/ack/float/FP_shift.h Executable file
View File

@ -0,0 +1,49 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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 */
/* 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

22
lib/ack/float/FP_trap.h Executable file
View File

@ -0,0 +1,22 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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)

113
lib/ack/float/FP_types.h Executable file
View File

@ -0,0 +1,113 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/********************************************************/
/*
Type definitions for C Floating Point Package
include file for floating point package
*/
/********************************************************/
/*
THESE STRUCTURES ARE USED TO ADDRESS THE INDIVIDUAL
PARTS OF THE FLOATING POINT NUMBER REPRESENTATIONS.
THREE STRUCTURES ARE DEFINED:
SINGLE: single precision floating format
DOUBLE: double precision floating format
EXTEND: double precision extended format
*/
/********************************************************/
#ifndef __FPTYPES
#define __FPTYPES
typedef struct {
unsigned long h_32; /* higher 32 bits of 64 */
unsigned long l_32; /* lower 32 bits of 64 */
} B64;
typedef unsigned long SINGLE;
typedef struct {
unsigned long d[2];
} DOUBLE;
typedef struct { /* expanded float format */
short sign;
short exp;
B64 mantissa;
#define m1 mantissa.h_32
#define m2 mantissa.l_32
} EXTEND;
struct fef4_returns {
int e;
SINGLE f;
};
struct fef8_returns {
int e;
DOUBLE f;
};
struct fif4_returns {
SINGLE ipart;
SINGLE fpart;
};
struct fif8_returns {
DOUBLE ipart;
DOUBLE fpart;
};
#if __STDC__
#define _PROTOTYPE(function, params) function params
#else
#define _PROTOTYPE(function, params) function()
#endif
_PROTOTYPE( void add_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void mul_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void div_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void sub_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void sft_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void nrm_ext, (EXTEND *e1));
_PROTOTYPE( void zrf_ext, (EXTEND *e1));
_PROTOTYPE( void extend, (unsigned long *from, EXTEND *to, int size));
_PROTOTYPE( void compact, (EXTEND *from, unsigned long *to, int size));
_PROTOTYPE( void _fptrp, (int));
_PROTOTYPE( void adf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( void adf8, (DOUBLE s2, DOUBLE s1));
_PROTOTYPE( void sbf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( void sbf8, (DOUBLE s2, DOUBLE s1));
_PROTOTYPE( void dvf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( void dvf8, (DOUBLE s2, DOUBLE s1));
_PROTOTYPE( void mlf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( void mlf8, (DOUBLE s2, DOUBLE s1));
_PROTOTYPE( void ngf4, (SINGLE f));
_PROTOTYPE( void ngf8, (DOUBLE f));
_PROTOTYPE( void zrf4, (SINGLE *l));
_PROTOTYPE( void zrf8, (DOUBLE *z));
_PROTOTYPE( void cff4, (DOUBLE src));
_PROTOTYPE( void cff8, (SINGLE src));
_PROTOTYPE( void cif4, (int ss, long src));
_PROTOTYPE( void cif8, (int ss, long src));
_PROTOTYPE( void cuf4, (int ss, long src));
_PROTOTYPE( void cuf8, (int ss, long src));
_PROTOTYPE( long cfu, (int ds, int ss, DOUBLE src));
_PROTOTYPE( long cfi, (int ds, int ss, DOUBLE src));
_PROTOTYPE( int cmf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( int cmf8, (DOUBLE d1, DOUBLE d2));
_PROTOTYPE( void fef4, (struct fef4_returns *r, SINGLE s1));
_PROTOTYPE( void fef8, (struct fef8_returns *r, DOUBLE s1));
_PROTOTYPE( void fif4, (struct fif4_returns *p, SINGLE x, SINGLE y));
_PROTOTYPE( void fif8, (struct fif8_returns *p, DOUBLE x, DOUBLE y));
_PROTOTYPE( void b64_sft, (B64 *, int));
_PROTOTYPE( void b64_lsft, (B64 *));
_PROTOTYPE( void b64_rsft, (B64 *));
_PROTOTYPE( int b64_add, (B64 *, B64 *));
#endif

61
lib/ack/float/Makefile Normal file
View File

@ -0,0 +1,61 @@
# Makefile for lib/float.
CC1 = /bin/sh ./FP.compile
LIBRARIES = libfp
libfp_OBJECTS = \
add_ext.o \
adder.o \
adf4.o \
adf8.o \
cff4.o \
cff8.o \
cfi.o \
cfu.o \
cif4.o \
cif8.o \
cmf4.o \
cmf8.o \
compact.o \
cuf4.o \
cuf8.o \
div_ext.o \
dvf4.o \
dvf8.o \
extend.o \
fef4.o \
fef8.o \
fif4.o \
fif8.o \
fptrp.o \
mlf4.o \
mlf8.o \
mul_ext.o \
ngf4.o \
ngf8.o \
nrm_ext.o \
sbf4.o \
sbf8.o \
sft_ext.o \
shifter.o \
sub_ext.o \
zrf4.o \
zrf8.o \
zrf_ext.o \
include ../../Makefile.ack.inc
#extra commands to convert the c files to the correct assembler files
%.s: %.fc
/bin/sh ./FP.compile $<
#1. make a assembler file of the c file
#%.fs: %.fc
# -cp $< $(<:.fc=.c) && cc -O -I. -D_MINIX -D_POSIX_SOURCE -S $(<:.fc=.c) && cp $(<:.fc=.s) $(<:.fc=.fs)
# @rm $(<:.fc=.c) $(<:.fc=.s)
#2. modify the assembler file
#%.s: %.fs
# sed -f FP.script $< > $@

56
lib/ack/float/add_ext.fc Executable file
View File

@ -0,0 +1,56 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
ADD TWO EXTENDED FORMAT NUMBERS
*/
#include "FP_types.h"
void
add_ext(e1,e2)
register EXTEND *e1,*e2;
{
if ((e2->m1 | e2->m2) == 0L) {
return;
}
if ((e1->m1 | e1->m2) == 0L) {
*e1 = *e2;
return;
}
sft_ext(e1, e2); /* adjust mantissas to equal powers */
if (e1->sign != e2->sign) {
/* e1 + e2 = e1 - (-e2) */
if (e2->m1 > e1->m1 ||
(e2->m1 == e1->m1 && e2->m2 > e1->m2)) {
/* abs(e2) > abs(e1) */
EXTEND x;
x = *e1;
*e1 = *e2;
if (x.m2 > e1->m2) {
e1->m1 -= 1; /* carry in */
}
e1->m1 -= x.m1;
e1->m2 -= x.m2;
}
else {
if (e2->m2 > e1->m2)
e1->m1 -= 1; /* carry in */
e1->m1 -= e2->m1;
e1->m2 -= e2->m2;
}
}
else {
if (b64_add(&e1->mantissa,&e2->mantissa)) { /* addition carry */
b64_rsft(&e1->mantissa); /* shift mantissa one bit RIGHT */
e1->m1 |= 0x80000000L; /* set max bit */
e1->exp++; /* increase the exponent */
}
}
nrm_ext(e1);
}

50
lib/ack/float/adder.fc Executable file
View File

@ -0,0 +1,50 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
* these are the routines the routines to do 32 and 64-bit addition
*/
# ifdef EXT_DEBUG
# include <stdio.h>
# endif
# include "FP_types.h"
# define UNKNOWN -1
# define TRUE 1
# define FALSE 0
# define MAXBIT 0x80000000L
/*
* add 64 bits
*/
int
b64_add(e1,e2)
/*
* pointers to 64 bit 'registers'
*/
register B64 *e1,*e2;
{
register int overflow;
int carry;
/* add higher pair of 32 bits */
overflow = ((unsigned long) 0xFFFFFFFF - e1->h_32 < e2->h_32);
e1->h_32 += e2->h_32;
/* add lower pair of 32 bits */
carry = ((unsigned long) 0xFFFFFFFF - e1->l_32 < e2->l_32);
e1->l_32 += e2->l_32;
# ifdef EXT_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 */
return(overflow); /* return status from higher add */
}

15
lib/ack/float/adder.h Executable file
View File

@ -0,0 +1,15 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
* include file for 32 & 64 bit addition
*/
typedef struct B64 {
unsigned long h_32; /* higher 32 bits of 64 */
unsigned long l_32; /* lower 32 bits of 64 */
} B64;

32
lib/ack/float/adf4.fc Executable file
View File

@ -0,0 +1,32 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
ADD TWO FLOATS - SINGLE (ADF 4)
*/
#include "FP_types.h"
void
adf4(s2,s1)
SINGLE s1,s2;
{
EXTEND e1,e2;
int swap = 0;
if (s1 == (SINGLE) 0) {
s1 = s2;
return;
}
if (s2 == (SINGLE) 0) {
return;
}
extend(&s1,&e1,sizeof(SINGLE));
extend(&s2,&e2,sizeof(SINGLE));
add_ext(&e1,&e2);
compact(&e1,&s1,sizeof(SINGLE));
}

32
lib/ack/float/adf8.fc Executable file
View File

@ -0,0 +1,32 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
ADD TWO FLOATS - DOUBLE (ADF 8)
*/
#include "FP_types.h"
void
adf8(s2,s1)
DOUBLE s1,s2;
{
EXTEND e1,e2;
if (s1.d[0] == 0 && s1.d[1] == 0) {
s1 = s2;
return;
}
if (s2.d[0] == 0 && s2.d[1] == 0) {
return;
}
extend(&s1.d[0],&e1,sizeof(DOUBLE));
extend(&s2.d[0],&e2,sizeof(DOUBLE));
add_ext(&e1,&e2);
compact(&e1,&s1.d[0],sizeof(DOUBLE));
}

6
lib/ack/float/byte_order.h Executable file
View File

@ -0,0 +1,6 @@
#define CHAR_UNSIGNED 0
#define MSB_AT_LOW_ADDRESS 0
#define MSW_AT_LOW_ADDRESS 0
#define FL_MSB_AT_LOW_ADDRESS 0
#define FL_MSW_AT_LOW_ADDRESS 0
#define FL_MSL_AT_LOW_ADDRESS 0

28
lib/ack/float/cff4.fc Executable file
View File

@ -0,0 +1,28 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT DOUBLE TO SINGLE (CFF 8 4)
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"
void
cff4(src)
DOUBLE src; /* the source itself - THIS TIME it's DOUBLE */
{
EXTEND buf;
extend(&src.d[0],&buf,sizeof(DOUBLE)); /* no matter what */
compact(&buf,&(src.d[1]),sizeof(SINGLE));
}

28
lib/ack/float/cff8.fc Executable file
View File

@ -0,0 +1,28 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT SINGLE TO DOUBLE (CFF 4 8)
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"
void
cff8(src)
SINGLE src;
{
EXTEND buf;
extend(&src,&buf,sizeof(SINGLE)); /* no matter what */
compact(&buf, &src,sizeof(DOUBLE));
}

52
lib/ack/float/cfi.fc Executable file
View File

@ -0,0 +1,52 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT FLOAT TO SIGNED (CFI m n)
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"
#include "FP_shift.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 max_exp;
extend(&src.d[0],&buf,ss); /* get extended format */
if (buf.exp < 0) { /* no conversion needed */
src.d[ss == 8] = 0L;
return(0L);
}
max_exp = (ds << 3) - 2; /* signed numbers */
/* have more limited max_exp */
if (buf.exp > max_exp) {
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 >> (31-buf.exp);
if (buf.sign)
new = -new;
done:
src.d[ss == 8] = new;
return(new);
}

43
lib/ack/float/cfu.fc Executable file
View File

@ -0,0 +1,43 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT FLOAT TO UNSIGNED (CFU m n)
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.d[0],&buf,ss); /* get extended format */
if (buf.exp < 0) { /* no conversion needed */
src.d[ss == 8] = 0L;
return(0L);
}
max_exp = (ds << 3) - 1;
if (buf.exp > max_exp) {
trap(EIOVFL); /* integer overflow */
buf.exp %= max_exp;
}
new = buf.m1 >> (31-buf.exp);
done:
src.d[ss == 8] = new;
return(new);
}

56
lib/ack/float/cif4.fc Executable file
View File

@ -0,0 +1,56 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT INTEGER TO SINGLE (CIF n 4)
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"
void
cif4(ss,src)
int ss; /* source size */
long src; /* largest possible integer to convert */
{
EXTEND buf;
short *ipt;
long i_src;
SINGLE *result;
zrf_ext(&buf);
if (ss == sizeof(long)) {
buf.exp = 31;
i_src = src;
result = (SINGLE *) &src;
}
else {
ipt = (short *) &src;
i_src = (long) *ipt;
buf.exp = 15;
result = (SINGLE *) &ss;
}
if (i_src == 0) {
*result = (SINGLE) 0L;
return;
}
/* 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 */
compact(&buf, result,sizeof(SINGLE)); /* put on stack */
}

55
lib/ack/float/cif8.fc Executable file
View File

@ -0,0 +1,55 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT INTEGER TO FLOAT (CIF n 8)
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"
void
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 *) ((void *) &ss); /* always */
zrf_ext(&buf);
if (ss == sizeof(long)) {
buf.exp = 31;
i_src = src;
}
else {
ipt = (short *) &src;
i_src = (long) *ipt;
buf.exp = 15;
}
if (i_src == 0) {
zrf8(result);
return;
}
/* 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);
compact(&buf,&result->d[0],8);
}

40
lib/ack/float/cmf4.fc Executable file
View File

@ -0,0 +1,40 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
COMPARE SINGLES (CMF 4)
*/
#include "FP_types.h"
#include "get_put.h"
int
cmf4(f1,f2)
SINGLE 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) {
if ((l1 & 0x7fffffff) == 0 &&
(l2 & 0x7fffffff) == 0) return 0;
return ((sign1 > 0) ? -1 : 1);
}
return (sign1 * ((l1 < l2) ? 1 : -1));
}

61
lib/ack/float/cmf8.fc Executable file
View File

@ -0,0 +1,61 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
COMPARE DOUBLES (CMF 8)
*/
#include "FP_types.h"
#include "get_put.h"
int
cmf8(d1,d2)
DOUBLE d1,d2;
{
#define SIGN(x) (((x) < 0) ? -1 : 1)
/*
* return ((d1 < d2) ? 1 : (d1 > d2) ? -1 : 0))
*/
long l1,l2;
int sign1,sign2;
int rv;
#if FL_MSL_AT_LOW_ADDRESS
l1 = get4((char *)&d1);
l2 = get4((char *)&d2);
#else
l1 = get4(((char *)&d1+4));
l2 = get4(((char *)&d2+4));
#endif
sign1 = SIGN(l1);
sign2 = SIGN(l2);
if (sign1 != sign2) {
l1 &= 0x7fffffff;
l2 &= 0x7fffffff;
if (l1 != 0 || l2 != 0) {
return ((sign1 > 0) ? -1 : 1);
}
}
if (l1 != l2) { /* we can decide here */
rv = l1 < l2 ? 1 : -1;
}
else { /* decide in 2nd half */
unsigned long u1, u2;
#if FL_MSL_AT_LOW_ADDRESS
u1 = get4(((char *)&d1 + 4));
u2 = get4(((char *)&d2 + 4));
#else
u1 = get4((char *)&d1);
u2 = get4((char *)&d2);
#endif
if (u1 == u2)
return(0);
if (u1 < u2) rv = 1;
else rv = -1;
}
return sign1 * rv;
}

202
lib/ack/float/compact.fc Executable file
View File

@ -0,0 +1,202 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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"
void
compact(f,to,size)
EXTEND *f;
unsigned long *to;
int size;
{
int error = 0;
if (size == sizeof(DOUBLE)) {
/*
* COMPACT EXTENDED INTO DOUBLE
*/
DOUBLE *DBL = (DOUBLE *) (void *) to;
if ((f->m1|(f->m2 & DBL_ZERO)) == 0L) {
zrf8(DBL);
return;
}
f->exp += DBL_BIAS; /* restore proper bias */
if (f->exp > DBL_MAX) {
dbl_over: trap(EFOVFL);
f->exp = DBL_MAX+1;
f->m1 = 0;
f->m2 = 0;
if (error++)
return;
}
else if (f->exp < DBL_MIN) {
b64_rsft(&(f->mantissa));
if (f->exp < 0) {
b64_sft(&(f->mantissa), -f->exp);
f->exp = 0;
}
/* underflow ??? */
}
/* local CAST conversion */
/* because of special format shift only 10 bits */
/* bit shift mantissa 10 bits */
/* first align within words, then do store operation */
DBL->d[0] = f->m1 >> DBL_RUNPACK; /* plus 22 == 32 */
DBL->d[1] = f->m2 >> DBL_RUNPACK; /* plus 22 == 32 */
DBL->d[1] |= (f->m1 << DBL_LUNPACK); /* plus 10 == 32 */
/* if not exact then round to nearest */
/* on a tie, round to even */
#ifdef EXCEPTION_INEXACT
if ((f->m2 & DBL_EXACT) != 0) {
INEXACT();
#endif
if (((f->m2 & DBL_EXACT) > DBL_ROUNDUP)
|| ((f->m2 & DBL_EXACT) == DBL_ROUNDUP
&& (f->m2 & (DBL_ROUNDUP << 1)))) {
DBL->d[1]++; /* rounding up */
if (DBL->d[1] == 0L) { /* carry out */
DBL->d[0]++;
if (f->exp == 0 && (DBL->d[0] & ~DBL_MASK)) {
f->exp++;
}
if (DBL->d[0] & DBL_CARRYOUT) { /* carry out */
if (DBL->d[0] & 01)
DBL->d[1] = CARRYBIT;
DBL->d[0] >>= 1;
f->exp++;
}
}
/* check for overflow */
if (f->exp > DBL_MAX)
goto dbl_over;
}
#ifdef EXCEPTION_INEXACT
}
#endif
/*
* STORE EXPONENT AND SIGN:
*
* 1) clear leading bits (B4-B15)
* 2) shift and store exponent
*/
DBL->d[0] &= DBL_MASK;
DBL->d[0] |=
((long) (f->exp << DBL_EXPSHIFT) << EXP_STORE);
if (f->sign)
DBL->d[0] |= CARRYBIT;
/*
* STORE MANTISSA
*/
#if FL_MSL_AT_LOW_ADDRESS
put4(DBL->d[0], (char *) &DBL->d[0]);
put4(DBL->d[1], (char *) &DBL->d[1]);
#else
{ unsigned long l;
put4(DBL->d[1], (char *) &l);
put4(DBL->d[0], (char *) &DBL->d[1]);
DBL->d[0] = l;
}
#endif
}
else {
/*
* COMPACT EXTENDED INTO FLOAT
*/
SINGLE *SGL;
/* local CAST conversion */
SGL = (SINGLE *) (void *) to;
if ((f->m1 & SGL_ZERO) == 0L) {
*SGL = 0L;
return;
}
f->exp += SGL_BIAS; /* restore bias */
if (f->exp > SGL_MAX) {
sgl_over: trap(EFOVFL);
f->exp = SGL_MAX+1;
f->m1 = 0L;
f->m2 = 0L;
if (error++)
return;
}
else if (f->exp < SGL_MIN) {
b64_rsft(&(f->mantissa));
if (f->exp < 0) {
b64_sft(&(f->mantissa), -f->exp);
f->exp = 0;
}
/* underflow ??? */
}
/* shift mantissa and store */
*SGL = (f->m1 >> SGL_RUNPACK);
/* check for rounding to nearest */
/* on a tie, round to even */
#ifdef EXCEPTION_INEXACT
if (f->m2 != 0 ||
(f->m1 & SGL_EXACT) != 0L) {
INEXACT();
#endif
if (((f->m1 & SGL_EXACT) > SGL_ROUNDUP)
|| ((f->m1 & SGL_EXACT) == SGL_ROUNDUP
&& (f->m1 & (SGL_ROUNDUP << 1)))) {
(*SGL)++;
if (f->exp == 0 && (*SGL & ~SGL_MASK)) {
f->exp++;
}
/* check normal */
if (*SGL & SGL_CARRYOUT) {
*SGL >>= 1;
f->exp++;
}
if (f->exp > SGL_MAX)
goto sgl_over;
}
#ifdef EXCEPTION_INEXACT
}
#endif
/*
* STORE EXPONENT AND SIGN:
*
* 1) clear leading bit of fraction
* 2) shift and store exponent
*/
*SGL &= SGL_MASK; /* B23-B31 are 0 */
*SGL |= ((long) (f->exp << SGL_EXPSHIFT) << EXP_STORE);
if (f->sign)
*SGL |= CARRYBIT;
/*
* STORE MANTISSA
*/
put4(*SGL, (char *) &SGL);
}
}

57
lib/ack/float/cuf4.fc Executable file
View File

@ -0,0 +1,57 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT INTEGER TO SINGLE (CUF n 4)
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"
void
cuf4(ss,src)
int ss; /* source size */
long src; /* largest possible integer to convert */
{
EXTEND buf;
short *ipt;
SINGLE *result;
long i_src;
zrf_ext(&buf);
if (ss == sizeof(long)) {
buf.exp = 31;
i_src = src;
result = (SINGLE *) &src;
}
else {
ipt = (short *) &src;
i_src = (long) *ipt;
buf.exp = 15;
result = (SINGLE *) ((void *) &ss);
}
if (i_src == 0) {
*result = (SINGLE) 0L;
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);
compact(&buf,result,4);
}

54
lib/ack/float/cuf8.fc Executable file
View File

@ -0,0 +1,54 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT INTEGER TO FLOAT (CUF n 8)
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"
void
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 = 31;
i_src = src;
}
else {
ipt = (short *) &src;
i_src = (long) *ipt;
buf.exp = 15;
}
if (i_src == 0) {
zrf8((DOUBLE *)((void *)&ss));
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);
compact(&buf,(unsigned long *) (void *)&ss,8);
}

266
lib/ack/float/div_ext.fc Executable file
View File

@ -0,0 +1,266 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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.
There are two versions:
One is based on the partial products method
and makes no use possible machine instructions
to divide (hardware dividers).
The other is used when USE_DIVIDE is defined. It is much faster on
machines with fast 4 byte operations.
*/
/********************************************************/
void
div_ext(e1,e2)
EXTEND *e1,*e2;
{
short error = 0;
B64 result;
register unsigned long *lp;
#ifndef USE_DIVIDE
short count;
#else
unsigned short u[9], v[5];
register int j;
register unsigned short *u_p = u;
int maxv = 4;
#endif
if ((e2->m1 | e2->m2) == 0) {
/*
* Exception 8.2 - Divide by zero
*/
trap(EFDIVZ);
e1->m1 = e1->m2 = 0L;
e1->exp = EXT_MAX;
return;
}
if ((e1->m1 | e1->m2) == 0) { /* 0 / anything == 0 */
e1->exp = 0; /* make sure */
return;
}
#ifndef USE_DIVIDE
/*
* numbers are right shifted one bit to make sure
* that m1 is quaranteed to be larger if its
* maximum bit is set
*/
b64_rsft(&e1->mantissa); /* 64 bit shift right */
b64_rsft(&e2->mantissa); /* 64 bit shift right */
e1->exp++;
e2->exp++;
#endif
/* check for underflow, divide by zero, etc */
e1->sign ^= e2->sign;
e1->exp -= e2->exp;
#ifndef USE_DIVIDE
/* do division of mantissas */
/* uses partial product method */
/* init control variables */
count = 64;
result.h_32 = 0L;
result.l_32 = 0L;
/* partial product division loop */
while (count--) {
/* first left shift result 1 bit */
/* this is ALWAYS done */
b64_lsft(&result);
/* compare dividend and divisor */
/* if dividend >= divisor add a bit */
/* and subtract divisior from dividend */
if ( (e1->m1 < e2->m1) ||
((e1->m1 == e2->m1) && (e1->m2 < e2->m2) ))
; /* null statement */
/* i.e., don't add or subtract */
else {
result.l_32++; /* ADD */
if (e2->m2 > e1->m2)
e1->m1 -= 1; /* carry in */
e1->m1 -= e2->m1; /* do SUBTRACTION */
e1->m2 -= e2->m2; /* SUBTRACTION */
}
/* 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_lsft(&e1->mantissa);
continue;
}
else
break; /* leave loop */
} /* end of divide by subtraction loop */
if (count > 0) {
lp = &result.h_32;
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.l_32 */
if (*lp) {
result.h_32 |= (*lp >> 32-count);
*lp <<= count;
}
}
#else /* USE_DIVIDE */
u[4] = (e1->m2 & 1) << 15;
b64_rsft(&(e1->mantissa));
u[0] = e1->m1 >> 16;
u[1] = e1->m1;
u[2] = e1->m2 >> 16;
u[3] = e1->m2;
u[5] = 0; u[6] = 0; u[7] = 0;
v[1] = e2->m1 >> 16;
v[2] = e2->m1;
v[3] = e2->m2 >> 16;
v[4] = e2->m2;
while (! v[maxv]) maxv--;
result.h_32 = 0;
result.l_32 = 0;
lp = &result.h_32;
/*
* Use an algorithm of Knuth (The art of programming, Seminumerical
* algorithms), to divide u by v. u and v are both seen as numbers
* with base 65536.
*/
for (j = 0; j <= 3; j++, u_p++) {
unsigned long q_est, temp;
if (j == 2) lp++;
if (u_p[0] == 0 && u_p[1] < v[1]) continue;
temp = ((unsigned long)u_p[0] << 16) + u_p[1];
if (u_p[0] >= v[1]) {
q_est = 0x0000FFFFL;
}
else {
q_est = temp / v[1];
}
temp -= q_est * v[1];
while (temp < 0x10000 && v[2]*q_est > ((temp<<16)+u_p[2])) {
q_est--;
temp += v[1];
}
/* Now, according to Knuth, we have an estimate of the
quotient, that is either correct or one too big, but
almost always correct.
*/
if (q_est != 0) {
int i;
unsigned long k = 0;
int borrow = 0;
for (i = maxv; i > 0; i--) {
unsigned long tmp = q_est * v[i] + k + borrow;
unsigned short md = tmp;
borrow = (md > u_p[i]);
u_p[i] -= md;
k = tmp >> 16;
}
k += borrow;
borrow = u_p[0] < k;
u_p[0] -= k;
if (borrow) {
/* So, this does not happen often; the estimate
was one too big; correct this
*/
*lp |= (j & 1) ? (q_est - 1) : ((q_est-1)<<16);
borrow = 0;
for (i = maxv; i > 0; i--) {
unsigned long tmp
= v[i]+(unsigned long)u_p[i]+borrow;
u_p[i] = tmp;
borrow = tmp >> 16;
}
u_p[0] += borrow;
}
else *lp |= (j & 1) ? q_est : (q_est<<16);
}
}
#ifdef EXCEPTION_INEXACT
u_p = &u[0];
for (j = 7; j >= 0; j--) {
if (*u_p++) {
error = 1;
break;
}
}
#endif
#endif
#ifdef EXCEPTION_INEXACT
if (error) {
/*
* report here exception 8.5 - Inexact
* from Draft 8.0 of IEEE P754:
* In the absence of an invalid operation exception,
* if the rounded result of an operation is not exact or if
* it overflows without a trap, then the inexact exception
* shall be assigned. The rounded or overflowed result
* shall be delivered to the destination.
*/
INEXACT();
#endif
e1->mantissa = result;
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;
}
}

26
lib/ack/float/dvf4.fc Executable file
View File

@ -0,0 +1,26 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
DIVIDE TWO SINGLES - SINGLE Precision (dvf 4)
*/
#include "FP_types.h"
void
dvf4(s2,s1)
SINGLE s1,s2;
{
EXTEND e1,e2;
extend(&s1,&e1,sizeof(SINGLE));
extend(&s2,&e2,sizeof(SINGLE));
/* do a divide */
div_ext(&e1,&e2);
compact(&e1,&s1,sizeof(SINGLE));
}

26
lib/ack/float/dvf8.fc Executable file
View File

@ -0,0 +1,26 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
DIVIDE TWO FLOATS - DOUBLE Precision (DVF 8)
*/
#include "FP_types.h"
void
dvf8(s2,s1)
DOUBLE s1,s2;
{
EXTEND e1,e2;
extend(&s1.d[0],&e1,sizeof(DOUBLE));
extend(&s2.d[0],&e2,sizeof(DOUBLE));
/* do a divide */
div_ext(&e1,&e2);
compact(&e1,&s1.d[0],sizeof(DOUBLE));
}

111
lib/ack/float/extend.fc Executable file
View File

@ -0,0 +1,111 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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 <SIGN>
->exp 0EEE EEEE | EEEE EEEE <EXPONENT>
->m1 LFFF FFFF | FFFF FFFF <L.Fraction>
FFFF FFFF | FFFF FFFF <Fraction>
->m2 FFFF FFFF | FFFF FFFF <Fraction>
FFFF F000 | 0000 0000 <Fraction>
*/
/********************************************************/
#include "FP_bias.h"
#include "FP_shift.h"
#include "FP_types.h"
#include "get_put.h"
/********************************************************/
void
extend(from,to,size)
unsigned long *from;
EXTEND *to;
int size;
{
register char *cpt1;
unsigned long tmp;
int leadbit = 0;
cpt1 = (char *) from;
#if FL_MSL_AT_LOW_ADDRESS
#if FL_MSW_AT_LOW_ADDRESS
to->exp = uget2(cpt1);
#else
to->exp = uget2(cpt1+2);
#endif
#else
#if FL_MSW_AT_LOW_ADDRESS
to->exp = uget2(cpt1+(size == sizeof(DOUBLE) ? 4 : 0));
#else
to->exp = uget2(cpt1+(size == sizeof(DOUBLE) ? 6 : 2));
#endif
#endif
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 */
else to->exp++;
if (size == sizeof(DOUBLE)) {
#if FL_MSL_AT_LOW_ADDRESS
to->m1 = get4(cpt1);
cpt1 += 4;
tmp = get4(cpt1);
#else
tmp = get4(cpt1);
cpt1 += 4;
to->m1 = get4(cpt1);
#endif
if (to->exp == 1 && to->m1 == 0 && tmp == 0) {
to->exp = 0;
to->sign = 0;
to->m1 = 0;
to->m2 = 0;
return;
}
to->m1 <<= DBL_M1LEFT; /* shift */
to->exp -= DBL_BIAS; /* remove bias */
to->m1 |= (tmp>>DBL_RPACK); /* plus 10 == 32 */
to->m2 = (tmp<<DBL_LPACK); /* plus 22 == 32 */
}
else { /* size == sizeof(SINGLE) */
to->m1 = get4(cpt1);
to->m1 <<= SGL_M1LEFT; /* shift */
if (to->exp == 1 && to->m1 == 0) {
to->exp = 0;
to->sign = 0;
to->m1 = 0;
to->m2 = 0;
return;
}
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 */
nrm_ext(to); /* and normalize */
}
}

33
lib/ack/float/fef4.fc Executable file
View File

@ -0,0 +1,33 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SEPERATE INTO EXPONENT AND FRACTION (FEF 4)
*/
#include "FP_types.h"
void
fef4(r,s1)
SINGLE s1;
struct fef4_returns *r;
{
EXTEND buf;
register struct fef4_returns *p = r; /* make copy; r might refer
to itself (see table)
*/
extend(&s1,&buf,sizeof(SINGLE));
if (buf.exp == 0 && buf.m1 == 0 && buf.m2 == 0) {
p->e = 0;
}
else {
p->e = buf.exp+1;
buf.exp = -1;
}
compact(&buf,&p->f,sizeof(SINGLE));
}

33
lib/ack/float/fef8.fc Executable file
View File

@ -0,0 +1,33 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SEPERATE DOUBLE INTO EXPONENT AND FRACTION (FEF 8)
*/
#include "FP_types.h"
void
fef8(r, s1)
DOUBLE s1;
struct fef8_returns *r;
{
EXTEND buf;
register struct fef8_returns *p = r; /* make copy, r might refer
to itself (see table)
*/
extend(&s1.d[0],&buf,sizeof(DOUBLE));
if (buf.exp == 0 && buf.m1 == 0 && buf.m2 == 0) {
p->e = 0;
}
else {
p->e = buf.exp + 1;
buf.exp = -1;
}
compact(&buf,&p->f.d[0],sizeof(DOUBLE));
}

46
lib/ack/float/fif4.fc Executable file
View File

@ -0,0 +1,46 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
MULTIPLY AND DISMEMBER PARTS (FIF 4)
*/
#include "FP_types.h"
#include "FP_shift.h"
void
fif4(p,x,y)
SINGLE x,y;
struct fif4_returns *p;
{
EXTEND e1,e2;
extend(&y,&e1,sizeof(SINGLE));
extend(&x,&e2,sizeof(SINGLE));
/* do a multiply */
mul_ext(&e1,&e2);
e2 = e1;
compact(&e2,&y,sizeof(SINGLE));
if (e1.exp < 0) {
p->ipart = 0;
p->fpart = y;
return;
}
if (e1.exp > 30 - SGL_M1LEFT) {
p->ipart = y;
p->fpart = 0;
return;
}
b64_sft(&e1.mantissa, 63 - e1.exp);
b64_sft(&e1.mantissa, e1.exp - 63); /* "loose" low order bits */
compact(&e1,&(p->ipart),sizeof(SINGLE));
extend(&(p->ipart), &e2, sizeof(SINGLE));
extend(&y, &e1, sizeof(SINGLE));
sub_ext(&e1, &e2);
compact(&e1, &(p->fpart), sizeof(SINGLE));
}

48
lib/ack/float/fif8.fc Executable file
View File

@ -0,0 +1,48 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
MULTIPLY AND DISMEMBER PARTS (FIF 8)
*/
#include "FP_types.h"
#include "FP_shift.h"
void
fif8(p,x,y)
DOUBLE x,y;
struct fif8_returns *p;
{
EXTEND e1,e2;
extend(&y.d[0],&e1,sizeof(DOUBLE));
extend(&x.d[0],&e2,sizeof(DOUBLE));
/* do a multiply */
mul_ext(&e1,&e2);
e2 = e1;
compact(&e2, &y.d[0], sizeof(DOUBLE));
if (e1.exp < 0) {
p->ipart.d[0] = 0;
p->ipart.d[1] = 0;
p->fpart = y;
return;
}
if (e1.exp > 62 - DBL_M1LEFT) {
p->ipart = y;
p->fpart.d[0] = 0;
p->fpart.d[1] = 0;
return;
}
b64_sft(&e1.mantissa, 63 - e1.exp);
b64_sft(&e1.mantissa, e1.exp - 63); /* "loose" low order bits */
compact(&e1, &(p->ipart.d[0]), sizeof(DOUBLE));
extend(&(p->ipart.d[0]), &e2, sizeof(DOUBLE));
extend(&y.d[0], &e1, sizeof(DOUBLE));
sub_ext(&e1, &e2);
compact(&e1, &(p->fpart.d[0]), sizeof(DOUBLE));
}

19
lib/ack/float/fptrp.s Executable file
View File

@ -0,0 +1,19 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
.define __fptrp
.sect .text
__fptrp:
#if __i386
push ebp
mov ebp, esp
mov eax, 8(bp)
call .Xtrp
leave
ret
#else /* i86 */
push bp
mov bp, sp
mov ax, 4(bp)
call .Xtrp
jmp .cret
#endif

41
lib/ack/float/get_put.h Executable file
View File

@ -0,0 +1,41 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
#include <byte_order.h>
#if CHAR_UNSIGNED
#define Xchar(ch) (ch)
#else
#define Xchar(ch) ((ch) & 0377)
#endif
#define BYTES_REVERSED (MSB_AT_LOW_ADDRESS != FL_MSB_AT_LOW_ADDRESS)
#define WORDS_REVERSED (MSW_AT_LOW_ADDRESS != FL_MSW_AT_LOW_ADDRESS)
#define LONGS_REVERSED (FL_MSL_AT_LOW_ADDRESS)
#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

25
lib/ack/float/mlf4.fc Executable file
View File

@ -0,0 +1,25 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
* Multiply Single Precesion Float (MLF 4)
*/
#include "FP_types.h"
void
mlf4(s2,s1)
SINGLE s1,s2;
{
EXTEND e1,e2;
extend(&s1,&e1,sizeof(SINGLE));
extend(&s2,&e2,sizeof(SINGLE));
/* do a multiply */
mul_ext(&e1,&e2);
compact(&e1,&s1,sizeof(SINGLE));
}

25
lib/ack/float/mlf8.fc Executable file
View File

@ -0,0 +1,25 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
* Multiply Double Precision Float (MLF 8)
*/
#include "FP_types.h"
void
mlf8(s2,s1)
DOUBLE s1,s2;
{
EXTEND e1,e2;
extend(&s1.d[0],&e1,sizeof(DOUBLE));
extend(&s2.d[0],&e2,sizeof(DOUBLE));
/* do a multiply */
mul_ext(&e1,&e2);
compact(&e1,&s1.d[0],sizeof(DOUBLE));
}

98
lib/ack/float/mul_ext.fc Executable file
View File

@ -0,0 +1,98 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
ROUTINE TO MULTIPLY TWO EXTENDED FORMAT NUMBERS
*/
# include "FP_bias.h"
# include "FP_trap.h"
# include "FP_types.h"
# include "FP_shift.h"
void
mul_ext(e1,e2)
EXTEND *e1,*e2;
{
register int i,j; /* loop control */
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;
/* compute new exponent */
e1->exp += e2->exp + 1;
/* 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;
for (i = 8; i--;) {
result[i] = 0;
}
/*
* fill registers with their components
*/
for(i=4, pres = &result[4];i--;pres--) if (mp[i]) {
unsigned short k = 0;
unsigned long mpi = mp[i];
for(j=4;j--;) {
unsigned long tmp = (unsigned long)pres[j] + k;
if (mc[j]) tmp += mpi * mc[j];
pres[j] = tmp;
k = tmp >> 16;
}
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
*/
e1->m1 = ((unsigned long)(result[0]) << 16) + result[1];
e1->m2 = ((unsigned long)(result[2]) << 16) + result[3];
if (result[4] & 0x8000) {
if (++e1->m2 == 0)
if (++e1->m1 == 0) {
e1->m1 = NORMBIT;
e1->exp++;
}
}
/* 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;
}
}

27
lib/ack/float/ngf4.fc Executable file
View File

@ -0,0 +1,27 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
NEGATE A FLOATING POINT (NGF 4)
*/
/********************************************************/
#include "FP_types.h"
#include "get_put.h"
#define OFF ((FL_MSW_AT_LOW_ADDRESS ? 0 : 2) + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
void
ngf4(f)
SINGLE f;
{
unsigned char *p;
if (f != (SINGLE) 0) {
p = (unsigned char *) &f + OFF;
*p ^= 0x80;
}
}

28
lib/ack/float/ngf8.fc Executable file
View File

@ -0,0 +1,28 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
NEGATE A FLOATING POINT (NGF 8)
*/
/********************************************************/
#include "FP_types.h"
#include "get_put.h"
#define OFF ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
void
ngf8(f)
DOUBLE f;
{
unsigned char *p;
if (f.d[0] != 0 || f.d[1] != 0) {
p = (unsigned char *) &f + OFF;
*p ^= 0x80;
}
}

50
lib/ack/float/nrm_ext.fc Executable file
View File

@ -0,0 +1,50 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/********************************************************/
/*
NORMALIZE an EXTENDED FORMAT NUMBER
*/
/********************************************************/
#include "FP_shift.h"
#include "FP_types.h"
void
nrm_ext(e1)
EXTEND *e1;
{
/* 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 ((e1->m1 | e1->m2) == 0L)
return;
/* if top word is zero mov low word */
/* to top word, adjust exponent value */
if (e1->m1 == 0L) {
e1->m1 = e1->m2;
e1->m2 = 0L;
e1->exp -= 32;
}
if ((e1->m1 & NORMBIT) == 0) {
unsigned long l = ((unsigned long)NORMBIT >> 1);
int cnt = -1;
while (! (l & e1->m1)) {
l >>= 1;
cnt--;
}
e1->exp += cnt;
b64_sft(&(e1->mantissa), cnt);
}
}

27
lib/ack/float/sbf4.fc Executable file
View File

@ -0,0 +1,27 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SUBTRACT TWO FLOATS - SINGLE Precision (SBF 4)
*/
#include "FP_types.h"
void
sbf4(s2,s1)
SINGLE s1,s2;
{
EXTEND e1,e2;
if (s2 == (SINGLE) 0) {
return;
}
extend(&s1,&e1,sizeof(SINGLE));
extend(&s2,&e2,sizeof(SINGLE));
sub_ext(&e1,&e2);
compact(&e1,&s1,sizeof(SINGLE));
}

27
lib/ack/float/sbf8.fc Executable file
View File

@ -0,0 +1,27 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SUBTRACT TWO FLOATS - DOUBLE Precision (SBF 8)
*/
#include "FP_types.h"
void
sbf8(s2,s1)
DOUBLE s1,s2;
{
EXTEND e1, e2;
if (s2.d[0] == 0 && s2.d[1] == 0) {
return;
}
extend(&s1.d[0],&e1,sizeof(DOUBLE));
extend(&s2.d[0],&e2,sizeof(DOUBLE));
sub_ext(&e1,&e2);
compact(&e1,&s1.d[0],sizeof(DOUBLE));
}

39
lib/ack/float/sft_ext.fc Executable file
View File

@ -0,0 +1,39 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SHIFT TWO EXTENDED NUMBERS INTO PROPER
ALIGNMENT FOR ADDITION (exponents are equal)
Numbers should not be zero on entry.
*/
#include "FP_types.h"
void
sft_ext(e1,e2)
EXTEND *e1,*e2;
{
register EXTEND *s;
register int diff;
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;
b64_sft(&(s->mantissa), diff);
}

75
lib/ack/float/shifter.fc Executable file
View File

@ -0,0 +1,75 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
# include "FP_types.h"
void
b64_sft(e1,n)
B64 *e1;
int n;
{
if (n > 0) {
if (n > 63) {
e1->l_32 = 0;
e1->h_32 = 0;
return;
}
if (n >= 32) {
e1->l_32 = e1->h_32;
e1->h_32 = 0;
n -= 32;
}
if (n > 0) {
e1->l_32 >>= n;
if (e1->h_32 != 0) {
e1->l_32 |= (e1->h_32 << (32 - n));
e1->h_32 >>= n;
}
}
return;
}
n = -n;
if (n > 0) {
if (n > 63) {
e1->l_32 = 0;
e1->h_32 = 0;
return;
}
if (n >= 32) {
e1->h_32 = e1->l_32;
e1->l_32 = 0;
n -= 32;
}
if (n > 0) {
e1->h_32 <<= n;
if (e1->l_32 != 0) {
e1->h_32 |= (e1->l_32 >> (32 - n));
e1->l_32 <<= n;
}
}
}
}
void
b64_lsft(e1)
B64 *e1;
{
/* shift left 1 bit */
e1->h_32 <<= 1;
if (e1->l_32 & 0x80000000L) e1->h_32 |= 1;
e1->l_32 <<= 1;
}
void
b64_rsft(e1)
B64 *e1;
{
/* shift right 1 bit */
e1->l_32 >>= 1;
if (e1->h_32 & 1) e1->l_32 |= 0x80000000L;
e1->h_32 >>= 1;
}

53
lib/ack/float/sub_ext.fc Executable file
View File

@ -0,0 +1,53 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SUBTRACT 2 EXTENDED FORMAT NUMBERS
*/
#include "FP_types.h"
void
sub_ext(e1,e2)
EXTEND *e1,*e2;
{
if ((e2->m1 | e2->m2) == 0L) {
return;
}
if ((e1->m1 | e1->m2) == 0L) {
*e1 = *e2;
e1->sign = e2->sign ? 0 : 1;
return;
}
sft_ext(e1, e2);
if (e1->sign != e2->sign) {
/* e1 - e2 = e1 + (-e2) */
if (b64_add(&e1->mantissa,&e2->mantissa)) { /* addition carry */
b64_rsft(&e1->mantissa); /* shift mantissa one bit RIGHT */
e1->m1 |= 0x80000000L; /* set max bit */
e1->exp++; /* increase the exponent */
}
}
else 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 */
}
e2->m1 -= e1->m1;
e2->m2 -= e1->m2;
*e1 = *e2;
e1->sign = e2->sign ? 0 : 1;
}
else {
if (e2->m2 > e1->m2)
e1->m1 -= 1; /* carry in */
e1->m1 -= e2->m1;
e1->m2 -= e2->m2;
}
nrm_ext(e1);
}

19
lib/ack/float/zrf4.fc Executable file
View File

@ -0,0 +1,19 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
return a zero float (ZRF 4)
*/
#include "FP_types.h"
void
zrf4(l)
SINGLE *l;
{
*l = 0L;
}

21
lib/ack/float/zrf8.fc Executable file
View File

@ -0,0 +1,21 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
return a zero double (ZRF 8)
*/
#include "FP_types.h"
void
zrf8(z)
DOUBLE *z;
{
z->d[0] = 0L;
z->d[1] = 0L;
}

22
lib/ack/float/zrf_ext.fc Executable file
View File

@ -0,0 +1,22 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
ZERO and return EXTEND FORMAT FLOAT
*/
#include "FP_types.h"
void
zrf_ext(e)
EXTEND *e;
{
e->m1 = 0;
e->m2 = 0;
e->exp = 0;
e->sign = 0;
}

19
lib/ack/fphook/FP.compile Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
# Author: Kees J. Bot
# Compile one soft FP source file.
# (These files shouldn't be optimized normally, but the 16-bit C compiler
# only optimizes scratch register allocation a bit with -O. To the 32-bit
# compiler -O is a no-op.)
case $#:$1 in
1:*.fc) ;;
*) echo "$0: $1: not a FC file" >&2; exit 1
esac
base="`basename "$1" .fc`"
trap 'rm -f tmp.c tmp.s"; exit 1' 2
cp "$1" tmp.c &&
cc -O -I. -D_MINIX -D_POSIX_SOURCE -S tmp.c &&
sed -f FP.script tmp.s > "$base.s" &&
rm tmp.c tmp.s

39
lib/ack/fphook/FP.script Executable file
View File

@ -0,0 +1,39 @@
s/_adf4/.adf4/
s/_adf8/.adf8/
s/_cff4/.cff4/
s/_cff8/.cff8/
s/_cfi/.cfi/
s/_cfu/.cfu/
s/_cif4/.cif4/
s/_cif8/.cif8/
s/_cmf4/.cmf4/
s/_cmf8/.cmf8/
s/_cuf4/.cuf4/
s/_cuf8/.cuf8/
s/_dvf4/.dvf4/
s/_dvf8/.dvf8/
s/_fef4/.fef4/
s/_fef8/.fef8/
s/_fif4/.fif4/
s/_fif8/.fif8/
s/_mlf4/.mlf4/
s/_mlf8/.mlf8/
s/_ngf4/.ngf4/
s/_ngf8/.ngf8/
s/_sbf4/.sbf4/
s/_sbf8/.sbf8/
s/_zrf4/.zrf4/
s/_zrf8/.zrf8/
s/_add_ext/.add_ext/
s/_div_ext/.div_ext/
s/_mul_ext/.mul_ext/
s/_nrm_ext/.nrm_ext/
s/_sft_ext/.sft_ext/
s/_sub_ext/.sub_ext/
s/_zrf_ext/.zrf_ext/
s/_compact/.compact/
s/_extend/.extend/
s/_b64_add/.b64_add/
s/_b64_sft/.b64_sft/
s/_b64_rsft/.b64_rsft/
s/_b64_lsft/.b64_lsft/

28
lib/ack/fphook/FP_bias.h Executable file
View File

@ -0,0 +1,28 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
include file for floating point package
*/
/* 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 254 /* standard definition */
#define SGL_MIN 1 /* standard definition */
#define DBL_MAX 2046 /* standard definition */
#define DBL_MIN 1 /* standard definition */
#define EXT_MAX 16383 /* standard minimum */
#define EXT_MIN -16382 /* standard minimum */

49
lib/ack/fphook/FP_shift.h Executable file
View File

@ -0,0 +1,49 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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 */
/* 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

22
lib/ack/fphook/FP_trap.h Executable file
View File

@ -0,0 +1,22 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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)

113
lib/ack/fphook/FP_types.h Executable file
View File

@ -0,0 +1,113 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/********************************************************/
/*
Type definitions for C Floating Point Package
include file for floating point package
*/
/********************************************************/
/*
THESE STRUCTURES ARE USED TO ADDRESS THE INDIVIDUAL
PARTS OF THE FLOATING POINT NUMBER REPRESENTATIONS.
THREE STRUCTURES ARE DEFINED:
SINGLE: single precision floating format
DOUBLE: double precision floating format
EXTEND: double precision extended format
*/
/********************************************************/
#ifndef __FPTYPES
#define __FPTYPES
typedef struct {
unsigned long h_32; /* higher 32 bits of 64 */
unsigned long l_32; /* lower 32 bits of 64 */
} B64;
typedef unsigned long SINGLE;
typedef struct {
unsigned long d[2];
} DOUBLE;
typedef struct { /* expanded float format */
short sign;
short exp;
B64 mantissa;
#define m1 mantissa.h_32
#define m2 mantissa.l_32
} EXTEND;
struct fef4_returns {
int e;
SINGLE f;
};
struct fef8_returns {
int e;
DOUBLE f;
};
struct fif4_returns {
SINGLE ipart;
SINGLE fpart;
};
struct fif8_returns {
DOUBLE ipart;
DOUBLE fpart;
};
#if __STDC__
#define _PROTOTYPE(function, params) function params
#else
#define _PROTOTYPE(function, params) function()
#endif
_PROTOTYPE( void add_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void mul_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void div_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void sub_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void sft_ext, (EXTEND *e1, EXTEND *e2));
_PROTOTYPE( void nrm_ext, (EXTEND *e1));
_PROTOTYPE( void zrf_ext, (EXTEND *e1));
_PROTOTYPE( void extend, (unsigned long *from, EXTEND *to, int size));
_PROTOTYPE( void compact, (EXTEND *from, unsigned long *to, int size));
_PROTOTYPE( void _fptrp, (int));
_PROTOTYPE( void adf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( void adf8, (DOUBLE s2, DOUBLE s1));
_PROTOTYPE( void sbf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( void sbf8, (DOUBLE s2, DOUBLE s1));
_PROTOTYPE( void dvf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( void dvf8, (DOUBLE s2, DOUBLE s1));
_PROTOTYPE( void mlf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( void mlf8, (DOUBLE s2, DOUBLE s1));
_PROTOTYPE( void ngf4, (SINGLE f));
_PROTOTYPE( void ngf8, (DOUBLE f));
_PROTOTYPE( void zrf4, (SINGLE *l));
_PROTOTYPE( void zrf8, (DOUBLE *z));
_PROTOTYPE( void cff4, (DOUBLE src));
_PROTOTYPE( void cff8, (SINGLE src));
_PROTOTYPE( void cif4, (int ss, long src));
_PROTOTYPE( void cif8, (int ss, long src));
_PROTOTYPE( void cuf4, (int ss, long src));
_PROTOTYPE( void cuf8, (int ss, long src));
_PROTOTYPE( long cfu, (int ds, int ss, DOUBLE src));
_PROTOTYPE( long cfi, (int ds, int ss, DOUBLE src));
_PROTOTYPE( int cmf4, (SINGLE s2, SINGLE s1));
_PROTOTYPE( int cmf8, (DOUBLE d1, DOUBLE d2));
_PROTOTYPE( void fef4, (struct fef4_returns *r, SINGLE s1));
_PROTOTYPE( void fef8, (struct fef8_returns *r, DOUBLE s1));
_PROTOTYPE( void fif4, (struct fif4_returns *p, SINGLE x, SINGLE y));
_PROTOTYPE( void fif8, (struct fif8_returns *p, DOUBLE x, DOUBLE y));
_PROTOTYPE( void b64_sft, (B64 *, int));
_PROTOTYPE( void b64_lsft, (B64 *));
_PROTOTYPE( void b64_rsft, (B64 *));
_PROTOTYPE( int b64_add, (B64 *, B64 *));
#endif

19
lib/ack/fphook/Makefile Normal file
View File

@ -0,0 +1,19 @@
# Makefile for lib/ack/fphook.
# The ACK ANSI C compiler has an nice trick to reduce the size of programs
# that do not use floating point. If a program uses floating point then the
# compiler generates an external reference to the label '_fp_hook'. This makes
# the loader bring in the floating point printing and conversion routines
# '_f_print' and 'strtod' from the library libd.a. Otherwise two dummy
# routines are found in libc.a. (The printf and scanf need floating point
# for the %f formats, whether you use them or not.)
CFLAGS = -O -D_MINIX -D_POSIX_SOURCE -I..
LIBRARIES = libd libc
libd_OBJECTS = fphook.o
libc_OBJECTS = fltpr.o strtod.o
include ../../Makefile.ack.inc

View File

@ -0,0 +1,32 @@
# Makefile for lib/i86/fphook.
# The ACK ANSI C compiler has an nice trick to reduce the size of programs
# that do not use floating point. If a program uses floating point then the
# compiler generates an external reference to the label '_fp_hook'. This makes
# the loader bring in the floating point printing and conversion routines
# '_f_print' and 'strtod' from the library libd.a. Otherwise two dummy
# routines are found in libc.a. (The printf and scanf need floating point
# for the %f formats, whether you use them or not.)
CFLAGS = -O -D_MINIX -D_POSIX_SOURCE
CC1 = $(CC) $(CFLAGS) -c -I$(SRCDIR)/ack
LIBD = ../../libd.a
LIBC = ../../libc.a
all: $(LIBD) $(LIBC)
$(LIBD): fphook.c
$(CC1) fphook.c
aal cr $@ fphook.o
rm fphook.o
$(LIBC): $(LIBC)(fltpr.o) $(LIBC)(strtod.o)
aal cr $@ *.o
rm *.o
$(LIBC)(fltpr.o): fltpr.c
$(CC1) fltpr.c
$(LIBC)(strtod.o): strtod.c
$(CC1) strtod.c

56
lib/ack/fphook/add_ext.fc Executable file
View File

@ -0,0 +1,56 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
ADD TWO EXTENDED FORMAT NUMBERS
*/
#include "FP_types.h"
void
add_ext(e1,e2)
register EXTEND *e1,*e2;
{
if ((e2->m1 | e2->m2) == 0L) {
return;
}
if ((e1->m1 | e1->m2) == 0L) {
*e1 = *e2;
return;
}
sft_ext(e1, e2); /* adjust mantissas to equal powers */
if (e1->sign != e2->sign) {
/* e1 + e2 = e1 - (-e2) */
if (e2->m1 > e1->m1 ||
(e2->m1 == e1->m1 && e2->m2 > e1->m2)) {
/* abs(e2) > abs(e1) */
EXTEND x;
x = *e1;
*e1 = *e2;
if (x.m2 > e1->m2) {
e1->m1 -= 1; /* carry in */
}
e1->m1 -= x.m1;
e1->m2 -= x.m2;
}
else {
if (e2->m2 > e1->m2)
e1->m1 -= 1; /* carry in */
e1->m1 -= e2->m1;
e1->m2 -= e2->m2;
}
}
else {
if (b64_add(&e1->mantissa,&e2->mantissa)) { /* addition carry */
b64_rsft(&e1->mantissa); /* shift mantissa one bit RIGHT */
e1->m1 |= 0x80000000L; /* set max bit */
e1->exp++; /* increase the exponent */
}
}
nrm_ext(e1);
}

50
lib/ack/fphook/adder.fc Executable file
View File

@ -0,0 +1,50 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
* these are the routines the routines to do 32 and 64-bit addition
*/
# ifdef EXT_DEBUG
# include <stdio.h>
# endif
# include "FP_types.h"
# define UNKNOWN -1
# define TRUE 1
# define FALSE 0
# define MAXBIT 0x80000000L
/*
* add 64 bits
*/
int
b64_add(e1,e2)
/*
* pointers to 64 bit 'registers'
*/
register B64 *e1,*e2;
{
register int overflow;
int carry;
/* add higher pair of 32 bits */
overflow = ((unsigned long) 0xFFFFFFFF - e1->h_32 < e2->h_32);
e1->h_32 += e2->h_32;
/* add lower pair of 32 bits */
carry = ((unsigned long) 0xFFFFFFFF - e1->l_32 < e2->l_32);
e1->l_32 += e2->l_32;
# ifdef EXT_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 */
return(overflow); /* return status from higher add */
}

15
lib/ack/fphook/adder.h Executable file
View File

@ -0,0 +1,15 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
* include file for 32 & 64 bit addition
*/
typedef struct B64 {
unsigned long h_32; /* higher 32 bits of 64 */
unsigned long l_32; /* lower 32 bits of 64 */
} B64;

32
lib/ack/fphook/adf4.fc Executable file
View File

@ -0,0 +1,32 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
ADD TWO FLOATS - SINGLE (ADF 4)
*/
#include "FP_types.h"
void
adf4(s2,s1)
SINGLE s1,s2;
{
EXTEND e1,e2;
int swap = 0;
if (s1 == (SINGLE) 0) {
s1 = s2;
return;
}
if (s2 == (SINGLE) 0) {
return;
}
extend(&s1,&e1,sizeof(SINGLE));
extend(&s2,&e2,sizeof(SINGLE));
add_ext(&e1,&e2);
compact(&e1,&s1,sizeof(SINGLE));
}

32
lib/ack/fphook/adf8.fc Executable file
View File

@ -0,0 +1,32 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
ADD TWO FLOATS - DOUBLE (ADF 8)
*/
#include "FP_types.h"
void
adf8(s2,s1)
DOUBLE s1,s2;
{
EXTEND e1,e2;
if (s1.d[0] == 0 && s1.d[1] == 0) {
s1 = s2;
return;
}
if (s2.d[0] == 0 && s2.d[1] == 0) {
return;
}
extend(&s1.d[0],&e1,sizeof(DOUBLE));
extend(&s2.d[0],&e2,sizeof(DOUBLE));
add_ext(&e1,&e2);
compact(&e1,&s1.d[0],sizeof(DOUBLE));
}

6
lib/ack/fphook/byte_order.h Executable file
View File

@ -0,0 +1,6 @@
#define CHAR_UNSIGNED 0
#define MSB_AT_LOW_ADDRESS 0
#define MSW_AT_LOW_ADDRESS 0
#define FL_MSB_AT_LOW_ADDRESS 0
#define FL_MSW_AT_LOW_ADDRESS 0
#define FL_MSL_AT_LOW_ADDRESS 0

28
lib/ack/fphook/cff4.fc Executable file
View File

@ -0,0 +1,28 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT DOUBLE TO SINGLE (CFF 8 4)
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"
void
cff4(src)
DOUBLE src; /* the source itself - THIS TIME it's DOUBLE */
{
EXTEND buf;
extend(&src.d[0],&buf,sizeof(DOUBLE)); /* no matter what */
compact(&buf,&(src.d[1]),sizeof(SINGLE));
}

28
lib/ack/fphook/cff8.fc Executable file
View File

@ -0,0 +1,28 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT SINGLE TO DOUBLE (CFF 4 8)
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"
void
cff8(src)
SINGLE src;
{
EXTEND buf;
extend(&src,&buf,sizeof(SINGLE)); /* no matter what */
compact(&buf, &src,sizeof(DOUBLE));
}

52
lib/ack/fphook/cfi.fc Executable file
View File

@ -0,0 +1,52 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT FLOAT TO SIGNED (CFI m n)
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"
#include "FP_shift.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 max_exp;
extend(&src.d[0],&buf,ss); /* get extended format */
if (buf.exp < 0) { /* no conversion needed */
src.d[ss == 8] = 0L;
return(0L);
}
max_exp = (ds << 3) - 2; /* signed numbers */
/* have more limited max_exp */
if (buf.exp > max_exp) {
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 >> (31-buf.exp);
if (buf.sign)
new = -new;
done:
src.d[ss == 8] = new;
return(new);
}

43
lib/ack/fphook/cfu.fc Executable file
View File

@ -0,0 +1,43 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT FLOAT TO UNSIGNED (CFU m n)
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.d[0],&buf,ss); /* get extended format */
if (buf.exp < 0) { /* no conversion needed */
src.d[ss == 8] = 0L;
return(0L);
}
max_exp = (ds << 3) - 1;
if (buf.exp > max_exp) {
trap(EIOVFL); /* integer overflow */
buf.exp %= max_exp;
}
new = buf.m1 >> (31-buf.exp);
done:
src.d[ss == 8] = new;
return(new);
}

56
lib/ack/fphook/cif4.fc Executable file
View File

@ -0,0 +1,56 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT INTEGER TO SINGLE (CIF n 4)
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"
void
cif4(ss,src)
int ss; /* source size */
long src; /* largest possible integer to convert */
{
EXTEND buf;
short *ipt;
long i_src;
SINGLE *result;
zrf_ext(&buf);
if (ss == sizeof(long)) {
buf.exp = 31;
i_src = src;
result = (SINGLE *) &src;
}
else {
ipt = (short *) &src;
i_src = (long) *ipt;
buf.exp = 15;
result = (SINGLE *) &ss;
}
if (i_src == 0) {
*result = (SINGLE) 0L;
return;
}
/* 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 */
compact(&buf, result,sizeof(SINGLE)); /* put on stack */
}

55
lib/ack/fphook/cif8.fc Executable file
View File

@ -0,0 +1,55 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT INTEGER TO FLOAT (CIF n 8)
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"
void
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 *) ((void *) &ss); /* always */
zrf_ext(&buf);
if (ss == sizeof(long)) {
buf.exp = 31;
i_src = src;
}
else {
ipt = (short *) &src;
i_src = (long) *ipt;
buf.exp = 15;
}
if (i_src == 0) {
zrf8(result);
return;
}
/* 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);
compact(&buf,&result->d[0],8);
}

40
lib/ack/fphook/cmf4.fc Executable file
View File

@ -0,0 +1,40 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
COMPARE SINGLES (CMF 4)
*/
#include "FP_types.h"
#include "get_put.h"
int
cmf4(f1,f2)
SINGLE 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) {
if ((l1 & 0x7fffffff) == 0 &&
(l2 & 0x7fffffff) == 0) return 0;
return ((sign1 > 0) ? -1 : 1);
}
return (sign1 * ((l1 < l2) ? 1 : -1));
}

61
lib/ack/fphook/cmf8.fc Executable file
View File

@ -0,0 +1,61 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
COMPARE DOUBLES (CMF 8)
*/
#include "FP_types.h"
#include "get_put.h"
int
cmf8(d1,d2)
DOUBLE d1,d2;
{
#define SIGN(x) (((x) < 0) ? -1 : 1)
/*
* return ((d1 < d2) ? 1 : (d1 > d2) ? -1 : 0))
*/
long l1,l2;
int sign1,sign2;
int rv;
#if FL_MSL_AT_LOW_ADDRESS
l1 = get4((char *)&d1);
l2 = get4((char *)&d2);
#else
l1 = get4(((char *)&d1+4));
l2 = get4(((char *)&d2+4));
#endif
sign1 = SIGN(l1);
sign2 = SIGN(l2);
if (sign1 != sign2) {
l1 &= 0x7fffffff;
l2 &= 0x7fffffff;
if (l1 != 0 || l2 != 0) {
return ((sign1 > 0) ? -1 : 1);
}
}
if (l1 != l2) { /* we can decide here */
rv = l1 < l2 ? 1 : -1;
}
else { /* decide in 2nd half */
unsigned long u1, u2;
#if FL_MSL_AT_LOW_ADDRESS
u1 = get4(((char *)&d1 + 4));
u2 = get4(((char *)&d2 + 4));
#else
u1 = get4((char *)&d1);
u2 = get4((char *)&d2);
#endif
if (u1 == u2)
return(0);
if (u1 < u2) rv = 1;
else rv = -1;
}
return sign1 * rv;
}

202
lib/ack/fphook/compact.fc Executable file
View File

@ -0,0 +1,202 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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"
void
compact(f,to,size)
EXTEND *f;
unsigned long *to;
int size;
{
int error = 0;
if (size == sizeof(DOUBLE)) {
/*
* COMPACT EXTENDED INTO DOUBLE
*/
DOUBLE *DBL = (DOUBLE *) (void *) to;
if ((f->m1|(f->m2 & DBL_ZERO)) == 0L) {
zrf8(DBL);
return;
}
f->exp += DBL_BIAS; /* restore proper bias */
if (f->exp > DBL_MAX) {
dbl_over: trap(EFOVFL);
f->exp = DBL_MAX+1;
f->m1 = 0;
f->m2 = 0;
if (error++)
return;
}
else if (f->exp < DBL_MIN) {
b64_rsft(&(f->mantissa));
if (f->exp < 0) {
b64_sft(&(f->mantissa), -f->exp);
f->exp = 0;
}
/* underflow ??? */
}
/* local CAST conversion */
/* because of special format shift only 10 bits */
/* bit shift mantissa 10 bits */
/* first align within words, then do store operation */
DBL->d[0] = f->m1 >> DBL_RUNPACK; /* plus 22 == 32 */
DBL->d[1] = f->m2 >> DBL_RUNPACK; /* plus 22 == 32 */
DBL->d[1] |= (f->m1 << DBL_LUNPACK); /* plus 10 == 32 */
/* if not exact then round to nearest */
/* on a tie, round to even */
#ifdef EXCEPTION_INEXACT
if ((f->m2 & DBL_EXACT) != 0) {
INEXACT();
#endif
if (((f->m2 & DBL_EXACT) > DBL_ROUNDUP)
|| ((f->m2 & DBL_EXACT) == DBL_ROUNDUP
&& (f->m2 & (DBL_ROUNDUP << 1)))) {
DBL->d[1]++; /* rounding up */
if (DBL->d[1] == 0L) { /* carry out */
DBL->d[0]++;
if (f->exp == 0 && (DBL->d[0] & ~DBL_MASK)) {
f->exp++;
}
if (DBL->d[0] & DBL_CARRYOUT) { /* carry out */
if (DBL->d[0] & 01)
DBL->d[1] = CARRYBIT;
DBL->d[0] >>= 1;
f->exp++;
}
}
/* check for overflow */
if (f->exp > DBL_MAX)
goto dbl_over;
}
#ifdef EXCEPTION_INEXACT
}
#endif
/*
* STORE EXPONENT AND SIGN:
*
* 1) clear leading bits (B4-B15)
* 2) shift and store exponent
*/
DBL->d[0] &= DBL_MASK;
DBL->d[0] |=
((long) (f->exp << DBL_EXPSHIFT) << EXP_STORE);
if (f->sign)
DBL->d[0] |= CARRYBIT;
/*
* STORE MANTISSA
*/
#if FL_MSL_AT_LOW_ADDRESS
put4(DBL->d[0], (char *) &DBL->d[0]);
put4(DBL->d[1], (char *) &DBL->d[1]);
#else
{ unsigned long l;
put4(DBL->d[1], (char *) &l);
put4(DBL->d[0], (char *) &DBL->d[1]);
DBL->d[0] = l;
}
#endif
}
else {
/*
* COMPACT EXTENDED INTO FLOAT
*/
SINGLE *SGL;
/* local CAST conversion */
SGL = (SINGLE *) (void *) to;
if ((f->m1 & SGL_ZERO) == 0L) {
*SGL = 0L;
return;
}
f->exp += SGL_BIAS; /* restore bias */
if (f->exp > SGL_MAX) {
sgl_over: trap(EFOVFL);
f->exp = SGL_MAX+1;
f->m1 = 0L;
f->m2 = 0L;
if (error++)
return;
}
else if (f->exp < SGL_MIN) {
b64_rsft(&(f->mantissa));
if (f->exp < 0) {
b64_sft(&(f->mantissa), -f->exp);
f->exp = 0;
}
/* underflow ??? */
}
/* shift mantissa and store */
*SGL = (f->m1 >> SGL_RUNPACK);
/* check for rounding to nearest */
/* on a tie, round to even */
#ifdef EXCEPTION_INEXACT
if (f->m2 != 0 ||
(f->m1 & SGL_EXACT) != 0L) {
INEXACT();
#endif
if (((f->m1 & SGL_EXACT) > SGL_ROUNDUP)
|| ((f->m1 & SGL_EXACT) == SGL_ROUNDUP
&& (f->m1 & (SGL_ROUNDUP << 1)))) {
(*SGL)++;
if (f->exp == 0 && (*SGL & ~SGL_MASK)) {
f->exp++;
}
/* check normal */
if (*SGL & SGL_CARRYOUT) {
*SGL >>= 1;
f->exp++;
}
if (f->exp > SGL_MAX)
goto sgl_over;
}
#ifdef EXCEPTION_INEXACT
}
#endif
/*
* STORE EXPONENT AND SIGN:
*
* 1) clear leading bit of fraction
* 2) shift and store exponent
*/
*SGL &= SGL_MASK; /* B23-B31 are 0 */
*SGL |= ((long) (f->exp << SGL_EXPSHIFT) << EXP_STORE);
if (f->sign)
*SGL |= CARRYBIT;
/*
* STORE MANTISSA
*/
put4(*SGL, (char *) &SGL);
}
}

57
lib/ack/fphook/cuf4.fc Executable file
View File

@ -0,0 +1,57 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT INTEGER TO SINGLE (CUF n 4)
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"
void
cuf4(ss,src)
int ss; /* source size */
long src; /* largest possible integer to convert */
{
EXTEND buf;
short *ipt;
SINGLE *result;
long i_src;
zrf_ext(&buf);
if (ss == sizeof(long)) {
buf.exp = 31;
i_src = src;
result = (SINGLE *) &src;
}
else {
ipt = (short *) &src;
i_src = (long) *ipt;
buf.exp = 15;
result = (SINGLE *) ((void *) &ss);
}
if (i_src == 0) {
*result = (SINGLE) 0L;
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);
compact(&buf,result,4);
}

54
lib/ack/fphook/cuf8.fc Executable file
View File

@ -0,0 +1,54 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
CONVERT INTEGER TO FLOAT (CUF n 8)
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"
void
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 = 31;
i_src = src;
}
else {
ipt = (short *) &src;
i_src = (long) *ipt;
buf.exp = 15;
}
if (i_src == 0) {
zrf8((DOUBLE *)((void *)&ss));
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);
compact(&buf,(unsigned long *) (void *)&ss,8);
}

266
lib/ack/fphook/div_ext.fc Executable file
View File

@ -0,0 +1,266 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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.
There are two versions:
One is based on the partial products method
and makes no use possible machine instructions
to divide (hardware dividers).
The other is used when USE_DIVIDE is defined. It is much faster on
machines with fast 4 byte operations.
*/
/********************************************************/
void
div_ext(e1,e2)
EXTEND *e1,*e2;
{
short error = 0;
B64 result;
register unsigned long *lp;
#ifndef USE_DIVIDE
short count;
#else
unsigned short u[9], v[5];
register int j;
register unsigned short *u_p = u;
int maxv = 4;
#endif
if ((e2->m1 | e2->m2) == 0) {
/*
* Exception 8.2 - Divide by zero
*/
trap(EFDIVZ);
e1->m1 = e1->m2 = 0L;
e1->exp = EXT_MAX;
return;
}
if ((e1->m1 | e1->m2) == 0) { /* 0 / anything == 0 */
e1->exp = 0; /* make sure */
return;
}
#ifndef USE_DIVIDE
/*
* numbers are right shifted one bit to make sure
* that m1 is quaranteed to be larger if its
* maximum bit is set
*/
b64_rsft(&e1->mantissa); /* 64 bit shift right */
b64_rsft(&e2->mantissa); /* 64 bit shift right */
e1->exp++;
e2->exp++;
#endif
/* check for underflow, divide by zero, etc */
e1->sign ^= e2->sign;
e1->exp -= e2->exp;
#ifndef USE_DIVIDE
/* do division of mantissas */
/* uses partial product method */
/* init control variables */
count = 64;
result.h_32 = 0L;
result.l_32 = 0L;
/* partial product division loop */
while (count--) {
/* first left shift result 1 bit */
/* this is ALWAYS done */
b64_lsft(&result);
/* compare dividend and divisor */
/* if dividend >= divisor add a bit */
/* and subtract divisior from dividend */
if ( (e1->m1 < e2->m1) ||
((e1->m1 == e2->m1) && (e1->m2 < e2->m2) ))
; /* null statement */
/* i.e., don't add or subtract */
else {
result.l_32++; /* ADD */
if (e2->m2 > e1->m2)
e1->m1 -= 1; /* carry in */
e1->m1 -= e2->m1; /* do SUBTRACTION */
e1->m2 -= e2->m2; /* SUBTRACTION */
}
/* 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_lsft(&e1->mantissa);
continue;
}
else
break; /* leave loop */
} /* end of divide by subtraction loop */
if (count > 0) {
lp = &result.h_32;
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.l_32 */
if (*lp) {
result.h_32 |= (*lp >> 32-count);
*lp <<= count;
}
}
#else /* USE_DIVIDE */
u[4] = (e1->m2 & 1) << 15;
b64_rsft(&(e1->mantissa));
u[0] = e1->m1 >> 16;
u[1] = e1->m1;
u[2] = e1->m2 >> 16;
u[3] = e1->m2;
u[5] = 0; u[6] = 0; u[7] = 0;
v[1] = e2->m1 >> 16;
v[2] = e2->m1;
v[3] = e2->m2 >> 16;
v[4] = e2->m2;
while (! v[maxv]) maxv--;
result.h_32 = 0;
result.l_32 = 0;
lp = &result.h_32;
/*
* Use an algorithm of Knuth (The art of programming, Seminumerical
* algorithms), to divide u by v. u and v are both seen as numbers
* with base 65536.
*/
for (j = 0; j <= 3; j++, u_p++) {
unsigned long q_est, temp;
if (j == 2) lp++;
if (u_p[0] == 0 && u_p[1] < v[1]) continue;
temp = ((unsigned long)u_p[0] << 16) + u_p[1];
if (u_p[0] >= v[1]) {
q_est = 0x0000FFFFL;
}
else {
q_est = temp / v[1];
}
temp -= q_est * v[1];
while (temp < 0x10000 && v[2]*q_est > ((temp<<16)+u_p[2])) {
q_est--;
temp += v[1];
}
/* Now, according to Knuth, we have an estimate of the
quotient, that is either correct or one too big, but
almost always correct.
*/
if (q_est != 0) {
int i;
unsigned long k = 0;
int borrow = 0;
for (i = maxv; i > 0; i--) {
unsigned long tmp = q_est * v[i] + k + borrow;
unsigned short md = tmp;
borrow = (md > u_p[i]);
u_p[i] -= md;
k = tmp >> 16;
}
k += borrow;
borrow = u_p[0] < k;
u_p[0] -= k;
if (borrow) {
/* So, this does not happen often; the estimate
was one too big; correct this
*/
*lp |= (j & 1) ? (q_est - 1) : ((q_est-1)<<16);
borrow = 0;
for (i = maxv; i > 0; i--) {
unsigned long tmp
= v[i]+(unsigned long)u_p[i]+borrow;
u_p[i] = tmp;
borrow = tmp >> 16;
}
u_p[0] += borrow;
}
else *lp |= (j & 1) ? q_est : (q_est<<16);
}
}
#ifdef EXCEPTION_INEXACT
u_p = &u[0];
for (j = 7; j >= 0; j--) {
if (*u_p++) {
error = 1;
break;
}
}
#endif
#endif
#ifdef EXCEPTION_INEXACT
if (error) {
/*
* report here exception 8.5 - Inexact
* from Draft 8.0 of IEEE P754:
* In the absence of an invalid operation exception,
* if the rounded result of an operation is not exact or if
* it overflows without a trap, then the inexact exception
* shall be assigned. The rounded or overflowed result
* shall be delivered to the destination.
*/
INEXACT();
#endif
e1->mantissa = result;
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;
}
}

26
lib/ack/fphook/dvf4.fc Executable file
View File

@ -0,0 +1,26 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
DIVIDE TWO SINGLES - SINGLE Precision (dvf 4)
*/
#include "FP_types.h"
void
dvf4(s2,s1)
SINGLE s1,s2;
{
EXTEND e1,e2;
extend(&s1,&e1,sizeof(SINGLE));
extend(&s2,&e2,sizeof(SINGLE));
/* do a divide */
div_ext(&e1,&e2);
compact(&e1,&s1,sizeof(SINGLE));
}

26
lib/ack/fphook/dvf8.fc Executable file
View File

@ -0,0 +1,26 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
DIVIDE TWO FLOATS - DOUBLE Precision (DVF 8)
*/
#include "FP_types.h"
void
dvf8(s2,s1)
DOUBLE s1,s2;
{
EXTEND e1,e2;
extend(&s1.d[0],&e1,sizeof(DOUBLE));
extend(&s2.d[0],&e2,sizeof(DOUBLE));
/* do a divide */
div_ext(&e1,&e2);
compact(&e1,&s1.d[0],sizeof(DOUBLE));
}

111
lib/ack/fphook/extend.fc Executable file
View File

@ -0,0 +1,111 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
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 <SIGN>
->exp 0EEE EEEE | EEEE EEEE <EXPONENT>
->m1 LFFF FFFF | FFFF FFFF <L.Fraction>
FFFF FFFF | FFFF FFFF <Fraction>
->m2 FFFF FFFF | FFFF FFFF <Fraction>
FFFF F000 | 0000 0000 <Fraction>
*/
/********************************************************/
#include "FP_bias.h"
#include "FP_shift.h"
#include "FP_types.h"
#include "get_put.h"
/********************************************************/
void
extend(from,to,size)
unsigned long *from;
EXTEND *to;
int size;
{
register char *cpt1;
unsigned long tmp;
int leadbit = 0;
cpt1 = (char *) from;
#if FL_MSL_AT_LOW_ADDRESS
#if FL_MSW_AT_LOW_ADDRESS
to->exp = uget2(cpt1);
#else
to->exp = uget2(cpt1+2);
#endif
#else
#if FL_MSW_AT_LOW_ADDRESS
to->exp = uget2(cpt1+(size == sizeof(DOUBLE) ? 4 : 0));
#else
to->exp = uget2(cpt1+(size == sizeof(DOUBLE) ? 6 : 2));
#endif
#endif
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 */
else to->exp++;
if (size == sizeof(DOUBLE)) {
#if FL_MSL_AT_LOW_ADDRESS
to->m1 = get4(cpt1);
cpt1 += 4;
tmp = get4(cpt1);
#else
tmp = get4(cpt1);
cpt1 += 4;
to->m1 = get4(cpt1);
#endif
if (to->exp == 1 && to->m1 == 0 && tmp == 0) {
to->exp = 0;
to->sign = 0;
to->m1 = 0;
to->m2 = 0;
return;
}
to->m1 <<= DBL_M1LEFT; /* shift */
to->exp -= DBL_BIAS; /* remove bias */
to->m1 |= (tmp>>DBL_RPACK); /* plus 10 == 32 */
to->m2 = (tmp<<DBL_LPACK); /* plus 22 == 32 */
}
else { /* size == sizeof(SINGLE) */
to->m1 = get4(cpt1);
to->m1 <<= SGL_M1LEFT; /* shift */
if (to->exp == 1 && to->m1 == 0) {
to->exp = 0;
to->sign = 0;
to->m1 = 0;
to->m2 = 0;
return;
}
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 */
nrm_ext(to); /* and normalize */
}
}

33
lib/ack/fphook/fef4.fc Executable file
View File

@ -0,0 +1,33 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SEPERATE INTO EXPONENT AND FRACTION (FEF 4)
*/
#include "FP_types.h"
void
fef4(r,s1)
SINGLE s1;
struct fef4_returns *r;
{
EXTEND buf;
register struct fef4_returns *p = r; /* make copy; r might refer
to itself (see table)
*/
extend(&s1,&buf,sizeof(SINGLE));
if (buf.exp == 0 && buf.m1 == 0 && buf.m2 == 0) {
p->e = 0;
}
else {
p->e = buf.exp+1;
buf.exp = -1;
}
compact(&buf,&p->f,sizeof(SINGLE));
}

33
lib/ack/fphook/fef8.fc Executable file
View File

@ -0,0 +1,33 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SEPERATE DOUBLE INTO EXPONENT AND FRACTION (FEF 8)
*/
#include "FP_types.h"
void
fef8(r, s1)
DOUBLE s1;
struct fef8_returns *r;
{
EXTEND buf;
register struct fef8_returns *p = r; /* make copy, r might refer
to itself (see table)
*/
extend(&s1.d[0],&buf,sizeof(DOUBLE));
if (buf.exp == 0 && buf.m1 == 0 && buf.m2 == 0) {
p->e = 0;
}
else {
p->e = buf.exp + 1;
buf.exp = -1;
}
compact(&buf,&p->f.d[0],sizeof(DOUBLE));
}

46
lib/ack/fphook/fif4.fc Executable file
View File

@ -0,0 +1,46 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
MULTIPLY AND DISMEMBER PARTS (FIF 4)
*/
#include "FP_types.h"
#include "FP_shift.h"
void
fif4(p,x,y)
SINGLE x,y;
struct fif4_returns *p;
{
EXTEND e1,e2;
extend(&y,&e1,sizeof(SINGLE));
extend(&x,&e2,sizeof(SINGLE));
/* do a multiply */
mul_ext(&e1,&e2);
e2 = e1;
compact(&e2,&y,sizeof(SINGLE));
if (e1.exp < 0) {
p->ipart = 0;
p->fpart = y;
return;
}
if (e1.exp > 30 - SGL_M1LEFT) {
p->ipart = y;
p->fpart = 0;
return;
}
b64_sft(&e1.mantissa, 63 - e1.exp);
b64_sft(&e1.mantissa, e1.exp - 63); /* "loose" low order bits */
compact(&e1,&(p->ipart),sizeof(SINGLE));
extend(&(p->ipart), &e2, sizeof(SINGLE));
extend(&y, &e1, sizeof(SINGLE));
sub_ext(&e1, &e2);
compact(&e1, &(p->fpart), sizeof(SINGLE));
}

48
lib/ack/fphook/fif8.fc Executable file
View File

@ -0,0 +1,48 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
MULTIPLY AND DISMEMBER PARTS (FIF 8)
*/
#include "FP_types.h"
#include "FP_shift.h"
void
fif8(p,x,y)
DOUBLE x,y;
struct fif8_returns *p;
{
EXTEND e1,e2;
extend(&y.d[0],&e1,sizeof(DOUBLE));
extend(&x.d[0],&e2,sizeof(DOUBLE));
/* do a multiply */
mul_ext(&e1,&e2);
e2 = e1;
compact(&e2, &y.d[0], sizeof(DOUBLE));
if (e1.exp < 0) {
p->ipart.d[0] = 0;
p->ipart.d[1] = 0;
p->fpart = y;
return;
}
if (e1.exp > 62 - DBL_M1LEFT) {
p->ipart = y;
p->fpart.d[0] = 0;
p->fpart.d[1] = 0;
return;
}
b64_sft(&e1.mantissa, 63 - e1.exp);
b64_sft(&e1.mantissa, e1.exp - 63); /* "loose" low order bits */
compact(&e1, &(p->ipart.d[0]), sizeof(DOUBLE));
extend(&(p->ipart.d[0]), &e2, sizeof(DOUBLE));
extend(&y.d[0], &e1, sizeof(DOUBLE));
sub_ext(&e1, &e2);
compact(&e1, &(p->fpart.d[0]), sizeof(DOUBLE));
}

12
lib/ack/fphook/fltpr.c Executable file
View File

@ -0,0 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
#include "../stdio/loc_incl.h"
int _fp_hook = 1;
char *
_f_print(va_list *ap, int flags, char *s, char c, int precision)
{
fprintf(stderr,"cannot print floating point\n");
exit(EXIT_FAILURE);
}

195
lib/ack/fphook/fphook.c Executable file
View File

@ -0,0 +1,195 @@
/*
* fltpr.c - print floating point numbers
*/
/* $Header$ */
#ifndef NOFLOAT
#include <string.h>
#include <stdarg.h>
#include "../stdio/loc_incl.h"
int _fp_hook = 1;
static char *
_pfloat(long double r, register char *s, int n, int flags)
{
register char *s1;
int sign, dp;
register int i;
s1 = _fcvt(r, n, &dp, &sign);
if (sign)
*s++ = '-';
else if (flags & FL_SIGN)
*s++ = '+';
else if (flags & FL_SPACE)
*s++ = ' ';
if (dp<=0)
*s++ = '0';
for (i=dp; i>0; i--)
if (*s1) *s++ = *s1++;
else *s++ = '0';
if (((i=n) > 0) || (flags & FL_ALT))
*s++ = '.';
while (++dp <= 0) {
if (--i<0)
break;
*s++ = '0';
}
while (--i >= 0)
if (*s1) *s++ = *s1++;
else *s++ = '0';
return s;
}
static char *
_pscien(long double r, register char *s, int n, int flags)
{
int sign, dp;
register char *s1;
s1 = _ecvt(r, n + 1, &dp, &sign);
if (sign)
*s++ = '-';
else if (flags & FL_SIGN)
*s++ = '+';
else if (flags & FL_SPACE)
*s++ = ' ';
*s++ = *s1++;
if ((n > 0) || (flags & FL_ALT))
*s++ = '.';
while (--n >= 0)
if (*s1) *s++ = *s1++;
else *s++ = '0';
*s++ = 'e';
if ( r != 0 ) --dp ;
if ( dp<0 ) {
*s++ = '-' ; dp= -dp ;
} else {
*s++ = '+' ;
}
if (dp >= 100) {
*s++ = '0' + (dp / 100);
dp %= 100;
}
*s++ = '0' + (dp/10);
*s++ = '0' + (dp%10);
return s;
}
#define NDIGINEXP(exp) (((exp) >= 100 || (exp) <= -100) ? 3 : 2)
#define LOW_EXP -4
#define USE_EXP(exp, ndigits) (((exp) < LOW_EXP + 1) || (exp >= ndigits + 1))
static char *
_gcvt(long double value, int ndigit, char *s, int flags)
{
int sign, dp;
register char *s1, *s2;
register int i;
register int nndigit = ndigit;
s1 = _ecvt(value, ndigit, &dp, &sign);
s2 = s;
if (sign) *s2++ = '-';
else if (flags & FL_SIGN)
*s2++ = '+';
else if (flags & FL_SPACE)
*s2++ = ' ';
if (!(flags & FL_ALT))
for (i = nndigit - 1; i > 0 && s1[i] == '0'; i--)
nndigit--;
if (USE_EXP(dp,ndigit)) {
/* Use E format */
dp--;
*s2++ = *s1++;
if ((nndigit > 1) || (flags & FL_ALT)) *s2++ = '.';
while (--nndigit > 0) *s2++ = *s1++;
*s2++ = 'e';
if (dp < 0) {
*s2++ = '-';
dp = -dp;
}
else *s2++ = '+';
s2 += NDIGINEXP(dp);
*s2 = 0;
for (i = NDIGINEXP(dp); i > 0; i--) {
*--s2 = dp % 10 + '0';
dp /= 10;
}
return s;
}
/* Use f format */
if (dp <= 0) {
if (*s1 != '0') {
/* otherwise the whole number is 0 */
*s2++ = '0';
*s2++ = '.';
}
while (dp < 0) {
dp++;
*s2++ = '0';
}
}
for (i = 1; i <= nndigit; i++) {
*s2++ = *s1++;
if (i == dp) *s2++ = '.';
}
if (i <= dp) {
while (i++ <= dp) *s2++ = '0';
*s2++ = '.';
}
if ((s2[-1]=='.') && !(flags & FL_ALT)) s2--;
*s2 = '\0';
return s;
}
char *
_f_print(va_list *ap, int flags, char *s, char c, int precision)
{
register char *old_s = s;
long double ld_val;
if (flags & FL_LONGDOUBLE) ld_val = va_arg(*ap, long double);
else ld_val = (long double) va_arg(*ap, double);
switch(c) {
case 'f':
s = _pfloat(ld_val, s, precision, flags);
break;
case 'e':
case 'E':
s = _pscien(ld_val, s, precision , flags);
break;
case 'g':
case 'G':
s = _gcvt(ld_val, precision, s, flags);
s += strlen(s);
break;
}
if ( c == 'E' || c == 'G') {
while (*old_s && *old_s != 'e') old_s++;
if (*old_s == 'e') *old_s = 'E';
}
return s;
}
#endif /* NOFLOAT */
/* $Header$ */
#include <stdlib.h>
#include "../ansi/ext_fmt.h"
void _str_ext_cvt(const char *s, char **ss, struct EXTEND *e);
double _ext_dbl_cvt(struct EXTEND *e);
double
strtod(const char *p, char **pp)
{
struct EXTEND e;
_str_ext_cvt(p, pp, &e);
return _ext_dbl_cvt(&e);
}

19
lib/ack/fphook/fptrp.s Executable file
View File

@ -0,0 +1,19 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
.define __fptrp
.sect .text
__fptrp:
#if __i386
push ebp
mov ebp, esp
mov eax, 8(bp)
call .Xtrp
leave
ret
#else /* i86 */
push bp
mov bp, sp
mov ax, 4(bp)
call .Xtrp
jmp .cret
#endif

41
lib/ack/fphook/get_put.h Executable file
View File

@ -0,0 +1,41 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
#include <byte_order.h>
#if CHAR_UNSIGNED
#define Xchar(ch) (ch)
#else
#define Xchar(ch) ((ch) & 0377)
#endif
#define BYTES_REVERSED (MSB_AT_LOW_ADDRESS != FL_MSB_AT_LOW_ADDRESS)
#define WORDS_REVERSED (MSW_AT_LOW_ADDRESS != FL_MSW_AT_LOW_ADDRESS)
#define LONGS_REVERSED (FL_MSL_AT_LOW_ADDRESS)
#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

25
lib/ack/fphook/mlf4.fc Executable file
View File

@ -0,0 +1,25 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
* Multiply Single Precesion Float (MLF 4)
*/
#include "FP_types.h"
void
mlf4(s2,s1)
SINGLE s1,s2;
{
EXTEND e1,e2;
extend(&s1,&e1,sizeof(SINGLE));
extend(&s2,&e2,sizeof(SINGLE));
/* do a multiply */
mul_ext(&e1,&e2);
compact(&e1,&s1,sizeof(SINGLE));
}

25
lib/ack/fphook/mlf8.fc Executable file
View File

@ -0,0 +1,25 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
* Multiply Double Precision Float (MLF 8)
*/
#include "FP_types.h"
void
mlf8(s2,s1)
DOUBLE s1,s2;
{
EXTEND e1,e2;
extend(&s1.d[0],&e1,sizeof(DOUBLE));
extend(&s2.d[0],&e2,sizeof(DOUBLE));
/* do a multiply */
mul_ext(&e1,&e2);
compact(&e1,&s1.d[0],sizeof(DOUBLE));
}

98
lib/ack/fphook/mul_ext.fc Executable file
View File

@ -0,0 +1,98 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
ROUTINE TO MULTIPLY TWO EXTENDED FORMAT NUMBERS
*/
# include "FP_bias.h"
# include "FP_trap.h"
# include "FP_types.h"
# include "FP_shift.h"
void
mul_ext(e1,e2)
EXTEND *e1,*e2;
{
register int i,j; /* loop control */
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;
/* compute new exponent */
e1->exp += e2->exp + 1;
/* 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;
for (i = 8; i--;) {
result[i] = 0;
}
/*
* fill registers with their components
*/
for(i=4, pres = &result[4];i--;pres--) if (mp[i]) {
unsigned short k = 0;
unsigned long mpi = mp[i];
for(j=4;j--;) {
unsigned long tmp = (unsigned long)pres[j] + k;
if (mc[j]) tmp += mpi * mc[j];
pres[j] = tmp;
k = tmp >> 16;
}
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
*/
e1->m1 = ((unsigned long)(result[0]) << 16) + result[1];
e1->m2 = ((unsigned long)(result[2]) << 16) + result[3];
if (result[4] & 0x8000) {
if (++e1->m2 == 0)
if (++e1->m1 == 0) {
e1->m1 = NORMBIT;
e1->exp++;
}
}
/* 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;
}
}

27
lib/ack/fphook/ngf4.fc Executable file
View File

@ -0,0 +1,27 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
NEGATE A FLOATING POINT (NGF 4)
*/
/********************************************************/
#include "FP_types.h"
#include "get_put.h"
#define OFF ((FL_MSW_AT_LOW_ADDRESS ? 0 : 2) + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
void
ngf4(f)
SINGLE f;
{
unsigned char *p;
if (f != (SINGLE) 0) {
p = (unsigned char *) &f + OFF;
*p ^= 0x80;
}
}

28
lib/ack/fphook/ngf8.fc Executable file
View File

@ -0,0 +1,28 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
NEGATE A FLOATING POINT (NGF 8)
*/
/********************************************************/
#include "FP_types.h"
#include "get_put.h"
#define OFF ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
void
ngf8(f)
DOUBLE f;
{
unsigned char *p;
if (f.d[0] != 0 || f.d[1] != 0) {
p = (unsigned char *) &f + OFF;
*p ^= 0x80;
}
}

50
lib/ack/fphook/nrm_ext.fc Executable file
View File

@ -0,0 +1,50 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/********************************************************/
/*
NORMALIZE an EXTENDED FORMAT NUMBER
*/
/********************************************************/
#include "FP_shift.h"
#include "FP_types.h"
void
nrm_ext(e1)
EXTEND *e1;
{
/* 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 ((e1->m1 | e1->m2) == 0L)
return;
/* if top word is zero mov low word */
/* to top word, adjust exponent value */
if (e1->m1 == 0L) {
e1->m1 = e1->m2;
e1->m2 = 0L;
e1->exp -= 32;
}
if ((e1->m1 & NORMBIT) == 0) {
unsigned long l = ((unsigned long)NORMBIT >> 1);
int cnt = -1;
while (! (l & e1->m1)) {
l >>= 1;
cnt--;
}
e1->exp += cnt;
b64_sft(&(e1->mantissa), cnt);
}
}

27
lib/ack/fphook/sbf4.fc Executable file
View File

@ -0,0 +1,27 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SUBTRACT TWO FLOATS - SINGLE Precision (SBF 4)
*/
#include "FP_types.h"
void
sbf4(s2,s1)
SINGLE s1,s2;
{
EXTEND e1,e2;
if (s2 == (SINGLE) 0) {
return;
}
extend(&s1,&e1,sizeof(SINGLE));
extend(&s2,&e2,sizeof(SINGLE));
sub_ext(&e1,&e2);
compact(&e1,&s1,sizeof(SINGLE));
}

27
lib/ack/fphook/sbf8.fc Executable file
View File

@ -0,0 +1,27 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SUBTRACT TWO FLOATS - DOUBLE Precision (SBF 8)
*/
#include "FP_types.h"
void
sbf8(s2,s1)
DOUBLE s1,s2;
{
EXTEND e1, e2;
if (s2.d[0] == 0 && s2.d[1] == 0) {
return;
}
extend(&s1.d[0],&e1,sizeof(DOUBLE));
extend(&s2.d[0],&e2,sizeof(DOUBLE));
sub_ext(&e1,&e2);
compact(&e1,&s1.d[0],sizeof(DOUBLE));
}

39
lib/ack/fphook/sft_ext.fc Executable file
View File

@ -0,0 +1,39 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SHIFT TWO EXTENDED NUMBERS INTO PROPER
ALIGNMENT FOR ADDITION (exponents are equal)
Numbers should not be zero on entry.
*/
#include "FP_types.h"
void
sft_ext(e1,e2)
EXTEND *e1,*e2;
{
register EXTEND *s;
register int diff;
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;
b64_sft(&(s->mantissa), diff);
}

75
lib/ack/fphook/shifter.fc Executable file
View File

@ -0,0 +1,75 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
# include "FP_types.h"
void
b64_sft(e1,n)
B64 *e1;
int n;
{
if (n > 0) {
if (n > 63) {
e1->l_32 = 0;
e1->h_32 = 0;
return;
}
if (n >= 32) {
e1->l_32 = e1->h_32;
e1->h_32 = 0;
n -= 32;
}
if (n > 0) {
e1->l_32 >>= n;
if (e1->h_32 != 0) {
e1->l_32 |= (e1->h_32 << (32 - n));
e1->h_32 >>= n;
}
}
return;
}
n = -n;
if (n > 0) {
if (n > 63) {
e1->l_32 = 0;
e1->h_32 = 0;
return;
}
if (n >= 32) {
e1->h_32 = e1->l_32;
e1->l_32 = 0;
n -= 32;
}
if (n > 0) {
e1->h_32 <<= n;
if (e1->l_32 != 0) {
e1->h_32 |= (e1->l_32 >> (32 - n));
e1->l_32 <<= n;
}
}
}
}
void
b64_lsft(e1)
B64 *e1;
{
/* shift left 1 bit */
e1->h_32 <<= 1;
if (e1->l_32 & 0x80000000L) e1->h_32 |= 1;
e1->l_32 <<= 1;
}
void
b64_rsft(e1)
B64 *e1;
{
/* shift right 1 bit */
e1->l_32 >>= 1;
if (e1->h_32 & 1) e1->l_32 |= 0x80000000L;
e1->h_32 >>= 1;
}

9
lib/ack/fphook/strtod.c Executable file
View File

@ -0,0 +1,9 @@
#include <stdio.h>
#include <stdlib.h>
double
strtod(const char *p, char **pp)
{
fprintf(stderr,"cannot print floating point\n");
exit(EXIT_FAILURE);
}

53
lib/ack/fphook/sub_ext.fc Executable file
View File

@ -0,0 +1,53 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
SUBTRACT 2 EXTENDED FORMAT NUMBERS
*/
#include "FP_types.h"
void
sub_ext(e1,e2)
EXTEND *e1,*e2;
{
if ((e2->m1 | e2->m2) == 0L) {
return;
}
if ((e1->m1 | e1->m2) == 0L) {
*e1 = *e2;
e1->sign = e2->sign ? 0 : 1;
return;
}
sft_ext(e1, e2);
if (e1->sign != e2->sign) {
/* e1 - e2 = e1 + (-e2) */
if (b64_add(&e1->mantissa,&e2->mantissa)) { /* addition carry */
b64_rsft(&e1->mantissa); /* shift mantissa one bit RIGHT */
e1->m1 |= 0x80000000L; /* set max bit */
e1->exp++; /* increase the exponent */
}
}
else 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 */
}
e2->m1 -= e1->m1;
e2->m2 -= e1->m2;
*e1 = *e2;
e1->sign = e2->sign ? 0 : 1;
}
else {
if (e2->m2 > e1->m2)
e1->m1 -= 1; /* carry in */
e1->m1 -= e2->m1;
e1->m2 -= e2->m2;
}
nrm_ext(e1);
}

19
lib/ack/fphook/zrf4.fc Executable file
View File

@ -0,0 +1,19 @@
/*
(c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
/*
return a zero float (ZRF 4)
*/
#include "FP_types.h"
void
zrf4(l)
SINGLE *l;
{
*l = 0L;
}

Some files were not shown because too many files have changed in this diff Show More