[comp.os.minix] Floating Point for Minix-PC, Part 02/03

housel@en.ecn.purdue.edu (Peter S. Housel) (07/29/89)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of archive 2 (of 3)."
# Contents:  Makefile addsub.x cc.c.cdif cff.x cfi.x cif.x cuf.x dvf8.x
#   exp.c float.h fpp.c modf.x norm4.x norm8.x strtod.c strtod_aux.x
#   trp.x
# Wrapped by housel@en.ecn.purdue.edu on Fri Jul 28 13:35:05 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(2672 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# Makefile for fpp and floating point library
X#
XCFLAGS = -f -LIB -DFLOATLIB
X
XFPPOBJS	= fpp.s atof.s strtod.s strtod_aux.s ldexp.s cff.s cmf8.s \
X	  zrf8.s norm8.s norm4.s
X
Xfpp: $(FPPOBJS)
X	cc -o fpp $(FPPOBJS)
Xfpp.s:
X	cc -c fpp.c
X
XCSRCS	= fabs.c pow.c exp.c sqrt.c log10.c log.c _poly.c _mult.c \
X	  ceil.c floor.c atof.c strtod.c printf.c fprintf.c sprintf.c \
X	  vprintf.c vsprintf.c vfprintf.c
XCOBJS	= fabs.s pow.s exp.s sqrt.s log10.s log.s _poly.s _mult.s \
X	  ceil.s floor.s atof.s strtod.s printf.s fprintf.s sprintf.s \
X	  vprintf.s vsprintf.s vfprintf.s
XGENSRCS	= frexp.x modf.x strtod_aux.x ldexp.x
XGENOBJS	= frexp.s modf.s strtod_aux.s ldexp.s
XAUXSRCS	= cff.x cfu.x cuf.x cif.x addsub.x cfi.x fat.x trp.x dvf8.x \
X	  ngf8.x mlf8.x cmf8.x zrf4.x zrf8.x norm4.x norm8.x
XAUXOBJS	= cff.s cfu.s cuf.s cif.s addsub.s cfi.s fat.s trp.s dvf8.s \
X	  ngf8.s mlf8.s cmf8.s zrf4.s zrf8.s norm4.s norm8.s
X
XMINIX1_1SRCS	= ret8.x return.x
X# MINIX1_1OBJS	= ret8.s return.s
X
XLIBOBJS	= ${COBJS} ${GENOBJS} ${AUXOBJS} ${MINIX1_1OBJS}
X
Xlibfp.a: ${LIBOBJS}
X	ar cr libfp.a `lorder ${LIBOBJS} | tsort`
X
X.SUFFIXES: .x
X.x.s:
X	-libpack < $*.x | sed '/^$$/d' > $*.s
X
Xclean:
X	rm -f libfp.a fpp $(LIBOBJS) core
X
Xdepend:
X	mkdep fpp.c $(CSRCS)
X
X# DO NOT DELETE THIS LINE -- mkdep uses it.
X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
X
Xfpp.s: /usr/include/stdio.h
Xfpp.s: fpp.c
Xfabs.s: /usr/include/math.h
Xfabs.s: fabs.c
Xpow.s: /usr/include/errno.h
Xpow.s: /usr/include/limits.h
Xpow.s: /usr/include/math.h
Xpow.s: pow.c
Xexp.s: /usr/include/errno.h
Xexp.s: /usr/include/limits.h
Xexp.s: /usr/include/math.h
Xexp.s: exp.c
Xsqrt.s: /usr/include/errno.h
Xsqrt.s: /usr/include/math.h
Xsqrt.s: sqrt.c
Xlog10.s: /usr/include/math.h
Xlog10.s: log10.c
Xlog.s: /usr/include/errno.h
Xlog.s: /usr/include/math.h
Xlog.s: log.c
X_poly.s: /usr/include/math.h
X_poly.s: _poly.c
X_mult.s: /usr/include/math.h
X_mult.s: _mult.c
Xceil.s: /usr/include/math.h
Xceil.s: ceil.c
Xfloor.s: /usr/include/math.h
Xfloor.s: floor.c
Xatof.s: atof.c
Xstrtod.s: /usr/include/ctype.h
Xstrtod.s: strtod.c
Xprintf.s: /usr/include/stdarg.h
Xprintf.s: /usr/include/stdio.h
Xprintf.s: printf.c
Xfprintf.s: /usr/include/stdarg.h
Xfprintf.s: /usr/include/stdio.h
Xfprintf.s: fprintf.c
Xsprintf.s: /usr/include/stdarg.h
Xsprintf.s: /usr/include/stdio.h
Xsprintf.s: sprintf.c
Xvprintf.s: /usr/include/stdarg.h
Xvprintf.s: /usr/include/stdio.h
Xvprintf.s: vprintf.c
Xvsprintf.s: /usr/include/stdarg.h
Xvsprintf.s: /usr/include/stdio.h
Xvsprintf.s: vsprintf.c
Xvfprintf.s: /usr/include/ctype.h
Xvfprintf.s: /usr/include/stdarg.h
Xvfprintf.s: /usr/include/stdio.h
Xvfprintf.s: /usr/include/sys/types.h
Xvfprintf.s: vfprintf.c
X
X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
END_OF_FILE
if test 2672 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'addsub.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'addsub.x'\"
else
echo shar: Extracting \"'addsub.x'\" \(3165 characters\)
sed "s/^X//" >'addsub.x' <<'END_OF_FILE'
X.define .sbf8,.adf8
X| 
X| floating point add/subtract routines
X| author: Peter S. Housel 9/21/88,01/17/89,03/19/89,5/24/89
X|
X
XV	=	6		| stack offset of v
XU	=	V + 8		| stack offset of u
X
X	.text
X	.globl	.sbf8,.adf8,.norm8
X.sbf8:
X	push	si		| save register variables
X	push	di
X	mov	di,sp		| di => v
X	add	di,#V
X	xorb	7(di),*128	| negate second argument
X				| fall through to adf8
X	jmp	0f
X.adf8:
X	push	si		| save register variables
X	push	di
X	mov	di,sp
X	add	di,#V		| di => v
X0:	mov	si,sp
X	add	si,#U		| si => u
X
X	mov	bx,6(si)	| extract u.exp
X	movb	dh,bh		| extract u.sign
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	and	bx,#2047	| kill sign bit
X
X	mov	cx,6(di)	| extract v.exp
X	movb	dl,ch		| extract v.sign
X	shr	cx,*1
X	shr	cx,*1
X	shr	cx,*1
X	shr	cx,*1
X	and	cx,#2047	| kill sign bit
X
X	mov	ax,6(si)	| remove exponent from u.mantissa
X	and	ax,#0x0F
X	test	bx,bx		| check for zero exponent - no leading "1"
X	jz	0f		| for denormalized numbers
X	or	ax,#0x10	| restore implied leading "1"
X0:	mov	6(si),ax
X
X	mov	ax,6(di)	| remove exponent from v.mantissa
X	and	ax,#0x0F
X	test	cx,cx		| check for zero exponent - no leading "1"
X	jz	0f		| for denormalized numbers
X	or	ax,#0x10	| restore implied leading "1"
X0:	mov	6(di),ax
X
X	mov	ax,bx
X	sub	ax,cx		| ax = u.exp - v.exp
X	movb	cl,*0		| (put initial zero rounding bits in cl)
X	je	4f		| exponents are equal - no shifting necessary
X	jg	1f		| not equal but no exchange necessary
X	xchg	si,di		| exchange u and v
X	xchgb	dh,dl
X	sub	bx,ax		| bx = u.exp - (u.exp - v.exp) = v.exp
X	neg	ax
X1:
X	cmp	ax,#53		| is u so much bigger that v is not
X	jge	7f		| significant?
X
X	movb	ch,#10		| shift u left up to 10 bits to minimize loss
X2:
X	shl	0(si),*1
X	rcl	2(si),*1
X	rcl	4(si),*1
X	rcl	6(si),*1
X	dec	bx		| decrement exponent
X	dec	ax
X	jz	4f		| done shifting altogether
X	decb	ch
X	jnz	2b		| still can shift u.mant more
X3:
X	shr	6(di),*1	| shift v.mant right the rest of the way
X	rcr	4(di),*1	| to line it up with u.mant
X	rcr	2(di),*1
X	rcr	0(di),*1
X	rcrb	cl,*1		| shift into rounding bits
X	jnc	0f
X	orb	cl,*1		| make least sig bit "sticky"
X0:	dec	ax		| loop
X	jne	3b
X4:
X	movb	al,dh		| are the signs equal?
X	xorb	al,dl
X	andb	al,*128
X	je	6f		| yes, no negate necessary
X
X	notb	cl		| negate rounding bits and v.mant
X	addb	cl,*1
X	not	0(di)
X	adc	0(di),#0
X	not	2(di)
X	adc	2(di),#0
X	not	4(di)
X	adc	4(di),#0
X	not	6(di)
X	adc	6(di),#0
X6:
X	push	ax		| save signs flag
X	mov	ax,0(di)	| u.mant = u.mant + v.mant
X	add	0(si),ax
X	mov	ax,2(di)
X	adc	2(si),ax
X	mov	ax,4(di)
X	adc	4(si),ax
X	mov	ax,6(di)
X	adc	6(si),ax
X
X	pop	ax		| restore u.sign ^ v.sign
X	jc	7f		| needn't negate
X	testb	al,al		| opposite signs?
X	je	7f		| don't need to negate result
X
X	notb	cl		| negate rounding bits and u.mant
X	addb	cl,*1
X	not	0(si)
X	adc	0(si),#0
X	not	2(si)
X	adc	2(si),#0
X	not	4(si)
X	adc	4(si),#0
X	not	6(si)
X	adc	6(si),#0
X	xorb	dh,*128		| switch sign
X7:
X	movb	dl,cl		| put rounding bits in dl for .norm8
X	mov	di,sp		| set destination = u
X	add	di,#U
X	mov			| if we swapped, move v onto u;
X	mov			| if we didn't swap, move u onto itself
X	mov
X	mov
X	pop	di		| restore register variables
X	pop	si
X	pop	cx		| cx = return address
X	add	sp,#8		| remove v from the stack
X	push	cx		| put the return address back
X	jmp	.norm8
END_OF_FILE
if test 3165 -ne `wc -c <'addsub.x'`; then
    echo shar: \"'addsub.x'\" unpacked with wrong size!
fi
# end of 'addsub.x'
fi
if test -f 'cc.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cc.c.cdif'\"
else
echo shar: Extracting \"'cc.c.cdif'\" \(4500 characters\)
sed "s/^X//" >'cc.c.cdif' <<'END_OF_FILE'
X*** cc.c	Thu Jun 22 18:52:16 1989
X--- fcc.c	Thu Jun 22 18:51:13 1989
X***************
X*** 42,47 ****
X--- 42,48 ----
X  char *PP     = "/lib/cpp";
X  char *CEM    = "/lib/cem";
X  char *OPT    = "/usr/lib/opt";
X+ char *FPP    = "/usr/lib/fpp";
X  char *CG     = "/usr/lib/cg";
X  char *ASLD   = "/usr/bin/asld";
X  char *AST    = "/usr/bin/ast";
X***************
X*** 54,59 ****
X--- 55,61 ----
X  char *PP     = "/usr/lib/cpp";
X  char *CEM    = "/usr/lib/cem";
X  char *OPT    = "/usr/lib/opt";
X+ char *FPP    = "/usr/lib/fpp";
X  char *CG     = "/usr/lib/cg";
X  char *ASLD   = "/usr/bin/asld";
X  char *AST    = "/usr/bin/ast";
X***************
X*** 66,71 ****
X--- 68,74 ----
X  char *PP     = "/lib/cpp";
X  char *CEM    = "/lib/cem";
X  char *OPT    = "/lib/opt";
X+ char *FPP    = "/usr/fpp";
X  char *CG     = "/lib/cg";
X  char *ASLD   = "/bin/asld";
X  char *AST    = "/bin/ast";
X***************
X*** 76,85 ****
X--- 79,90 ----
X  #ifdef RAMDISK
X  struct arglist LD_HEAD =    {1, { "/lib/crtso.s" } };
X  struct arglist M_LD_HEAD =  {1, { "/lib/mrtso.s" } };
X+ struct arglist LD_FPLIB =   {1, { "/lib/libfp.a" } };
X  struct arglist LD_TAIL =    {2, { "/lib/libc.a", "/lib/end.s" } };
X  #else
X  struct arglist LD_HEAD =    {1, { "/usr/lib/crtso.s" } };
X  struct arglist M_LD_HEAD =  {1, { "/usr/lib/mrtso.s" } };
X+ struct arglist LD_FPLIB =   {1, { "/usr/lib/libfp.a" } };
X  struct arglist LD_TAIL =    {2, { "/usr/lib/libc.a", "/usr/lib/end.s" } };
X  #endif
X  
X***************
X*** 109,114 ****
X--- 114,120 ----
X  int RET_CODE = 0;
X  
X  struct arglist OPT_FLAGS;
X+ struct arglist FPP_FLAGS;
X  struct arglist CG_FLAGS;
X  struct arglist ASLD_FLAGS;
X  struct arglist DEBUG_FLAGS;
X***************
X*** 121,131 ****
X  int F_flag = 0;	/* use pipes by default */
X  int s_flag = 0;
X  int p_flag = 0;	/* profil flag */
X  
X  char *mkstr();
X  char *alloc();
X  
X! USTRING ifile, kfile, sfile, mfile, ofile;
X  USTRING BASE;
X  
X  char *tmpdir = "/tmp";
X--- 127,138 ----
X  int F_flag = 0;	/* use pipes by default */
X  int s_flag = 0;
X  int p_flag = 0;	/* profil flag */
X+ int f_flag = 0; /* use floating point flag */
X  
X  char *mkstr();
X  char *alloc();
X  
X! USTRING ifile, kfile, sfile, mfile, Mfile, ofile;
X  USTRING BASE;
X  
X  char *tmpdir = "/tmp";
X***************
X*** 161,169 ****
X  
X  	ProgCall = *argv++;
X  
X! 	signal(SIGHUP, trapcc);
X! 	signal(SIGINT, trapcc);
X! 	signal(SIGQUIT, trapcc);
X  	while (--argc > 0) {
X  		if (*(str = *argv++) != '-') {
X  			append(&SRCFILES, str);
X--- 168,176 ----
X  
X  	ProgCall = *argv++;
X  
X! 	if (signal(SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, trapcc);
X! 	if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, trapcc);
X! 	if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) signal(SIGQUIT, trapcc);
X  	while (--argc > 0) {
X  		if (*(str = *argv++) != '-') {
X  			append(&SRCFILES, str);
X***************
X*** 219,224 ****
X--- 226,234 ----
X  			p_flag = 1;
X  			s_flag = 1;
X  			break;
X+ 		case 'f':
X+ 			f_flag = 1;
X+ 			break;
X  		case 'L':
X  			if (strcmp(&str[1], "LIB") == 0) {
X  				append(&OPT_FLAGS, "-L");
X***************
X*** 316,334 ****
X  			cleanup(kfile);
X  		}
X  
X! 		/* .m to .s */
X! 		if (ext == 'm') {
X! 			ldfile = S_flag ? ofile : alloc(strlen(BASE) + 3);
X! 
X! 			init(call);
X! 			append(call, CG);
X! 			concat(call, &CG_FLAGS);
X! 			append(call, file);
X! 			f = mkstr(ldfile, BASE, ".s", 0);
X  			append(call, f);
X  			if (runvec(call, (char *)0) == 0)
X  				continue;
X  			cleanup(mfile);
X  			file = ldfile;
X  			ext = 's';
X  		}
X--- 326,360 ----
X  			cleanup(kfile);
X  		}
X  
X! 		/* .m to .M */
X! 		if (ext == 'm' && f_flag) {
X! 			init(call);
X! 			append(call, FPP);
X! 			concat(call, &FPP_FLAGS);
X! 			append(call, file);
X! 			f = mkstr(Mfile, tmpdir, tmpname, ".M", 0);
X  			append(call, f);
X  			if (runvec(call, (char *)0) == 0)
X  				continue;
X  			cleanup(mfile);
X+ 			file = Mfile;
X+ 			ext = 'M';
X+ 		}
X+ 
X+ 		/* .m (or .M) to .s */
X+ 		if (ext == 'm' || ext == 'M') {
X+ 			ldfile = S_flag ? ofile : alloc(strlen(BASE) + 3);
X+ 
X+ 			init(call);
X+ 			append(call, CG);
X+ 			concat(call, &CG_FLAGS);
X+ 			append(call, file);
X+ 			f = mkstr(ldfile, BASE, ".s", 0);
X+ 			append(call, f);
X+ 			if (runvec(call, (char *)0) == 0)
X+ 				continue;
X+ 			cleanup(mfile);
X+ 			cleanup(Mfile);
X  			file = ldfile;
X  			ext = 's';
X  		}
X***************
X*** 355,360 ****
X--- 381,387 ----
X  			concat(call, &M_LD_HEAD);
X  		else	concat(call, &LD_HEAD);
X  		concat(call, &LDFILES);
X+ 		if(f_flag) concat(call, &LD_FPLIB);
X  		concat(call, &LD_TAIL);
X  		if (s_flag) 
X  			f = SYMBOL_FILE;
END_OF_FILE
if test 4500 -ne `wc -c <'cc.c.cdif'`; then
    echo shar: \"'cc.c.cdif'\" unpacked with wrong size!
fi
# end of 'cc.c.cdif'
fi
if test -f 'cff.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cff.x'\"
else
echo shar: Extracting \"'cff.x'\" \(2066 characters\)
sed "s/^X//" >'cff.x' <<'END_OF_FILE'
X.define .cff
X| 
X| floating point <=> floating point conversion routines
X| author: Peter S. Housel 06/03/89
X|
X
XBIAS4	=	0x7F - 1
XBIAS8	=	0x3FF - 1
X
X	.text
X	.globl	.cff
X|
X| on entry dx=source size, cx=dest. size
X|
X.cff:
X	cmp	dx,#4
X	jne	cff8
Xcff4:
X	cmp	cx,#4
X	jne	cff4_8
Xcff4_4:				| redundant 4-byte float to 4-byte float
X	ret
Xcff4_8:				| 4-byte float to 8-byte double
X	cmp	cx,#8
X	jne	ill		| illegal EM op
X
X	pop	cx		| cx = return address
X	xor	ax,ax		| append 32 bits of zeroes
X	push	ax
X	push	ax
X	push	cx		| put return address back
X	push	si
X	mov	si,sp
X
X	mov	bx,4+6(si)	| extract exponent
X	movb	dh,bh		| extract sign
X	movb	cl,*7
X	shr	bx,cl
X	xorb	bh,bh		| kill sign bit (exponent is 8 bits)
X
X	mov	ax,4+6(si)	| remove exponent from mantissa
X	and	ax,#0x7F
X	test	bx,bx		| check for zero exponent - no leading "1"
X	jz	0f		| for denormalized numbers
X	or	ax,#0x80	| restore implied leading "1"
X0:	mov	4+6(si),ax
X
X	add	bx,#BIAS8-BIAS4-3	| adjust bias, account for shift
X	xorb	dl,dl
X
X	pop	si		| restore si
X	jmp	.norm8		| normalize and return
Xcff8:
X	cmp	dx,#8
X	jne	ill		| illegal EM op
X
X	cmp	cx,#4
X	jne	cff8_8
Xcff8_4:				| 8-byte double to 4-byte float
X	push	si
X	mov	si,sp
X
X	mov	bx,4+6(si)	| extract exp
X	movb	dh,bh		| extract sign
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	and	bx,#2047	| kill sign bit
X
X	mov	ax,4+6(si)	| remove exponent from v.mantissa
X	and	ax,#0x0F
X	test	bx,bx		| check for zero exponent - no leading "1"
X	jz	0f		| for denormalized numbers
X	or	ax,#0x10	| restore implied leading "1"
X0:	mov	4+6(si),ax
X
X	add	bx,#BIAS4-BIAS8	| adjust bias
X
X	mov	cx,#3		| shift up to realign mantissa for floats
X1:	shl	4+0(si),*1
X	rcl	4+2(si),*1
X	rcl	4+4(si),*1
X	rcl	4+6(si),*1
X	loop	1b
X
X	movb	dl,4+3(si)	| set rounding bits
X	mov	ax,4+0(si)	| check to see if sticky bit should be set
X	orb	al,4+2(si)
X	or	ax,ax
X	jz	2f
X	orb	dl,*1		| set sticky bit
X
X2:	pop	si		| restore si
X	pop	cx		| cx = return address
X	add	sp,#4		| remove lower 32 bits
X	push	cx		| put return address back
X	jmp	.norm4
Xcff8_8:
X	cmp	cx,#8
X	jne	ill		| illegal EM op
X	ret			| redundant
X
Xill:
X	pop	bx 
X	jmp	.trpilin
END_OF_FILE
if test 2066 -ne `wc -c <'cff.x'`; then
    echo shar: \"'cff.x'\" unpacked with wrong size!
fi
# end of 'cff.x'
fi
if test -f 'cfi.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cfi.x'\"
else
echo shar: Extracting \"'cfi.x'\" \(3518 characters\)
sed "s/^X//" >'cfi.x' <<'END_OF_FILE'
X.define .cfi
X| 
X| floating point => integer conversion routines
X| author: Peter S. Housel 6/12/89,6/14/89
X|
X
XBIAS4	=	0x7F - 1
XBIAS8	=	0x3FF - 1
X
X	.text
X	.globl	.cfi
X|
X| on entry dx=source size, cx=dest. size
X|
X.cfi:
X	push	si		| save register variable
X	mov	si,sp
X
X	cmp	dx,#4
X	jne	cfi8
Xcfi4:
X	mov	bx,4+2(si)	| extract exp
X	movb	dh,bh		| extract sign
X	shl	bx,*1		| shift up one, then down 8
X	movb	bl,bh
X	xorb	bh,bh
X
X	mov	ax,4+2(si)	| remove exponent from mantissa
X	and	ax,#0x7F
X	test	bx,bx		| check for zero exponent - no leading "1"
X	jz	0f		| for denormalized numbers
X	or	ax,#0x80	| restore implied leading "1"
X0:	mov	4+2(si),ax
X
X	cmp	bx,#BIAS4	| check exponent
X	jl	zer4		| strictly fractional, no integer part?
X	cmp	bx,#BIAS4+32	| is it too big to fit in a 32-bit integer?
X	jg	toobig
X
X1:	cmp	bx,#BIAS4+24	| shifted all the way down yet?
X	jge	2f
X	shr	4+2(si),*1	| shift down to align radix point;
X	rcr	4+0(si),*1	| extra bits fall off the end (no rounding)
X	inc	bx
X	jmp	1b
X
X2:	cmp	bx,#BIAS4+24	| do we have to shift up?
X	jle	3f
X	shl	4+0(si),*1	| shift up to align radix point
X	rcl	4+2(si),*1
X	dec	bx
X	jmp	2b
Xzer4:
X	xor	ax,ax		| make the whole thing zero
X	mov	4+0(si),ax
X	mov	4+2(si),ax
X
X3:	jmp	cfi8b		| amazingly, we can share the rest of the code
X
Xcfi8:
X	cmp	dx,#8
X	jne	ill		| illegal EM op
X
X	mov	bx,4+6(si)	| extract exp
X	movb	dh,bh		| extract sign
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	and	bx,#2047	| kill sign bit
X
X	mov	ax,4+6(si)	| remove exponent from mantissa
X	and	ax,#0x0F
X	test	bx,bx		| check for zero exponent - no leading "1"
X	jz	0f		| for denormalized numbers
X	or	ax,#0x10	| restore implied leading "1"
X0:	mov	4+6(si),ax
X
X	cmp	bx,#BIAS8	| check exponent
X	jl	zer8		| strictly fractional, no integer part?
X	cmp	bx,#BIAS8+32	| is it too big to fit in a 32-bit integer?
X	jg	toobig
X
X1:	cmp	bx,#BIAS8+53	| shifted all the way down yet?
X	jge	cfi8b
X	shr	4+6(si),*1	| shift down to align radix point;
X	rcr	4+4(si),*1	| extra bits fall off the end (no rounding)
X	rcr	4+2(si),*1
X	rcr	4+0(si),*1
X	inc	bx
X	jmp	1b
Xzer8:
X	xor	ax,ax		| make the whole thing zero
X	mov	4+0(si),ax
X	mov	4+2(si),ax
X	mov	4+4(si),ax
X	mov	4+6(si),ax
X
Xcfi8b:	cmp	cx,#2
X	jne	cfi8_4
Xcfi8_2:				| 8-byte float to 2-byte integer
X	mov	ax,4+2(si)
X	or	ax,ax
X	jnz	toobig		| too big to fit into a 16-bit integer?
X	mov	ax,4+0(si)
X	cmp	ax,#0x8000	| -32768 is a nasty evil special case
X	jnz	0f
X	testb	dh,#128		| this had better be -32768 and not 32768
X	jz	toobig
X	jmp	3f
X0:	test	ax,ax		| otherwise, sign bit set? (i.e. too big?)
X	js	toobig
X	testb	dh,dh		| need to negate?
X	jns	3f
X	neg	ax
X3:	pop	si		| restore si
X	pop	bx		| save program counter
X	xorb	dh,dh		| dl still contains source size
X	add	sp,dx		| get rid of source value
X	push	ax		| put return value on stack
X	push	bx		| put back return address
X	ret
Xcfi8_4:				| 8-byte float to 4-byte integer
X	cmp	cx,#4
X	jne	ill
X	mov	ax,4+0(si)	| put integer into registers
X	mov	cx,4+2(si)
X	cmp	cx,#0x8000	| -2147483648 is a nasty evil special case
X	jnz	6f
X	test	ax,ax
X	jnz	toobig
X	testb	dh,#128		| this had better be -2^31 and not 2^31
X	jz	toobig
X	jmp	8f
X6:	test	cx,cx		| sign bit set? (i.e. too big)
X	js	toobig
X	testb	dh,dh		| is it negative?
X	jns	8f
X	neg	ax		| negate
X	neg	cx
X	sbb	cx,#0
X8:
X	pop	si		| restore si
X	pop	bx		| save program counter
X	xorb	dh,dh		| dl still contains source size
X	add	sp,dx		| get rid of source value
X	push	cx		| put return value on stack
X	push	ax
X	push	bx		| put back return address
X	ret
Xill:
X	pop	bx 
X	jmp	.trpilin
X
XECONV	=	10
X	.globl	.fat
Xtoobig:
X	mov	ax,#ECONV
X	push	ax
X	jmp	.fat
END_OF_FILE
if test 3518 -ne `wc -c <'cfi.x'`; then
    echo shar: \"'cfi.x'\" unpacked with wrong size!
fi
# end of 'cfi.x'
fi
if test -f 'cif.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cif.x'\"
else
echo shar: Extracting \"'cif.x'\" \(1680 characters\)
sed "s/^X//" >'cif.x' <<'END_OF_FILE'
X.define .cif
X| 
X| floating point <=> integer conversion routines
X| author: Peter S. Housel 3/28/89
X|
X
XBIAS4	=	0x7F - 1
XBIAS8	=	0x3FF - 1
X
X	.text
X	.globl	.cif
X|
X| on entry dx=source size, cx=dest. size
X|
X.cif:
X	pop	bx		| save return address
X	cmp	dx,#2
X	jne	cif4
Xcif2:
X	pop	ax
X	test	ax,ax		| check sign of ax
X	jge	1f		| nonnegative
X	neg	ax		| take absolute value
X	movb	dh,*128		| set sign flag to negative
X1:	push	ax
X	cmp	cx,#4
X	jne	cif2_8
Xcif2_4:				| 2-byte integer to 4-byte float
X	xor	ax,ax
X	push	ax		| pad rest of mantissa with zeroes
X	push	bx		| restore return address
X	mov	bx,#BIAS4+16-8	| radix point just after most sig. word
X	xorb	dl,dl		| set rounding = 0
X	jmp	.norm4
Xcif2_8:				| 2-byte integer to 8-byte double
X	cmp	cx,#8
X	jne	ill		| illegal EM op
X	xor	ax,ax
X	push	ax		| pad rest of mantissa with zeroes
X	push	ax
X	push	ax	
X	push	bx		| restore return address
X	mov	bx,#BIAS8+16-11	| radix point just after most sig. word
X	xorb	dl,dl		| rounding = 0
X	jmp	.norm8
X
Xcif4:
X	cmp	dx,#4
X	jne	ill		| illegal EM op
X	pop	ax
X	pop	dx
X	test	dx,dx		| check sign of number
X	jge	2f
X	not	ax		| negate
X	not	dx
X	inc	ax
X	adc	dx,#0
X	push	dx
X	movb	dh,*128
X	jmp	3f
X2:	push	dx
X3:	push	ax
X	cmp	cx,#4
X	jne	cif4_8
Xcif4_4:				| 4-byte unsigned to 4-byte float
X	push	bx		| restore return address
X	mov	bx,#BIAS4+32-8	| radix point at end
X	xorb	dl,dl		| rounding = 0 (if positive, dh already 0)
X	jmp	.norm4
Xcif4_8:
X	cmp	cx,#8
X	jne	ill		| illegal EM op
X	xor	ax,ax
X	push	ax		| zero-fill rest of mantissa
X	push	ax
X	push	bx		| restore return address
X	mov	bx,#BIAS8+32-11	| radix point just after first 32 bits
X	xorb	dl,dl		| rounding = 0 (if positive, dh already 0)
X	jmp	.norm8
X
Xill:
X	pop	bx 
X	jmp	.trpilin
END_OF_FILE
if test 1680 -ne `wc -c <'cif.x'`; then
    echo shar: \"'cif.x'\" unpacked with wrong size!
fi
# end of 'cif.x'
fi
if test -f 'cuf.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cuf.x'\"
else
echo shar: Extracting \"'cuf.x'\" \(1303 characters\)
sed "s/^X//" >'cuf.x' <<'END_OF_FILE'
X.define .cuf
X| 
X| floating point <=> unsigned conversion routines
X| author: Peter S. Housel 3/28/89
X|
X
XBIAS4	=	0x7F - 1
XBIAS8	=	0x3FF - 1
X
X	.text
X	.globl	.cuf
X|
X| on entry dx=source size, cx=dest. size
X|
X.cuf:
X	pop	bx		| save return address
X	cmp	dx,#2
X	jne	cuf4
Xcuf2:
X	cmp	cx,#4
X	jne	cuf2_8
Xcuf2_4:				| 2-byte unsigned to 4-byte float
X	xor	ax,ax
X	push	ax		| pad rest of mantissa with zeroes
X	push	bx		| restore return address
X	mov	bx,#BIAS4+16-8	| radix point just after most sig. word
X	xor	dx,dx		| sign = rounding = 0
X	jmp	.norm4
Xcuf2_8:
X	cmp	cx,#8
X	jne	ill		| illegal EM op
X	xor	ax,ax
X	push	ax		| pad rest of mantissa with zeroes
X	push	ax
X	push	ax	
X	push	bx		| restore return address
X	mov	bx,#BIAS8+16-11	| radix point just after most sig. word
X	xor	dx,dx		| sign = rounding = 0
X	jmp	.norm8
X
Xcuf4:
X	cmp	dx,#4
X	jne	ill		| illegal EM op
X	cmp	cx,#4
X	jne	cuf4_8
Xcuf4_4:				| 4-byte unsigned to 4-byte float
X	push	bx		| restore return address
X	mov	bx,#BIAS4+32-8	| radix point at end
X	xor	dx,dx		| sign = rounding = 0
X	jmp	.norm4
Xcuf4_8:
X	cmp	cx,#8
X	jne	ill		| illegal EM op
X	xor	ax,ax
X	push	ax		| zero-fill rest of mantissa
X	push	ax
X	push	bx		| restore return address
X	mov	bx,#BIAS8+32-11	| radix point just after first 32 bits
X	xor	dx,dx		| sign = rounding = 0
X	jmp	.norm8
X
Xill:
X	pop	bx 
X	jmp	.trpilin
END_OF_FILE
if test 1303 -ne `wc -c <'cuf.x'`; then
    echo shar: \"'cuf.x'\" unpacked with wrong size!
fi
# end of 'cuf.x'
fi
if test -f 'dvf8.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dvf8.x'\"
else
echo shar: Extracting \"'dvf8.x'\" \(2526 characters\)
sed "s/^X//" >'dvf8.x' <<'END_OF_FILE'
X.define .dvf8
X| 
X| floating point divide routine
X| author: Peter S. Housel 4/8/89,6/2/89,6/13/89
X|
X
XU	=	14		| offset of dividend
XV	=	6		| offset of divisor
XBIAS8	=	0x3FF - 1
X
X	.text
X	.globl	.dvf8
X.dvf8:
X	push	si		| save register variables
X	push	di
X
X	mov	si,sp		| point to arguments
X
X	mov	bx,6+U(si)	| extract u.exp
X	movb	dh,bh		| extract u.sign
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	and	bx,#2047	| kill sign bit
X
X	mov	cx,6+V(si)	| extract v.exp
X	movb	dl,ch		| extract v.sign
X	shr	cx,*1
X	shr	cx,*1
X	shr	cx,*1
X	shr	cx,*1
X	and	cx,#2047	| kill sign bit
X
X	mov	ax,6+U(si)	| remove exponent from u.mantissa
X	and	ax,#0x0F
X	test	bx,bx		| check for zero exponent - no leading "1"
X	jz	0f
X	or	ax,#0x10	| restore implied leading "1"
X0:	mov	6+U(si),ax
X	or	ax,4+U(si)
X	or	ax,2+U(si)
X	or	ax,0+U(si)
X	jz	retz		| dividing zero
X
X	mov	ax,6+V(si)	| remove exponent from v.mantissa
X	and	ax,#0x0F
X	test	cx,cx		| check for zero exponent - no leading "1"
X	jz	0f
X	or	ax,#0x10	| restore implied leading "1"
X0:	mov	6+V(si),ax
X	or	ax,4+V(si)
X	or	ax,2+V(si)
X	or	ax,0+V(si)
X	jz	divz		| dividing by zero
X
X	xorb	dh,dl		| xor sign bits for resultant sign
X	sub	bx,cx		| subtract exponents,
X	add	bx,#BIAS8-11+1	| add bias back in, account for shift
X
X	xor	ax,ax		| zero the quotient
X	push	ax
X	push	ax
X	push	ax
X	push	ax
X	mov	di,sp		| di => quotient
X
X	mov	ax,0+V(si)	| initial subtraction
X	sub	0+U(si),ax
X	mov	ax,2+V(si)
X	sbb	2+U(si),ax
X	mov	ax,4+V(si)
X	sbb	4+U(si),ax
X	mov	ax,6+V(si)
X	sbb	6+U(si),ax
X
X	mov	cx,#64		| loop on all bits
X	jmp	3f		| skip first shift of quotient
X2:
X	shl	0(di),*1	| shift quotient
X	rcl	2(di),*1
X	rcl	4(di),*1
X	rcl	6(di),*1
X3:
X	shl	0+U(si),*1	| shift dividend
X	rcl	2+U(si),*1
X	rcl	4+U(si),*1
X	rcl	6+U(si),*1
X
X	jc	4f		| if carry set, add
X
X	mov	ax,0+V(si)	| else subtract
X	sub	0+U(si),ax
X	mov	ax,2+V(si)
X	sbb	2+U(si),ax
X	mov	ax,4+V(si)
X	sbb	4+U(si),ax
X	mov	ax,6+V(si)
X	sbb	6+U(si),ax
X
X	orb	0(di),*1	| set bit zero of quotient
X
X	loop	2b
X	jmp	5f
X4:
X	mov	ax,0+V(si)	| add (restore)
X	add	0+U(si),ax
X	mov	ax,2+V(si)
X	adc	2+U(si),ax
X	mov	ax,4+V(si)
X	adc	4+U(si),ax
X	mov	ax,6+V(si)
X	adc	6+U(si),ax
X
X	loop	2b		| loop
X5:
X	add	si,#U		| si => u, di => quotient
X	xchg	si,di		| reverse for move into u's location
X	mov
X	mov
X	mov
X	mov
X	add	sp,#8		| remove result
X9:	pop	di		| restore register variables
X	pop	si
X	pop	cx		| save return address
X	add	sp,#8		| remove v
X	push	cx		| restore return address
X	xorb	dl,dl		| zero rounding bits
X	jmp	.norm8
X
Xretz:	xor	bx,bx
X	xor	dx,dx
X	jmp	9b
X
X	.globl	.fat
XEFDIVZ	=	7
Xdivz:
X	mov	ax,#EFDIVZ
X	push	ax
X	call	.fat
END_OF_FILE
if test 2526 -ne `wc -c <'dvf8.x'`; then
    echo shar: \"'dvf8.x'\" unpacked with wrong size!
fi
# end of 'dvf8.x'
fi
if test -f 'exp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'exp.c'\"
else
echo shar: Extracting \"'exp.c'\" \(1386 characters\)
sed "s/^X//" >'exp.c' <<'END_OF_FILE'
X/* exp.c */
X
X#include <limits.h>
X#include <math.h>
X#include <errno.h>
Xextern int errno;
X
Xextern double _poly(/* double z, double coeff[], int ncoeff */);
X
X#define	LOG2E	1.4426950408889633870E0			/* 1/(ln 2) */
X#define LOG2	6.9314718055994530942705877E-1		/* ln 2 */
X
Xstatic double expcoeff[] =
X       {
X	1.0000000000000000000E0,	/* 1/0! */
X	1.0000000000000000000E0,	/* 1/1! */
X	0.5000000000000000000E0,	/* 1/2! and so on */
X	0.1666666666666666667E0,
X	0.0416666666666666667E0,
X	0.0083333333333333333E0,
X	0.0013888888888888889E0,
X	1.9841269841269841270E-4,
X	2.4801587301587301587E-5,
X	2.7557319223985894396E-6,
X	2.7557319223985894396E-7,
X	2.5052108385441722582E-8,
X	2.0876756987868101412E-9,	/* after 1/10! things get dubious. */
X	1.6059043836821618179E-10,
X	1.1470745597729725684E-11,
X	7.6471637318198171229E-13,
X	4.7794773323873860349E-14,
X	2.8114572543455219389E-15,
X	1.5619206968586232698E-16,
X       };
X
X#define	NCOEFF	((sizeof expcoeff) / sizeof(double))
X
Xdouble exp(x)
Xdouble x;
X{
X double ipart, frac;
X
X frac = modf(x * LOG2E, &ipart);
X
X if(frac > 0.5)
X   {
X    ipart += 1.0;
X    frac -= 1.0;
X   }
X else if(frac < -0.5)
X   {
X    ipart -= 1.0;
X    frac += 1.0;
X   }
X
X if(ipart < (double) INT_MIN)		/* really small */
X    return 0;
X else if(ipart > (double) INT_MAX)	/* really big */
X    ipart = (double) INT_MAX;
X
X return ldexp(_poly(frac * LOG2, expcoeff, NCOEFF), (int) ipart);
X}
END_OF_FILE
if test 1386 -ne `wc -c <'exp.c'`; then
    echo shar: \"'exp.c'\" unpacked with wrong size!
fi
# end of 'exp.c'
fi
if test -f 'float.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'float.h'\"
else
echo shar: Extracting \"'float.h'\" \(747 characters\)
sed "s/^X//" >'float.h' <<'END_OF_FILE'
X/* float.h */
X/* Produced by config version 4.1, CWI, Amsterdam */
X/* (on an Ardent Titan)
X/* hand-modified by Peter S. Housel */
X
X#define FLT_RADIX		2
X#define FLT_MANT_DIG		24
X#define FLT_DIG			6
X#define FLT_ROUNDS		1
X#define FLT_EPSILON		((float)1.19209290e-07)
X#define FLT_MIN_EXP		(-125)
X#define FLT_MIN			((float)1.17549435e-38)
X#define FLT_MIN_10_EXP		(-37)
X#define FLT_MAX_EXP		128
X#define FLT_MAX			((float)3.40282347e+38)
X#define FLT_MAX_10_EXP		38
X
X#define DBL_MANT_DIG		53
X#define DBL_DIG			15
X#define DBL_EPSILON		2.2204460492503130e-16
X#define DBL_MIN_EXP		(-1021)
X#define DBL_MIN			2.2250738585072022e-308
X#define DBL_MIN_10_EXP		(-307)
X#define DBL_MAX_EXP		1024
X#define DBL_MAX			1.7976931348623159e+308
X#define DBL_MAX_10_EXP		308
END_OF_FILE
if test 747 -ne `wc -c <'float.h'`; then
    echo shar: \"'float.h'\" unpacked with wrong size!
fi
# end of 'float.h'
fi
if test -f 'fpp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fpp.c'\"
else
echo shar: Extracting \"'fpp.c'\" \(13586 characters\)
sed "s/^X//" >'fpp.c' <<'END_OF_FILE'
X/* file: fpp.c
X * EM floating-point-translator for i8088 Minix
X * (EXTREMELY machine and compiler-dependant!)
X * author: Peter S. Housel 6/12/89
X */
X
X#include <stdio.h>
X/* #include <stddef.h> */
X/* #include <stdlib.h> */
X
Xunion munge			/* type-punning */
X      {
X       double dpart;
X       float fpart;
X       int ipart[4];
X      };
X
Xextern double atof(/* const char * */);
X
Xmain(argc, argv)
Xint argc; char *argv[];
X{
X if(++argv, --argc)
X    if(strcmp(*argv, "-") != 0)
X       if(freopen(*argv, "rb", stdin) == NULL)
X	 {
X          fprintf(stderr, "fpp: can't open %s for input\n", *argv);
X	  exit(1);
X	 }
X
X if(++argv, --argc)
X    if(strcmp(*argv, "-") != 0)
X       if(freopen(*argv, "wb", stdout) == NULL)
X	 {
X          fprintf(stderr, "fpp: can't open %s for output\n", *argv);
X	  exit(1);
X	 }
X
X if(argc > 1)
X   {
X    fprintf(stderr, "fpp: usage: fpp [infile] [outfile]\n");
X    exit(1);
X   }
X
X filein();
X
X exit(0);
X}
X
Xstruct instrtab
X       {
X	char *iname;		/* instruction name */
X        char tag; 		/* argument description tag */
X       };
X
Xstruct instrtab itab[] = {			/* EM instructions */
X"NON", '-',	/* [Illegal instruction] */
X"AAR", 'w',	/* Load address of array element */
X"ADF", 'w',	/* Floating add */
X"ADI", 'w',	/* Addition */
X"ADP", 'f',	/* Add f to pointer on top of stack */
X"ADS", 'w',	/* Add w-byte value and pointer */
X"ADU", 'w',	/* Addition */
X"AND", 'w',	/* Boolean and on two groups of w bytes */
X"ASP", 'f',	/* Adjust the stack pointer by f */
X"ASS", 'w',	/* Adjust the stack pointer by w-byte integer */
X"BEQ", 'b',	/* Branch equal */
X"BGE", 'b',	/* Branch greater or equal */
X"BGT", 'b',	/* Branch greater */
X"BLE", 'b',	/* Branch less or equal */
X"BLM", 'z',	/* Block move z bytes; first pop dest. addr, then source */
X"BLS", 'w',	/* Block move, size is in w-byte integer on top of stack */
X"BLT", 'b',	/* Branch less (pop 2 words, branch if top > second) */
X"BNE", 'b',	/* Branch not equal */
X"BRA", 'b',	/* Branch unconditionally to label b */
X"CAI", '-',	/* Call procedure (procedure identifier on stack) */
X"CAL", 'p',	/* Call procedure (with identifier p) */
X"CFF", '-',	/* Convert floating to floating */
X"CFI", '-',	/* Convert floating to integer */
X"CFU", '-',	/* Convert floating to unsigned */
X"CIF", '-',	/* Convert integer to floating */
X"CII", '-',	/* Convert integer to integer */
X"CIU", '-',	/* Convert integer to unsigned */
X"CMF", 'w',	/* Compare w byte reals */
X"CMI", 'w',	/* Compare w byte int, push neg., zero, pos. for <, = or > */
X"CMP", '-',	/* Compare pointers */
X"CMS", 'w',	/* Compare w byte values, used only for bit equality test */
X"CMU", 'w',	/* Compare w byte unsigneds */
X"COM", 'w',	/* Complement (one's complement of top w bytes) */
X"CSA", 'w',	/* Case jump; address of jump table at top of stack */
X"CSB", 'w',	/* Table lookup jump; address of jump table at top of stack */
X"CUF", '-',	/* Convert unsigned to floating */
X"CUI", '-',	/* Convert unsigned to integer */
X"CUU", '-',	/* Convert unsigned to unsigned */
X"DCH", '-',	/* Follow dynamic chain, convert LB to LB of caller */
X"DEC", '-',	/* Decrement word on top of stack by 1 */
X"DEE", 'g',	/* Decrement external */
X"DEL", 'l',	/* Decrement local or parameter */
X"DUP", 's',	/* Duplicate top s bytes */
X"DUS", 'w',	/* Duplicate top w bytes */
X"DVF", 'w',	/* Floating divide */
X"DVI", 'w',	/* Division */
X"DVU", 'w',	/* Division */
X"EXG", 'w',	/* Exchange top w bytes */
X"FEF", 'w',	/* Split floating number in exponent and fraction part */
X"FIF", 'w',	/* Floating multiply and split integer and fraction part */
X"FIL", 'g',	/* File name (external 4 := g) */
X"GTO", 'g',	/* Non-local goto, descriptor at g */
X"INC", '-',	/* Increment word on top of stack by 1 */
X"INE", 'g',	/* Increment external */
X"INL", 'l',	/* Increment local or parameter */
X"INN", 'w',	/* Bit test on w byte set (bit number on top of stack) */
X"IOR", 'w',	/* Boolean inclusive or on two groups of w bytes */
X"LAE", 'g',	/* Load address of external */
X"LAL", 'l',	/* Load address of local or parameter */
X"LAR", 'w',	/* Load array element, desc. contains integers of size w */
X"LDC", 'd',	/* Load double constant ( push two words ) */
X"LDE", 'g',	/* Load double external (two consec. externals are stacked) */
X"LDF", 'f',	/* Load double offsetted (top of stack + f yield address) */
X"LDL", 'l',	/* Load double local or parameter (2 consec. words stacked) */
X"LFR", 's',	/* Load function result */
X"LIL", 'l',	/* Load word pointed to by l-th local or parameter */
X"LIM", '-',	/* Load 16 bit ignore mask */
X"LIN", 'n',	/* Line number (external 0 := n) */
X"LNI", '-',	/* Line number increment */
X"LOC", 'c',	/* Load constant (i.e. push one word onto the stack) */
X"LOE", 'g',	/* Load external word g */
X"LOF", 'f',	/* Load offsetted (top of stack + f yield address) */
X"LOI", 'o',	/* Load indirect o bytes (address is popped from the stack) */
X"LOL", 'l',	/* Load word at l-th local (l<0) or parameter (l>=0) */
X"LOR", 'r',	/* Load register (0=LB, 1=SP, 2=HP) */
X"LOS", 'w',	/* Load indirect, w-byte integer on stack top gives size */
X"LPB", '-',	/* Convert local base to argument base */
X"LPI", 'p',	/* Load procedure identifier */
X"LXA", 'n',	/* Load lexical (address of AB n static levels back) */
X"LXL", 'n',	/* Load lexical (address of LB n static levels back) */
X"MLF", 'w',	/* Floating multiply */
X"MLI", 'w',	/* Multiplication */
X"MLU", 'w',	/* Multiplication */
X"MON", '-',	/* Monitor call */
X"NGF", 'w',	/* Floating negate */
X"NGI", 'w',	/* Negate (two's complement) */
X"NOP", '-',	/* No operation */
X"RCK", 'w',	/* Range check; trap on error */
X"RET", 'z',	/* Return (function result consists of top z bytes) */
X"RMI", 'w',	/* Remainder */
X"RMU", 'w',	/* Remainder */
X"ROL", 'w',	/* Rotate left a group of w bytes */
X"ROR", 'w',	/* Rotate right a group of w bytes */
X"RTT", '-',	/* Return from trap */
X"SAR", 'w',	/* Store array element */
X"SBF", 'w',	/* Floating subtract */
X"SBI", 'w',	/* Subtraction */
X"SBS", 'w',	/* Subtract pointers in same fragment and push diff as size w integer */
X"SBU", 'w',	/* Subtraction */
X"SDE", 'g',	/* Store double external */
X"SDF", 'f',	/* Store double offsetted */
X"SDL", 'l',	/* Store double local or parameter */
X"SET", 'w',	/* Create singleton w byte set with bit n on (n is top of stack) */
X"SIG", '-',	/* Trap errors to proc identifier on top of stack, -2 resets default */
X"SIL", 'l',	/* Store into word pointed to by l-th local or parameter */
X"SIM", '-',	/* Store 16 bit ignore mask */
X"SLI", 'w',	/* Shift left */
X"SLU", 'w',	/* Shift left */
X"SRI", 'w',	/* Shift right */
X"SRU", 'w',	/* Shift right */
X"STE", 'g',	/* Store external */
X"STF", 'f',	/* Store offsetted */
X"STI", 'o',	/* Store indirect o bytes (pop address, then data) */
X"STL", 'l',	/* Store local or parameter */
X"STR", 'r',	/* Store register (0=LB, 1=SP, 2=HP) */
X"STS", 'w',	/* Store indirect, w-byte integer on top of stack gives object size */
X"TEQ", '-',	/* True if equal, i.e. iff top of stack = 0 */
X"TGE", '-',	/* True if greater or equal, i.e. iff top of stack >= 0 */
X"TGT", '-',	/* True if greater, i.e. iff top of stack > 0 */
X"TLE", '-',	/* True if less or equal, i.e. iff top of stack <= 0 */
X"TLT", '-',	/* True if less, i.e. iff top of stack < 0 */
X"TNE", '-',	/* True if not equal, i.e. iff top of stack non zero */
X"TRP", '-',	/* Cause trap to occur (Error number on stack) */
X"XOR", 'w',	/* Boolean exclusive or on two groups of w bytes */
X"ZEQ", 'b',	/* Branch equal zero */
X"ZER", 'w',	/* Load w zero bytes */
X"ZGE", 'b',	/* Branch greater or equal zero */
X"ZGT", 'b',	/* Branch greater than zero */
X"ZLE", 'b',	/* Branch less or equal to zero */
X"ZLT", 'b',	/* Branch less than zero (pop 1 word, branch negative) */
X"ZNE", 'b',	/* Branch not zero */
X"ZRE", 'g',	/* Zero external */
X"ZRF", 'w',	/* Load a floating zero of size w */
X"ZRL", 'l'	/* Zero local or parameter */
X};
X
Xstruct instrtab ptab[] = {			/* EM pseudo-ops */
X"BSS", '3',		/* Reserve storage */
X"CON", '*',		/* Initialized constants */
X"END", 'B',		/* End of procedure */
X"EXA", '1',		/* External name */
X"EXC", '2',		/* Exchange instruction blocks */
X"EXP", '1',		/* External procedure identifier */
X"HOL", '3',		/* Reserve global(?) storage */
X"INA", '1',		/* Internal name */
X"INP", '1',		/* Internal procedure name */
X"MES", '*',		/* Back-end hints */
X"PRO", 'A',		/* Start of procedure */
X"ROM", '*'		/* Read-only constants */
X};
X
Xfilein()
X{
X int ins;
X
X /* copy magic number */
X if(getchar() != 0255)
X   {
X    fprintf(stderr, "fpp: bad EM file magic number\n");
X    exit(1);
X   }
X putchar(0255);
X if(getchar() != 0)
X   {
X    fprintf(stderr, "fpp: bad EM file magic number\n");
X    exit(1);
X   }
X putchar(0);
X
X /* neutral state */
X while((ins = getchar()) != EOF)
X      {
X       if(0 <= ins && ins < sizeof itab / sizeof (struct instrtab))
X         {       /* instruction */
X	  putchar(ins);
X	  if(itab[ins].tag != '-')
X	     doargs(itab[ins].tag);
X	 }
X       else if(150 <= ins && ins < 150+(sizeof ptab)/sizeof(struct instrtab))
X	 {	/* pseudo-op */
X	  putchar(ins);
X	  doargs(ptab[ins - 150].tag);
X	 }
X       else if(180 <= ins && ins < 240)
X         {	/* instruction label */
X	  putchar(ins);
X	 }
X       else if(240 <= ins && ins < 245)
X	 {	/* instruction label */
X	  doarg(ins);
X	 }
X       else
X         {
X	  putchar(ins);
X	  fprintf(stderr, "illegal instruction byte %d\n", ins);
X	 }
X      } 
X}
X
Xdoargs(tag)
Xint tag;
X{
X int argbyte;
X
X switch(tag)
X       {
X	case '3':			/* three args */
X		doarg(getchar());
X		/* FALLTHRU */
X	case '2':			/* two args */
X		doarg(getchar());
X		/* FALLTHRU */
X	case '1':			/* one arg, of one of several types */
X	case 'c':
X	case 'd':
X	case 'l':
X	case 'g':
X	case 'f':
X	case 'n':
X	case 's':
X	case 'z':
X	case 'o':
X	case 'p':
X	case 'b':
X	case 'r':
X		doarg(getchar());
X		break;
X
X	case 'B':			/* one (optional) arg */
X	case 'w':
X		if((argbyte = getchar()) != 255)
X		   doarg(argbyte);
X		else
X		   putchar(argbyte);
X		break;
X
X	case '*':			/* any number of args */
X		while((argbyte = getchar()) != 255)
X		      doarg(argbyte);
X		putchar(255);
X		break;
X
X	case 'A':			/* one arg, one optional arg */
X		doarg(getchar());
X		if((argbyte = getchar()) != 255)
X		  {
X		   doarg(argbyte);
X		  }
X		else
X		   putchar(255);
X		break;
X       }
X}
X
Xdoarg(byte)
Xint byte;
X{
X int b1, b2, b3, b4;
X int length;
X int i;
X
X if(byte == EOF)
X   {
X    fprintf(stderr, "Unexpected eof\n");
X    exit(1);
X   }
X
X if(byte != 253)		/* special case floating point constant */
X    putchar(byte);
X
X if(0 <= byte && byte < 240)
X   {
X    /* nothing */
X   }
X else
X    switch(byte)
X	  {
X	   case 240:			/* 1-byte instruction label */
X		putchar(getchar());
X		break;
X	   case 241:			/* 2-byte instruction label */
X		b1 = getchar(); putchar(b1);
X		b2 = getchar(); putchar(b2);
X		break;
X	   case 242:			/* 1-byte data label */
X		putchar(getchar());
X		break;
X	   case 243:			/* 2-byte data label */
X		b1 = getchar(); putchar(b1);
X		b2 = getchar(); putchar(b2);
X		break;
X	   case 244:			/* global symbol */
X		length = getcst();
X		putcst(length);
X		while(length--)
X		      putchar(getchar());
X		break;
X	   case 245:			/* 2-byte integer constant */
X		b1 = getchar(); putchar(b1);
X		b2 = getchar(); putchar(b2);
X		break;
X	   case 246:			/* 4-byte integer constant */
X		b1 = getchar(); putchar(b1);
X		b2 = getchar(); putchar(b2);
X		b3 = getchar(); putchar(b3);
X		b4 = getchar(); putchar(b4);
X		break;
X	   case 247:			/* 8-byte integer constant */
X		length = 8;
X		while(length--)
X		      putchar(getchar());
X		break;
X	   case 248:			/* global label + constant */
X		doarg(getchar());	
X		putcst(getcst());
X		break;
X	   case 249:			/* procedure name */
X		length = getcst();
X		putcst(length);
X		while(length--)
X		      putchar(getchar());
X		break;
X	   case 250:			/* string */
X		length = getcst();
X		putcst(length);
X		while(length--)
X		      putchar(getchar());
X		break;
X	   case 251:			/* integer constant */
X		putcst(getcst());
X		length = getcst();
X		putcst(length);
X		while(length--)
X		      putchar(getchar());
X		break;
X	   case 252:			/* unsigned constant */
X		putcst(getcst());
X		length = getcst();
X		putcst(length);
X		while(length--)
X		      putchar(getchar());
X		break;
X	   case 253:			/* floating constant */
X		if((i = getcst()) == 8 || i == 4)
X		  {
X		   char buf[512];	/* for reading ASCII constant */
X		   char *bufp;
X		   union munge number;
X
X		   length = getcst();
X		   bufp = &buf[0];
X		   while(length-- && (bufp - buf) < (sizeof buf) - 1)
X		         *bufp++ = getchar();
X		   *bufp = '\0';
X
X		   if(i == 8)
X		     {
X		      number.dpart = atof(buf);	/* convert to a double, */
X		      putcst(number.ipart[0]);	/* then write out each */
X		      putcst(number.ipart[1]);	/* of the words that makes */
X		      putcst(number.ipart[2]);	/* it up as a 16-bit */
X		      putcst(number.ipart[3]);	/* integer constant */
X		     }
X		   else
X		     {
X		      number.fpart = (float) atof(buf);
X		      putcst(number.ipart[0]);
X		      putcst(number.ipart[1]);
X		     }
X		  }
X		else
X		   fprintf(stderr, "Illegal floating-point constant size\n");
X		break;
X	   case 254:
X	   case 255:
X		fprintf(stderr, "Illegal argument type %d\n", byte);
X	  }
X}
X
Xint getcst()
X{
X int b1, b2;
X int type;
X
X type = getchar();
X if(0 <= type && type < 240)	/* short constant */
X    return type - 120;
X
X if(type != 245)
X   {
X    fprintf(stderr, "Illegal constant argument type %d\n", type);
X   }
X
X b1 = getchar();		/* 16-bit integer constant */
X b2 = getchar();
X return 256 * b2 + b1; 
X}
X
Xputcst(number)
Xint number;
X{
X if(-120 <= number && number < 120)
X   {
X    putchar(number + 120);	/* short constant */
X    return;
X   }
X
X putchar(245);			/* 16-bit integer constant */
X putchar(number & 255);
X putchar((number >> 8) & 255);
X}
END_OF_FILE
if test 13586 -ne `wc -c <'fpp.c'`; then
    echo shar: \"'fpp.c'\" unpacked with wrong size!
fi
# end of 'fpp.c'
fi
if test -f 'modf.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'modf.x'\"
else
echo shar: Extracting \"'modf.x'\" \(1734 characters\)
sed "s/^X//" >'modf.x' <<'END_OF_FILE'
X.define	_modf
X
XBIAS8	=	0x3ff - 1
X
X	.globl	_modf
X	.text
X_modf:
X	push	bp
X	mov	bp,sp
X	push	si
X	mov	si,12(bp)	| si -> ipart
X
X	mov	bx,4+6(bp)	| extract value.exp
X	movb	dh,bh		| extract value.sign
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	shr	bx,*1
X	and	bx,#2047	| kill sign bit
X
X	cmp	bx,#BIAS8
X	jge	1f		| fabs(value) >= 1.0
X
X	xor	ax,ax		| store zero as the integer part
X	mov	0(si),ax
X	mov	2(si),ax
X	mov	4(si),ax
X	mov	6(si),ax
X
X	lea	bx,4(bp)	| return entire value as fractional part
X	mov	cx,#8
X	call	.loi
X9:	call	.ret8
X	jmp	.sret
X
X1:
X	cmp	bx,#BIAS8+53	| all integer, with no fractional part?
X	jl	2f		| no, mixed
X
X	lea	bx,4(bp)	| store entire value as the integer part
X	mov	cx,#8
X	call	.loi
X	mov	bx,si
X	mov	cx,#8
X	call	.sti
X
X	call	.zrf8
X	jmp	9b		| return zero as fractional part
X
X2:
X	mov	ax,4+6(bp)	| remove exponent from value.mantissa
X	and	ax,#0x0F
X	or	ax,#0x10	| restore implied leading "1"
X0:	mov	4+6(bp),ax
X
X	xor	ax,ax		| push a zero fractional part
X	push	ax
X	push	ax
X	push	ax
X	push	ax
X
X4:
X	shr	4+6(bp),*1	| shift integer part
X	rcr	4+4(bp),*1
X	rcr	4+2(bp),*1
X	rcr	4+0(bp),*1
X
X	rcr	-10+6(bp),*1	| shift high bit into fractional part
X	rcr	-10+4(bp),*1
X	rcr	-10+2(bp),*1
X	rcr	-10+0(bp),*1
X
X	inc	cx		| increment frac part exponent
X	inc	bx		| increment ipart exponent
X	cmp	bx,#BIAS8+53	| done?
X	jl	4b		| keep shifting
X
X	movb	dl,*0		| clear rounding bits
X	push	dx		| save sign and rounding bits
X
X	push	4+6(bp)		| push the integer part
X	push	4+4(bp)
X	push	4+2(bp)
X	push	4+0(bp)
X
X	call	.norm8		| renormalize the integer part
X
X	mov	bx,si		| store indirectly through the pointer
X	mov	cx,#8
X	call	.sti
X
X	pop	dx		| dx = frac part sign and rounding
X	mov	bx,#BIAS8-11	| bx = frac part exponent
X	call	.norm8		| normalize frac part
X	jmp	9b		| return frac part
END_OF_FILE
if test 1734 -ne `wc -c <'modf.x'`; then
    echo shar: \"'modf.x'\" unpacked with wrong size!
fi
# end of 'modf.x'
fi
if test -f 'norm4.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'norm4.x'\"
else
echo shar: Extracting \"'norm4.x'\" \(1618 characters\)
sed "s/^X//" >'norm4.x' <<'END_OF_FILE'
X.define .norm4
X
X	.globl	.norm4
X|
X| on entry to norm4:
X|	bx=u.exp dh=u.sign dl=rounding bits
X.norm4:
X	push	si		| save register variables
X	mov	si,sp		| si => u
X	add	si,#4
X
X	mov	ax,0(si)	| rounding and u.mant == 0?
X	orb	al,dl
X	or	ax,2(si)
X	jz	retz
X1:
X	mov	ax,2(si)	| divide (shift) until
X	and	ax,#0xff00	| no bits above 23
X	jz	2f
X	shr	2(si),*1
X	rcr	0(si),*1
X	rcrb	dl,*1		| shift into rounding bits
X	jnc	0f		| make least sig bit "sticky"
X	orb	dl,*1
X0:	inc	bx		| increment exponent
X	jmp	1b
X2:
X	mov	ax,2(si)	| multiply (shift) until
X	and	ax,#0xff80	| one in "implied" position
X	jnz	3f
X	shlb	dl,*1		| some doubt about this one *
X	rcl	0(si),*1
X	rcl	2(si),*1
X	dec	bx		| decrement exponent
X	jmp	2b
X3:
X	testb	dl,dl		| check rounding bits
X	jge	5f		| round down - no action necessary
X	negb	dl
X	jge	4f		| round up
X	and	0(si),#0xfffe	| tie case - round to even
X	jmp	5f
X4:
X	xorb	dl,dl		| zero rounding bits
X	add	0(si),#1	| round up
X	adc	2(si),#0
X	jmp	1b		| go back and renormalize just in case
X5:
X	cmp	bx,#0		| check for exponent overflow or underflow
X	jle	retz
X	cmp	bx,#255
X	jge	oflow
X6:
X	movb	cl,*7		| re-position exponent
X	shl	bx,cl
X	mov	ax,2(si)
X	and	ax,#0x7f	| top mantissa bits
X	or	ax,bx		| insert exponent
X	andb	dh,*128		| sign bit
X	orb	ah,dh		| insert sign bit
X	mov	2(si),ax
X	pop	si		| restore register variables
X	ret
X
Xretz:
X	xor	bx,bx		| exponent = 0,
X	mov	dx,bx		|      sign = 0, rounding = 0,
X	mov	0(si),bx	|      mantissa = 0
X	mov	2(si),bx
X	jmp	6b
X
X	.globl	.fat
XECONV	=	10
X	mov	ax,#ECONV
X	push	ax
X	jmp	.fat	
X
XEFOVFL	=	4
Xoflow:
X	mov	ax,#EFOVFL
X	push	ax
X	jmp	.fat
X
X|EFUNFL	=	5
X|uflow:	
X|	mov	ax,#EFUNFL
X|	push	ax
X|	jmp	.fat
END_OF_FILE
if test 1618 -ne `wc -c <'norm4.x'`; then
    echo shar: \"'norm4.x'\" unpacked with wrong size!
fi
# end of 'norm4.x'
fi
if test -f 'norm8.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'norm8.x'\"
else
echo shar: Extracting \"'norm8.x'\" \(1780 characters\)
sed "s/^X//" >'norm8.x' <<'END_OF_FILE'
X.define .norm8
X
X	.globl	.norm8
X|
X| on entry to norm8:
X|	bx=u.exp dh=u.sign dl=rounding bits
X.norm8:
X	push	si		| save register variables
X	mov	si,sp		| si => u
X	add	si,#4
X
X	mov	ax,0(si)	| rounding and u.mant == 0?
X	orb	al,dl
X	or	ax,2(si)
X	or	ax,4(si)
X	or	ax,6(si)
X	jz	retz
X1:
X	mov	ax,6(si)	| divide (shift) until
X	and	ax,#0xffe0	| no bits above 53
X	jz	2f
X	shr	6(si),*1
X	rcr	4(si),*1
X	rcr	2(si),*1
X	rcr	0(si),*1
X	rcrb	dl,*1		| shift into rounding bits
X	jnc	0f		| make least sig bit "sticky"
X	orb	dl,*1
X0:	inc	bx		| increment exponent
X	jmp	1b
X2:
X	mov	ax,6(si)	| multiply (shift) until
X	and	ax,#0xfff0	| one in "implied" position
X	jnz	3f
X	shlb	dl,*1		| some doubt about this one *
X	rcl	0(si),*1
X	rcl	2(si),*1
X	rcl	4(si),*1
X	rcl	6(si),*1
X	dec	bx		| decrement exponent
X	jmp	2b
X3:
X	testb	dl,dl		| check rounding bits
X	jge	5f		| round down - no action necessary
X	negb	dl
X	jge	4f		| round up
X	and	0(si),#0xfffe	| tie case - round to even
X	jmp	5f
X4:
X	xorb	dl,dl		| zero rounding bits
X	add	0(si),#1	| round up
X	adc	2(si),#0
X	adc	4(si),#0
X	jnc	5f		| no chance of "rounding overflow"
X	adc	6(si),#0	| some chance of rounding overflow - go
X	jmp	1b		|  back and renormalize just in case
X5:
X	cmp	bx,#0		| check for exponent underflow
X	jle	retz
X	cmp	bx,#2047	| check for exponent overflow
X	jge	oflow
X6:
X	shl	bx,*1		| re-position exponent
X	shl	bx,*1
X	shl	bx,*1
X	shl	bx,*1
X	mov	ax,6(si)
X	and	ax,#0xf		| top mantissa bits
X	or	ax,bx		| insert exponent
X	andb	dh,*128		| sign bit
X	orb	ah,dh		| insert sign bit
X	mov	6(si),ax
X	pop	si
X	ret
X
Xretz:
X	xor	bx,bx		| exponent = 0,
X	mov	dx,bx		|      sign = 0, rounding = 0
X	mov	0(si),bx
X	mov	2(si),bx
X	mov	4(si),bx
X	mov	6(si),bx
X	jmp	6b
X
XEFOVFL	=	4
X	.globl	.fat
Xoflow:
X	mov	ax,#EFOVFL
X	push	ax
X	jmp	.fat
X
X|EFUNFL	=	5
X|uflow:	
X|	mov	ax,#EFUNFL
X|	push	ax
X|	jmp	.fat
END_OF_FILE
if test 1780 -ne `wc -c <'norm8.x'`; then
    echo shar: \"'norm8.x'\" unpacked with wrong size!
fi
# end of 'norm8.x'
fi
if test -f 'strtod.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'strtod.c'\"
else
echo shar: Extracting \"'strtod.c'\" \(1737 characters\)
sed "s/^X//" >'strtod.c' <<'END_OF_FILE'
X/* file: strtod.c */
X
X#include <ctype.h>
X/* #include <stddef.h> */
X/* #include <stdlib.h> */
X
X#ifndef NULL
X#define NULL 0
X#endif
X
X#define MSIGN	1		/* mantissa has negative sign */
X#define ESIGN	2		/* exponent has negative sign */
X#define DECPT	4		/* decimal point encountered */
X
Xdouble strtod(s, endp)
Xregister char *s;
Xchar **endp;
X{
X int flags = 0;
X int decexp = 0;		/* decimal exponent */
X double value = 0;		/* accumulated value - actually */
X				/* a 64-bit integer */
X
X extern int _mul10add(/* double *valuep, int digit */);
X extern double _adjust(/* double *valuep, int decexp, int negflag */);
X
X while(isspace(*s))		/* skip leading white space */
X       ++s;
X
X if(*s == '+')
X    ++s;
X else if(*s == '-')
X   {
X    ++s;
X    flags |= MSIGN;		/* mantissa is negative */
X   }
X
X for(; ; ++s)
X    {
X     if(isdigit(*s))
X       {
X	if(_mul10add(&value, *s - '0'))
X  	   ++decexp;
X	if(flags & DECPT)
X	   --decexp;
X       }
X     else if(*s == '.')
X       {
X	flags |= DECPT;
X       }
X     else
X	break;
X    }
X
X if(*s == 'e' || *s == 'E')
X   {
X    int eacc = 0;		/* exponent accumulator */
X
X    ++s;
X  
X    if(*s == '+')
X       ++s;
X    else if(*s == '-')
X      {
X       ++s;
X       flags |= ESIGN;		/* decimal exponent is negative */
X      }
X    
X    while(isdigit(*s))
X         {
X	  if(eacc < 1000)
X	     eacc = eacc * 10 + (*s - '0');
X          ++s;
X         }
X
X    if(flags & ESIGN)
X       decexp -= eacc;
X    else
X       decexp += eacc;	
X   }
X
X if(decexp > 350)		/* outrageously large */
X    decexp = 350;
X else if(decexp < -350)		/* outrageously small */
X    decexp = -350;
X 
X if(endp != (char **)NULL)	/* store endp if desired */
X    *endp = s;
X
X if(value == 0)
X    return 0;
X else
X    return _adjust(&value, decexp, flags & MSIGN);
X}
END_OF_FILE
if test 1737 -ne `wc -c <'strtod.c'`; then
    echo shar: \"'strtod.c'\" unpacked with wrong size!
fi
# end of 'strtod.c'
fi
if test -f 'strtod_aux.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'strtod_aux.x'\"
else
echo shar: Extracting \"'strtod_aux.x'\" \(3370 characters\)
sed "s/^X//" >'strtod_aux.x' <<'END_OF_FILE'
X.define __mul10add,__adjust
X
X| 
X| auxiliary routines for strtod()
X| author: Peter S. Housel 6/3/89
X|
X
XBIAS8	=	0x3FF - 1
X
X	.globl __mul10add
X	.text
X__mul10add:
X	push	bp
X	mov	bp,sp
X	push	si
X	mov	si,4(bp)
X
X	mov	ax,#1			| return 1 if overflow
X	cmp	6(si),#3276		| would this digit cause overflow?
X	jg	1f
X
X	shl	0(si),*1		| multiply accumulator by 10 - first
X	rcl	2(si),*1		|  we multiply by two
X	rcl	4(si),*1
X	rcl	6(si),*1
X
X	push	6(si)			| save 2x value
X	push	4(si)
X	push	2(si)
X	push	0(si)
X
X	shl	0(si),*1		| multiply by four, to make this
X	rcl	2(si),*1		|  8x the original accumuator
X	rcl	4(si),*1
X	rcl	6(si),*1
X	shl	0(si),*1
X	rcl	2(si),*1
X	rcl	4(si),*1
X	rcl	6(si),*1
X
X	pop	ax			| add 2x value back in
X	add	0(si),ax
X	pop	ax
X	adc	2(si),ax
X	pop	ax
X	adc	4(si),ax
X	pop	ax
X	adc	6(si),ax
X
X	mov	ax,6(bp)		| get digit value
X	add	0(si),ax		| add it in
X	adc	2(si),#0
X	adc	4(si),#0
X	adc	6(si),#0
X
X	xor	ax,ax			| return zero overflow flag
X1:	jmp	.sret
X
X
X	.globl	__adjust
X__adjust:
X	push	bp
X	mov	bp,sp
X	push	si			| si => 64-bit accumulator
X	mov	si,4(bp)
X	push	di			| di = decimal exponent
X	mov	di,6(bp)
X
X	mov	bx,#0			| bx = binary scale factor
X	test	di,di			| check decimal exponent
X	jz	9f			| if zero, no scaling necessary
X	js	4f			| if negative, do division loop
X
X1:	cmp	6(si),#6553		| compare with 2^15 / 5
X	jb	2f			| no danger of overflow?
X	shr	6(si),*1		| could overflow; divide by two
X	rcr	4(si),*1		| to prevent it
X	rcr	2(si),*1
X	rcr	0(si),*1
X	inc	bx			| increment scale factor to compensate
X	jmp	1b			| try again to see if we're ok now
X2:					| now we multiply by 5:
X	push	6(si)			| save 1x value
X	push	4(si)
X	push	2(si)
X	push	0(si)
X
X	shl	0(si),*1		| multiply by four, 
X	rcl	2(si),*1
X	rcl	4(si),*1
X	rcl	6(si),*1
X
X	shl	0(si),*1
X	rcl	2(si),*1
X	rcl	4(si),*1
X	rcl	6(si),*1
X
X	pop	ax			| add 1x value back in
X	add	0(si),ax
X	pop	ax
X	adc	2(si),ax
X	pop	ax
X	adc	4(si),ax
X	pop	ax
X	adc	6(si),ax
X
X	inc	bx			| increment scale factor to make this
X					| a multiplication by 10
X	sub	di,#1			| decrement decimal exponent
X	jnz	1b			| keep scaling if not done
X
X	jmp	9f			| done with multiplication loop
X
X4:
X	test	6(si),#0xC000		| make sure upper bits set to preserve
X	jnz	5f			| as much precision as possible
X	shl	0(si),*1		| if not, multiply by 2
X	rcl	2(si),*1
X	rcl	4(si),*1
X	rcl	6(si),*1
X	dec	bx			| decrement scale factor to compensate
X	jmp	4b			| and check again
X5:
X	mov	cx,#5		 	| division by 5
X	xor	dx,dx			| start off with zero remainder
X	mov	ax,6(si)		| get word
X	div	cx			| divide dx/ax by 5
X	mov	6(si),ax		| store result; dx contains remainder
X	mov	ax,4(si)
X	div	cx
X	mov	4(si),ax
X	mov	ax,2(si)
X	div	cx
X	mov	2(si),ax
X	mov	ax,0(si)
X	div	cx
X	mov	0(si),ax
X
X	dec	bx			| increment scale factor to make this
X					| a division by 10
X	add	di,#1			| increment decimal exponent
X	jnz	4b			| keep looping if not done
X
X9:	push	bx			| scale factor; multiplier for ldexp()
X
X	push	6(si)			| copy value onto stack
X	push	4(si)
X	push	2(si)
X	push	0(si)
X
X	xor	dx,dx			| sign = 0, rounding bits = 0
X	mov	ax,8(bp)		| check sign flag argument
X	test	ax,ax
X	jz	0f
X	orb	dh,*128			| set sign bit in dh if negative
X0:	mov	bx,#BIAS8+53		| first normalize the number as
X	call	.norm8			| an integer,
X
X	call	_ldexp			| then re-scale it using ldexp()
X					| to check for over/underflow
X	add	sp,#10			| remove args
X
X|	call	.lfr8			| these cancel each other out;
X|	call	.ret8			| code generator should special-case
X	jmp	.dsret
END_OF_FILE
if test 3370 -ne `wc -c <'strtod_aux.x'`; then
    echo shar: \"'strtod_aux.x'\" unpacked with wrong size!
fi
# end of 'strtod_aux.x'
fi
if test -f 'trp.x' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'trp.x'\"
else
echo shar: Extracting \"'trp.x'\" \(2041 characters\)
sed "s/^X//" >'trp.x' <<'END_OF_FILE'
X.define .trp,.trpilin
X|.define .trpdivz,.trpcase,.trprang,.trpset,.trpnofp,.trpheap
X
X	.bss
X.M:	.zerow	24/2
X
X	.text
X	.globl	.trp,.trpilin
X|	.globl	.trpdivz,.trpcase,.trprang,.trpset,.trpnofp,.trpheap
X|.trpdivz:
X|	mov	ax,#6
X|	mov	dx,#.Mdivz
X|	jmp	.Trp
X.trpilin:
X	mov	ax,#18
X	mov	dx,#.Milin
X	jmp	.Trp
X|.trpcase:
X|	mov	ax,#20
X|	mov	dx,#.Mcase
X|	jmp	.Trp
X|.trprang:
X|	mov	ax,#1
X|	mov	dx,#.Mrang
X|	jmp	.Trp
X|.trpset:
X|	mov	ax,#2
X|	mov	dx,#.Mset
X|	jmp	.Trp
X|.trpnofp:
X|	mov	ax,#18
X|	mov	dx,#.Milin
X|	jmp	.Trp
X|.trpheap:
X|	mov	ax,#17
X|	mov	dx,#.Mheap
X||	jmp	.Trp
X.Trp:
X	xor	bx,bx
X	.globl	.trppc
X	xchg	bx,.trppc
X	test	bx,bx
X	jz	2f
X	push	ax
X	call	(bx)
X	pop	ax
X	ret
X2:
X	mov	bx,#22
X	push	bx
X	push	dx
X	mov	ax,#2
X	push	ax
X	call	.Write
X	call	_exit
X
X.trp:
X	mov	dx,ax
X	cmp	dx,#21
X	jae	1f
X	sal	dx,#1
X	mov	bx,#.Mtable
X	add	bx,dx
X	mov	bx,(bx)
X	test	bx,bx
X	jz	1f
X	mov	dx,bx
X	jmp	2f
X1:
X	mov	bx,#.Mtrp+14
X	mov	cx,#6
X	mov	dx,ax
X1:
X	and	dx,#7
X	add	dx,#'0'
X	movb	(bx),dl
X	dec	bx
X	sar	dx,#1
X	sar	dx,#1
X	sar	dx,#1
X	loop	1b
X	mov	dx,#.Mtrp
X2:
X	jmp	.Trp
X
X.Write:
X	push	bp
X	mov	bp,sp
X	mov	.M+2,#4
X	mov	bx,4(bp)
X	mov	.M+4,bx
X	mov	bx,8(bp)
X	mov	.M+6,bx
X	mov	bx,6(bp)
X	mov	.M+10,bx
X	mov	ax,#.M
X	push	ax
X	mov	ax,#1
X	push	ax
X
X	mov	ax,#1
X	mov	bx,#.M
X	mov	cx,#3
X	int	32
X	mov	sp,bp
X	pop	bp
X	ret
X
X	.data
X.Mtable:
X	.word	0, .Mrang, .Mset, 0, .Mfovf, .Mfunf, .Mdivz, .Mfdvz
X	.word	0, 0, .Mconv, 0, 0, 0, 0, 0
X	.word	0, .Mheap, .Milin, 0, .Mcase
X
X.Mrang:	.asciz	"Variable out of range\n"	| ERANGE	=	1
X.Mset:	.asciz	"Err in EM set instr  \n"	| ESET		=	2
X.Mfovf:	.asciz	"Floating pt. overflow\n"	| EFOVFL	=	4
X.Mfunf:	.asciz	"Floating pt underflow\n"	| EFUNFL	=	5
X.Mdivz:	.asciz	"Integer division by 0\n"	| EIDIVZ	=	6
X.Mfdvz:	.asciz	"Division by float 0.0\n"	| EFDIVZ	=	7
X|.Mfunf:.asciz	"Bad floating pt value\n"	| EFUND		=	9
X.Mconv:	.asciz	"Bad number conversion\n"	| ECONV		=	10
X.Mheap:	.asciz	"Heap overflow        \n"	| EHEAP		=	17
X.Milin:	.asciz	"Illegal EM instruct'n\n"	| EILLINS	=	18
X.Mcase:	.asciz	"Err in EM case instr \n"	| ECASE		=	20
X
X.Mtrp:	.asciz	"EM trap 0000000 octal\n"
END_OF_FILE
if test 2041 -ne `wc -c <'trp.x'`; then
    echo shar: \"'trp.x'\" unpacked with wrong size!
fi
# end of 'trp.x'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0