Instead of using parameterised rsts for stack access, add a huge swathe of

automatically built helper tools. Star Trek goes up from 40243 to 40779 bytes,
but should be a lot faster.
This commit is contained in:
David Given 2019-02-13 22:45:22 +01:00
parent f70659f460
commit 79a38ecc08
11 changed files with 386 additions and 157 deletions

View file

@ -1,8 +1,68 @@
for _, plat in ipairs(vars.plats) do
acklibrary {
name = "lib_"..plat,
srcs = { "./*.s" },
vars = { plat = plat },
local generated = {}
definerule("generate",
{
body = { type="string" },
offset = { type="object" },
},
function(e)
return normalrule {
name = e.name,
ins = { "./generate.sh", "./"..e.body },
outleaves = { e.name..".s" },
commands = {
"%{ins[1]} "..e.body.." "..e.offset.." > %{outs}"
}
}
end
)
for i = 1, 128 do
generated[#generated+1] = generate {
name = "fload"..i,
body = "fload.h",
offset = i
}
generated[#generated+1] = generate {
name = "floadn"..i,
body = "floadn.h",
offset = i
}
generated[#generated+1] = generate {
name = "fstore"..i,
body = "fstore.h",
offset = i
}
generated[#generated+1] = generate {
name = "fstoren"..i,
body = "fstoren.h",
offset = i
}
generated[#generated+1] = generate {
name = "faddr"..i,
body = "faddr.h",
offset = i
}
generated[#generated+1] = generate {
name = "faddrn"..i,
body = "faddrn.h",
offset = i
}
end
for _, plat in ipairs(vars.plats) do
acklibrary {
name = "lib_"..plat,
srcs = concat("./*.s", generated),
vars = {
plat = plat,
["+ackcflags"] = {"-Imach/i80/libem"}
},
}
end

30
mach/i80/libem/faddr.h Normal file
View file

@ -0,0 +1,30 @@
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text
! Fetches the word at positive stack offset OFFSET into de.
#define PASTE(a, b) a ## b
#define LABEL(prefix, offset) PASTE(prefix, offset)
.define LABEL(.faddr, OFFSET)
LABEL(.faddr, OFFSET):
#if OFFSET == 0
mov l, c
mov h, b
#elif OFFSET == 1
mov l, c
mov h, b
inx h
#elif OFFSET == 2
mov l, c
mov h, b
inx h
inx h
#else
lxi h, OFFSET
dad b
#endif
ret

30
mach/i80/libem/faddrn.h Normal file
View file

@ -0,0 +1,30 @@
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text
! Fetches the word at negative stack offset OFFSET into de.
#define PASTE(a, b) a ## b
#define LABEL(prefix, offset) PASTE(prefix, offset)
.define LABEL(.faddrn, OFFSET)
LABEL(.faddrn, OFFSET):
#if OFFSET == 0
mov l, c
mov h, b
#elif OFFSET == 1
mov l, c
mov h, b
dcx h
#elif OFFSET == 2
mov l, c
mov h, b
dcx h
dcx h
#else
lxi h, -OFFSET
dad b
#endif
ret

32
mach/i80/libem/fload.h Normal file
View file

@ -0,0 +1,32 @@
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text
! Fetches the word at positive stack offset OFFSET into de.
#define PASTE(a, b) a ## b
#define LABEL(prefix, offset) PASTE(prefix, offset)
.define LABEL(.fload, OFFSET)
LABEL(.fload, OFFSET):
#if OFFSET == 0
#error "0 shouldn't happen"
#elif OFFSET == 1
mov l, c
mov h, b
inx h
#elif OFFSET == 2
mov l, c
mov h, b
inx h
inx h
#else
lxi h, OFFSET
dad b
#endif
mov e, m
inx h
mov d, m
ret

38
mach/i80/libem/floadn.h Normal file
View file

@ -0,0 +1,38 @@
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text
! Fetches the word at negative stack offset OFFSET into de.
#define PASTE(a, b) a ## b
#define LABEL(prefix, offset) PASTE(prefix, offset)
.define LABEL(.floadn, OFFSET)
LABEL(.floadn, OFFSET):
#if OFFSET == 0
#error "0 shouldn't happen"
#elif OFFSET == 1
mov l, c
mov h, b
mov d, m
dcx h
mov e, m
ret
#elif OFFSET == 2
mov l, c
mov h, b
dcx h
mov d, m
dcx h
mov e, m
ret
#else
lxi h, -OFFSET
dad b
mov e, m
inx h
mov d, m
ret
#endif

32
mach/i80/libem/fstore.h Normal file
View file

@ -0,0 +1,32 @@
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text
! Stores the word in de to positive stack offset OFFSET.
#define PASTE(a, b) a ## b
#define LABEL(prefix, offset) PASTE(prefix, offset)
.define LABEL(.fstore, OFFSET)
LABEL(.fstore, OFFSET):
#if OFFSET == 0
#error "0 shouldn't happen"
#elif OFFSET == 1
mov l, c
mov h, b
inx h
#elif OFFSET == 2
mov l, c
mov h, b
inx h
inx h
#else
lxi h, OFFSET
dad b
#endif
mov m, e
inx h
mov m, d
ret

39
mach/i80/libem/fstoren.h Normal file
View file

@ -0,0 +1,39 @@
.sect .text
.sect .rom
.sect .data
.sect .bss
.sect .text
! Stores the word in de to negative stack offset OFFSET.
#define PASTE(a, b) a ## b
#define LABEL(prefix, offset) PASTE(prefix, offset)
.define LABEL(.fstoren, OFFSET)
LABEL(.fstoren, OFFSET):
#if OFFSET == 0
#error "0 shouldn't happen"
#elif OFFSET == 1
mov l, c
mov h, b
mov m, d
dcx h
mov m, e
ret
#elif OFFSET == 2
mov l, c
mov h, b
dcx h
mov m, d
dcx h
mov m, e
ret
#else
lxi h, -OFFSET
dad b
mov m, e
inx h
mov m, d
ret
#endif

4
mach/i80/libem/generate.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/sh
echo "#"
echo "#define OFFSET $2"
echo "#include \"$1\""

View file

@ -5,68 +5,36 @@
.sect .bss
.sect .text
! Which resets we install are determined by statistical analysis of Star
! Trek. When changing these, make sure to update the i80 table to match.
! 97 call .floadn2
! 41 call .floadn4
! 34 call .fload4
! 28 call .fstoren2
.define .rst_init
.rst_init:
mvi a, 0xc3 ! jmp <a16>
sta 0x08
sta 0x10
sta 0x18
lxi h, rst1
shld 0x09
lxi h, rst2
shld 0x11
lxi h, rst3
shld 0x19
ret
lxi h, .floadn2
lxi d, 0x0008
call copy
lxi h, .floadn4
lxi d, 0x0010
call copy
lxi h, .fload4
lxi d, 0x0018
call copy
lxi h, .fstoren2
lxi d, 0x0020
jmp copy
! de = [bc+const1] (remember bc is the frame pointer)
rst1:
pop h
! Copies eight bytes from HL to DE.
copy:
mvi c, 8
.1:
mov a, m
stax d
inx h
push h
mov l, a
ral
sbb a
mov h, a
dad b
mov e, m
inx h
mov d, m
ret
! [bc+const1] = de (remember bc is the frame pointer)
rst2:
pop h
mov a, m
inx h
push h
mov l, a
ral
sbb a
mov h, a
dad b
mov m, e
inx h
mov m, d
ret
! hl = bc+const1
rst3:
pop h
mov a, m
inx h
push h
mov l, a
ral
sbb a
mov h, a
dad b
ret
inx d
dcr c
jnz .1
ret

View file

@ -15,6 +15,8 @@ EM_BSIZE = 4
SL=4
STACKHELPERS=128
PROPERTIES
areg /* the a-register */
@ -48,6 +50,7 @@ const1 = { INT num; } 1 num.
const2 = { INT num; } 2 num.
smallconst2 = { INT num; } 2 num.
label = { ADDR off; } 2 off.
plabel = { ADDR off; INT param; } 2 off param.
m = { } 2 cost(0,3) "m".
SETS
@ -69,6 +72,7 @@ INSTRUCTIONS
ana reg1:ro kills a:cc cost(1, 4).
ani const1:ro kills a:cc cost(2, 7).
Call "call" label:ro cost(3,17).
Call "call" plabel:ro cost(3,17).
/* 'call' is a reserved word */
/* cc label:ro cost(3,14). */
/* cm label:ro cost(3,14). */
@ -253,22 +257,44 @@ pat ldc
yields {const2, highw($1)} {const2, loww($1)}
#ifdef USE_I80_RSTS
pat lol sfit($1, 8)
uses hlreg, areg, dereg
pat lol $1==0-2
uses dereg, hlreg
gen
rst {const1, 1}
data1 {const1, $1}
yields de
pat lol $1==0-4
uses dereg, hlreg
gen
rst {const1, 2}
yields de
pat lol $1==4
uses dereg, hlreg
gen
rst {const1, 3}
yields de
#endif
pat lol ($1>0) && ($1<=STACKHELPERS)
uses dereg, hlreg
gen
Call {plabel, ".fload", $1}
yields de
pat lol ($1<0) && ($1>=0-STACKHELPERS)
uses dereg, hlreg
gen
Call {plabel, ".floadn", 0-$1}
yields de
pat lol
uses hlreg={const2, $1}, dereg
gen
dad lb
mov e,{m}
inx hl
mov d,{m}
yields de
uses dereg
gen
dad lb
mov e, {m}
inx hl
mov d, {m}
pat loe
uses hlreg
@ -286,14 +312,17 @@ pat lof
adp $1
loi 2
#ifdef USE_I80_RSTS
pat lal sfit($1, 8)
uses dereg, hlreg, areg
gen
rst {const1, 3}
data1 {const1, $1}
yields hl
#endif
pat lal ($1>0) && ($1<=STACKHELPERS)
uses hlreg
gen
Call {plabel, ".faddr", $1}
yields hl
pat lal ($1<0) && ($1>=0-STACKHELPERS)
uses hlreg
gen
Call {plabel, ".faddrn", 0-$1}
yields hl
pat lal
uses hlreg={const2,$1}
@ -457,22 +486,33 @@ pat stl lol $1==$2
with dereg yields de de leaving stl $1
#ifdef USE_I80_RSTS
pat stl sfit($1, 8)
with dereg
uses hlreg, areg
gen
rst {const1, 2}
data1 {const1, $1}
pat stl $1==0-2
with dereg
uses hlreg
gen
rst {const1, 4}
#endif
pat stl ($1>0) && ($1<=STACKHELPERS)
with dereg
uses hlreg
gen
Call {plabel, ".fstore", $1}
pat stl ($1<0) && ($1>=0-STACKHELPERS)
with dereg
uses hlreg
gen
Call {plabel, ".fstoren", 0-$1}
pat stl
with dereg
uses hlreg={const2, $1}
gen
dad lb
mov {m}, e
inx hl
mov {m}, d
uses hlreg={const2, $1}
gen
dad lb
mov {m}, e
inx hl
mov {m}, d
pat ste loe $1==$2
with hlreg yields hl hl leaving ste $1
@ -906,18 +946,25 @@ pat inc
inx %1
yields %1
#ifdef USE_I80_RSTS
pat inl sfit($1, 8)
uses hlreg, areg
pat inl ($1>0) && ($1<STACKHELPERS)
uses hlreg
gen
rst {const1, 3}
data1 {const1, $1}
Call {plabel, ".faddr", $1}
inr {m}
jnz {label, 1f}
jnz {label,1f}
inx hl
inr {m}
1:
pat inl ($1<0) && ($1<0-STACKHELPERS)
uses hlreg
gen
Call {plabel, ".faddrn", $1}
inr {m}
jnz {label,1f}
inx hl
inr {m}
1:
#endif
pat inl
uses hlreg={const2,$1}
@ -941,12 +988,10 @@ pat dec
with hl_or_de
gen dcx %1 yields %1
#ifdef USE_I80_RSTS
pat del sfit($1, 8)
uses hlreg, areg, dereg
pat del
uses hlreg={const2,$1}
gen
rst {const1, 3}
data1 {const1, $1}
dad lb
mov e, {m}
inx hl
mov d, {m}
@ -954,18 +999,6 @@ gen dcx %1 yields %1
mov {m}, d
dcx hl
mov {m}, e
#endif
pat del
uses hlreg={const2,$1}, dereg
gen dad lb
mov e,{m}
inx hl
mov d,{m}
dcx de
mov {m},d
dcx hl
mov {m},e
pat dee
uses hlreg
@ -973,18 +1006,6 @@ gen lhld {label,$1}
dcx hl
shld {label,$1}
#ifdef USE_I80_RSTS
pat zrl sfit($1, 8)
uses hlreg, areg
gen
rst {const1, 3}
data1 {const1, $1}
xra a
mov {m}, a
inx hl
mov {m}, a
#endif
pat zrl
uses hlreg={const2,$1}, areg
gen
@ -2046,19 +2067,6 @@ gen xra a
jnz {label,$1}
1:
#ifdef USE_I80_RSTS
pat lol zeq sfit($1, 8)
with STACK
uses hlreg, areg
gen
rst {const1, 3}
data1 {const1, $1}
mov a, {m}
inx hl
ora {m}
jz {label, $2}
#endif
pat lol zeq
with STACK
uses hlreg={const2,$1}, areg
@ -2069,19 +2077,6 @@ pat lol zeq
ora {m}
jz {label,$2}
#ifdef USE_I80_RSTS
pat lol zne sfit($1, 8)
with STACK
uses hlreg, areg
gen
rst {const1, 3}
data1 {const1, $1}
mov a, {m}
inx hl
ora {m}
jnz {label, $2}
#endif
pat lol zne
with STACK
uses hlreg={const2,$1}, areg

View file

@ -76,6 +76,7 @@ name led
{FLOATS?} \
(.e:{TAIL}={PLATFORMDIR}/libem.a \
{PLATFORMDIR}/libsys.a \
{PLATFORMDIR}/libem.a \
{PLATFORMDIR}/libend.a)
linker
end