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 local generated = {}
acklibrary {
name = "lib_"..plat, definerule("generate",
srcs = { "./*.s" }, {
vars = { plat = plat }, 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 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 .bss
.sect .text .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 .define .rst_init
.rst_init: .rst_init:
mvi a, 0xc3 ! jmp <a16> lxi h, .floadn2
sta 0x08 lxi d, 0x0008
sta 0x10 call copy
sta 0x18 lxi h, .floadn4
lxi h, rst1 lxi d, 0x0010
shld 0x09 call copy
lxi h, rst2 lxi h, .fload4
shld 0x11 lxi d, 0x0018
lxi h, rst3 call copy
shld 0x19 lxi h, .fstoren2
ret lxi d, 0x0020
jmp copy
! de = [bc+const1] (remember bc is the frame pointer) ! Copies eight bytes from HL to DE.
rst1: copy:
pop h mvi c, 8
.1:
mov a, m mov a, m
stax d
inx h inx h
push h inx d
dcr c
mov l, a jnz .1
ral
sbb a
mov h, a
dad b
mov e, m
inx h
mov d, m
ret 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

View file

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

View file

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