optimized setting word values into array if index is fixed number

This commit is contained in:
Irmen de Jong 2020-12-08 22:54:20 +01:00
parent cba502e87a
commit 2265ae9600
3 changed files with 48 additions and 63 deletions

View File

@ -1164,22 +1164,20 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
storeRegisterInMemoryAddress(register, target.memory!!)
}
TargetStorageKind.ARRAY -> {
when {
target.constArrayIndexValue!=null -> {
when (register) {
CpuRegister.A -> asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}")
CpuRegister.X -> asmgen.out(" stx ${target.asmVarname}+${target.constArrayIndexValue}")
CpuRegister.Y -> asmgen.out(" sty ${target.asmVarname}+${target.constArrayIndexValue}")
}
if (target.constArrayIndexValue!=null) {
when (register) {
CpuRegister.A -> asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}")
CpuRegister.X -> asmgen.out(" stx ${target.asmVarname}+${target.constArrayIndexValue}")
CpuRegister.Y -> asmgen.out(" sty ${target.asmVarname}+${target.constArrayIndexValue}")
}
else -> {
when (register) {
CpuRegister.A -> {}
CpuRegister.X -> asmgen.out(" txa")
CpuRegister.Y -> asmgen.out(" tya")
}
asmgen.out(" ldy ${asmgen.asmVariableName(target.array!!.indexer.indexVar!!)} | sta ${target.asmVarname},y")
}
else {
when (register) {
CpuRegister.A -> {}
CpuRegister.X -> asmgen.out(" txa")
CpuRegister.Y -> asmgen.out(" tya")
}
asmgen.out(" ldy ${asmgen.asmVariableName(target.array!!.indexer.indexVar!!)} | sta ${target.asmVarname},y")
}
}
TargetStorageKind.REGISTER -> {
@ -1238,20 +1236,30 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
}
TargetStorageKind.ARRAY -> {
// TODO can be a bit more optimized if the array indexer is a number
when(regs) {
RegisterOrPair.AX -> asmgen.out(" pha | txa | pha")
RegisterOrPair.AY -> asmgen.out(" pha | tya | pha")
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
else -> throw AssemblyError("expected reg pair")
if (target.constArrayIndexValue!=null) {
val idx = target.constArrayIndexValue!! * 2
when (regs) {
RegisterOrPair.AX -> asmgen.out(" sta ${target.asmVarname}+$idx | stx ${target.asmVarname}+$idx+1")
RegisterOrPair.AY -> asmgen.out(" sta ${target.asmVarname}+$idx | sty ${target.asmVarname}+$idx+1")
RegisterOrPair.XY -> asmgen.out(" stx ${target.asmVarname}+$idx | sty ${target.asmVarname}+$idx+1")
else -> throw AssemblyError("expected reg pair")
}
}
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UWORD, CpuRegister.Y, true)
asmgen.out("""
pla
sta ${target.asmVarname},y
dey
pla
sta ${target.asmVarname},y""")
else {
when(regs) {
RegisterOrPair.AX -> asmgen.out(" pha | txa | pha")
RegisterOrPair.AY -> asmgen.out(" pha | tya | pha")
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
else -> throw AssemblyError("expected reg pair")
}
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UWORD, CpuRegister.Y, true)
asmgen.out("""
pla
sta ${target.asmVarname},y
dey
pla
sta ${target.asmVarname},y""")
}
}
TargetStorageKind.REGISTER -> {
when(regs) {

View File

@ -4,6 +4,7 @@ TODO
- see if we can group some errors together for instance the (now single) errors about unidentified symbols
- Cx16 target: support full-screen 640x480 and 320x240 graphics? That requires our own custom graphics routines though to draw lines.
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
- use VIC banking to move up the graphics bitmap memory location. Move it to $e000 under the kernal rom?

View File

@ -5,44 +5,20 @@
%import test_stack
%option no_sysinit
errors {
sub tofix() {
; ; TODO fix undefined symbol:
; repeat {
; ubyte char = c64.CHRIN()
; ; ...
; }
; do {
; char = c64.CHRIN() ; TODO fix undefined symbol error, should refer to 'char' above in the subroutine's scope
; } until char==0
str[4] names1 = ["one", "two", "three", "four"]
str[4] names2
names2[0] = "four"
names2[1] = "three"
names2[2] = "two"
names2[3] = "one"
uword xx
for xx in names1 {
txt.print(xx)
txt.chrout(',')
}
txt.chrout('\n')
for xx in names2 {
txt.print(xx)
txt.chrout(',')
}
txt.chrout('\n')
}
}
main {
sub start() {
errors.tofix()
ubyte[] barr = [0,0,0]
uword[] warr = [0,0,0]
ubyte xx = 0
barr[1] = xx+9
warr[1] = &warr
txt.print_ub(barr[1])
txt.chrout('\n')
txt.print_uwhex(warr[1],1 )
txt.chrout('\n')
test_stack.test()
}
}