mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
optimized setting word values into array if index is fixed number
This commit is contained in:
parent
cba502e87a
commit
2265ae9600
@ -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) {
|
||||
|
@ -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?
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user