mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-01-10 06:30:41 +00:00
FPU stack based libary
This commit is contained in:
parent
a8da978c13
commit
f9447602b6
42
src/inc/fpu.plh
Normal file
42
src/inc/fpu.plh
Normal file
@ -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
|
267
src/libsrc/fpu.pla
Normal file
267
src/libsrc/fpu.pla
Normal file
@ -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
|
12
src/makefile
12
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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user