From f9447602b6eea651732d79fb5c195fb7f9c0d3fc Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Sun, 19 Nov 2017 18:08:49 -0800 Subject: [PATCH] FPU stack based libary --- src/inc/fpu.plh | 42 ++++++ src/libsrc/fpu.pla | 267 +++++++++++++++++++++++++++++++++++++++ src/makefile | 12 +- src/samplesrc/sanity.pla | 13 +- 4 files changed, 328 insertions(+), 6 deletions(-) create mode 100644 src/inc/fpu.plh create mode 100644 src/libsrc/fpu.pla diff --git a/src/inc/fpu.plh b/src/inc/fpu.plh new file mode 100644 index 0000000..5fcb8e7 --- /dev/null +++ b/src/inc/fpu.plh @@ -0,0 +1,42 @@ +import fpu +struc t_fpu +word reset +word pushDbl +word pushDbl +word pushDbl +word pushExt +word pushStr +word pullDbl +word pullDbl +word pullDbl +word pullExt +word pullStr +word loadDbl +word loadDbl +word loadDbl +word loadExt +word loadStr +word storDbl +word storDbl +word storDbl +word storExt +word storStr +word shiftUp +word shiftDown +word rotateUp +word rotateDown +word dup +word swap +word clear +word add +word sub +word mul +word div +word rem +word neg +word abs +word trunc +word round +word sqrt +end +end diff --git a/src/libsrc/fpu.pla b/src/libsrc/fpu.pla new file mode 100644 index 0000000..cb7e9f0 --- /dev/null +++ b/src/libsrc/fpu.pla @@ -0,0 +1,267 @@ +// +// SANE stack-based Floating Point Unit library +// +include "inc/cmdsys.plh" +include "inc/sane.plh" +include "inc/fpstr.plh" +// +// External interface to FPU library +// +//export word[] fpu +//word = @reset +//word = @pushDbl, @pushDbl, @pushDbl, @pushExt, @pushStr +//word = @pullDbl, @pullDbl, @pullDbl, @pullExt, @pullStr +//word = @loadDbl, @loadDbl, @loadDbl, @loadExt, @loadStr +//word = @storDbl, @storDbl, @storDbl, @storExt, @storStr +//word = @shiftUp, @shiftDown, @rotateUp, @rotateDown, @dup, @swap, @clear +//word = @add, @sub, @mul, @div, @rem +//word = @neg, @abs, @trunc, @round +// +// FP Stack +// +byte stack[t_extended*4] +word stackRegs[4] +// +// Stack manipulation routines +// +def rotateUp#1 + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[3], stackRegs[0], stackRegs[1], stackRegs[2] +end +def rotateDown#1 + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[1], stackRegs[2], stackRegs[3], stackRegs[0] +end +def shiftUp#1 + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[3], stackRegs[0], stackRegs[1], stackRegs[2] + memset(stackRegs[0], 0, t_extended) +end +def shiftDown#1 + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[1], stackRegs[2], stackRegs[3], stackRegs[0] + memset(stackRegs[3], 0, t_extended) +end +def dup#1 + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[3], stackRegs[0], stackRegs[1], stackRegs[2] + memcpy(stackRegs[0], stackRegs[1], t_extended) +end +def swap#1 + byte temp[t_extended] + memcpy(temp, stackRegs[1], t_extended) + memcpy(stackRegs[1], stackRegs[0], t_extended) + memcpy(stackRegs[0], temp, t_extended) +end +def clear#1 + memset(stackRegs[0], 0, t_extended) +end +// +// Stack access +// +def pushInt(pInt) + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[3], stackRegs[0], stackRegs[1], stackRegs[2] + sane:zpSave() + sane:fpOp2(FFINT|FOZ2X, stackRegs[0], pInt) + return sane:zpRestore() +end +def pullInt(pInt) + sane:zpSave() + sane:fpOp2(FFINT|FOX2Z, pInt, stackRegs[0]) + sane:zpRestore() + return shiftDown +end +def loadInt(pInt, reg) + sane:zpSave() + sane:fpOp2(FFINT|FOZ2X, stackRegs[reg & $03], pInt) + return sane:zpRestore() +end +def storeInt(pInt, reg) + sane:zpSave() + sane:fpOp2(FFINT|FOX2Z, pInt, stackRegs[reg & $03]) + return sane:zpRestore() +end +def pushSgl(pSgl) + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[3], stackRegs[0], stackRegs[1], stackRegs[2] + sane:zpSave() + sane:fpOp2(FFSGL|FOZ2X, stackRegs[0], pSgl) + return sane:zpRestore() +end +def pullSgl(pSgl) + sane:zpSave() + sane:fpOp2(FFSGL|FOX2Z, pSgl, stackRegs[0]) + sane:zpRestore() + return shiftDown +end +def loadSgl(pSgl, reg) + sane:zpSave() + sane:fpOp2(FFSGL|FOZ2X, stackRegs[reg & $03], pSgl) + return sane:zpRestore() +end +def storeSgl(pSgl, reg) + sane:zpSave() + sane:fpOp2(FFSGL|FOX2Z, pSgl, stackRegs[reg & $03]) + return sane:zpRestore() +end +def pushDbl(pDbl) + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[3], stackRegs[0], stackRegs[1], stackRegs[2] + sane:zpSave() + sane:fpOp2(FFDBL|FOZ2X, stackRegs[0], pDbl) + return sane:zpRestore() +end +def pullDbl(pDbl) + sane:zpSave() + sane:fpOp2(FFDBL|FOX2Z, pDbl, stackRegs[0]) + sane:zpRestore() + return shiftDown +end +def loadDbl(pDbl, reg) + sane:zpSave() + sane:fpOp2(FFDBL|FOZ2X, stackRegs[reg & $03], pDbl) + return sane:zpRestore() +end +def storeDbl(pDbl, reg) + sane:zpSave() + sane:fpOp2(FFDBL|FOX2Z, pDbl, stackRegs[reg & $03]) + return sane:zpRestore() +end +def pushExt(pExt) + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[3], stackRegs[0], stackRegs[1], stackRegs[2] + sane:zpSave() + sane:fpOp2(FFEXT|FOZ2X, stackRegs[0], pExt) + return sane:zpRestore() +end +def pullExt(pExt) + sane:zpSave() + sane:fpOp2(FFEXT|FOX2Z, pExt, stackRegs[0]) + sane:zpRestore() + return shiftDown +end +def loadExt(pExt, reg) + sane:zpSave() + sane:fpOp2(FFEXT|FOZ2X, stackRegs[reg & $03], pExt) + return sane:zpRestore() +end +def storeExt(pExt, reg) + sane:zpSave() + sane:fpOp2(FFEXT|FOX2Z, pExt, stackRegs[reg & $03]) + return sane:zpRestore() +end +def pushStr(pStr) + stackRegs[0], stackRegs[1], stackRegs[2], stackRegs[3] = stackRegs[3], stackRegs[0], stackRegs[1], stackRegs[2] + sane:zpSave() + str2ext(pStr, stackRegs[0]) + return sane:zpRestore() +end +def pullStr(pStr, sigdigits, expformat) + sane:zpSave() + ext2str(stackRegs[0], pStr, sigdigits, expformat) + sane:zpRestore() + return shiftDown +end +def loadStr(pStr, reg) + sane:zpSave() + str2ext(pStr, stackRegs[reg]) + return sane:zpRestore() +end +def storStr(pStr, sigdigits, expformat, reg) + sane:zpSave() + ext2str(stackRegs[reg], pStr, sigdigits, expformat) + return sane:zpRestore() +end +// +// Basic math operations +// +def add#1 + sane:zpSave() + sane:fpOp2(FFEXT|FOADD, stackRegs[1], stackRegs[0]) + sane:zpRestore() + return shiftDown +end +def sub#1 + sane:zpSave() + sane:fpOp2(FFEXT|FOSUB, stackRegs[1], stackRegs[0]) + sane:zpRestore() + return shiftDown +end +def mul#1 + sane:zpSave() + sane:fpOp2(FFEXT|FOMUL, stackRegs[1], stackRegs[0]) + sane:zpRestore() + return shiftDown +end +def div#1 + sane:zpSave() + sane:fpOp2(FFEXT|FODIV, stackRegs[1], stackRegs[0]) + sane:zpRestore() + return shiftDown +end +def rem#1 + sane:zpSave() + sane:fpOp2(FFEXT|FOREM, stackRegs[1], stackRegs[0]) + sane:zpRestore() + return shiftDown +end +def neg#1 + sane:zpSave() + sane:fpOp1(FFEXT|FONEG, stackRegs[0]) + return sane:zpRestore() +end +def abs#1 + sane:zpSave() + sane:fpOp1(FFEXT|FOABS, stackRegs[0]) + return sane:zpRestore() +end +def trunc#1 + sane:zpSave() + sane:fpOp1(FFEXT|FOTTI, stackRegs[0]) + return sane:zpRestore() +end +def round#1 + sane:zpSave() + sane:fpOp1(FFEXT|FORTI, stackRegs[0]) + return sane:zpRestore() +end +def sqrt#1 + sane:zpSave() + sane:fpOp1(FFEXT|FOSQRT, stackRegs[0]) + return sane:zpRestore() +end +// +// Reset FPU and SANE +// +def reset#1 + byte i + word zero + + zero = 0 + sane:fpInit() + sane:zpSave() + for i = 0 to 3 + stackRegs[i] = @stack[i * t_extended] + sane:fpOp2(FFINT|FOZ2X, stackRegs[i], @zero) + next + return sane:zpRestore() +end +// +// Test code +// +def dumpStack#0 + byte r + byte regStr[24] + + for r = 3 downto 0 + storStr(@regStr, 8, 0, r) + puts(" "); puti(r); putc(':'); puts(@regStr); putln + next +end +// +// Run through some test cases +// +reset +dumpStack +puts("Push 2.0\n") +pushStr("2.0") +dumpStack +puts("Push 4.0\n") +pushStr("4.0") +dumpStack +puts("Add\n") +add +dumpStack +done diff --git a/src/makefile b/src/makefile index a70e19e..9792acf 100755 --- a/src/makefile +++ b/src/makefile @@ -19,6 +19,8 @@ FATWDSK = FATWRITEDSK\#FE1000 FATRDSK = FATREADDSK\#FE1000 FILEIO = FILEIO\#FE1000 SANE = SANE\#FE1000 +FPSTR = FPSTR\#FE1000 +FPU = FPU\#FE1000 SANITY = SANITY\#FE1000 WIZNET = WIZNET\#FE1000 UTHERNET2= UTHERNET2\#FE1000 @@ -64,7 +66,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(FILEIO) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(SANITY) +all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(FILEIO) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) $(FATGET) $(FATPUT) $(FATWDSK) $(FATRDSK) $(SANE) $(FPSTR) $(FPU) $(SANITY) clean: -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) @@ -181,6 +183,14 @@ $(SANE): libsrc/sane.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMO < libsrc/sane.pla > libsrc/sane.a acme --setpc 4094 -o $(SANE) libsrc/sane.a +$(FPSTR): libsrc/fpstr.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMO < libsrc/fpstr.pla > libsrc/fpstr.a + acme --setpc 4094 -o $(FPSTR) libsrc/fpstr.a + +$(FPU): libsrc/fpu.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AMO < libsrc/fpu.pla > libsrc/fpu.a + acme --setpc 4094 -o $(FPU) libsrc/fpu.a + $(SANITY): samplesrc/sanity.pla $(PLVM02) $(PLASM) ./$(PLASM) -AMO < samplesrc/sanity.pla > samplesrc/sanity.a acme --setpc 4094 -o $(SANITY) samplesrc/sanity.a diff --git a/src/samplesrc/sanity.pla b/src/samplesrc/sanity.pla index de52970..26a0568 100644 --- a/src/samplesrc/sanity.pla +++ b/src/samplesrc/sanity.pla @@ -131,14 +131,14 @@ def str2ext(str, ext) //putc(decrec.sgn ?? '-' :: '+'); puts(@decrec.sig); putc('e'); puti(decrec:exp); putln return sane:fpOp2(FFEXT|FOD2B, ext, @decrec) end -def ext2str(ext, str, fracdigits, maxlen, expformat) +def ext2str(ext, str, numdigits, expformat) byte d, i, sigdigits word dp, tens byte decform[t_decformat] byte decrec[t_decrecord] decform:style = 0 - decform:digits = fracdigits + decform:digits = numdigits sane:fpOp3(FFEXT|FOB2D, @decrec, ext, @decform) ^(str+1) = decrec.sgn ?? '-' :: ' ' if decrec.sig.1 == 'I' @@ -155,6 +155,9 @@ def ext2str(ext, str, fracdigits, maxlen, expformat) ^str = 4 return str fin + if decrec.sig.1 == '0' + decrec:exp = -decrec.sig + fin dp = decrec.sig + decrec:exp sigdigits = decrec.sig //putc(decrec.sgn ?? '-' :: '+'); puts(@decrec.sig); putc('e'); puti(decrec:exp); putln @@ -162,12 +165,12 @@ def ext2str(ext, str, fracdigits, maxlen, expformat) // // Strip off trailing fractional zeros // - while sigdigits > (decrec.sig+decrec:exp) and decrec.sig[sigdigits] == '0' + while sigdigits > dp and decrec.sig[sigdigits] == '0' sigdigits-- loop fin //puts("sigdigits: "); puti(sigdigits); putln - if (decrec:exp + (decrec.sig - sigdigits)) < -fracdigits or decrec:exp > 0 or expformat + if (decrec:exp + (decrec.sig - sigdigits)) < -numdigits or decrec:exp > 0 or expformat // // Convert to exponential format // @@ -250,7 +253,7 @@ def divstri(strNum, denom, expformat)#0 sane:zpSave() str2ext(strNum, @xResult) sane:fpOp2(FFINT|FODIV, @xResult, @denom) // Div int denom into ext Result - ext2str(@xResult, @strResult, 6, 19, expformat) + ext2str(@xResult, @strResult, 6, expformat) sane:zpRestore() puts(strNum); putc('/'); puti(denom); putc('='); puts(@strResult); putln end