slightly optimized repeat loop asmgen

This commit is contained in:
Irmen de Jong 2021-05-30 11:45:08 +02:00
parent c03f6604af
commit e61a2d7083
3 changed files with 37 additions and 28 deletions

View File

@ -880,7 +880,16 @@ internal class AsmGen(private val program: Program,
} }
out("; variables") out("; variables")
out("; register saves") for((name, addr) in sub.asmGenInfo.extraVarsZP) {
out("$name = $addr")
}
for((dt, name) in sub.asmGenInfo.extraVars) {
when(dt) {
DataType.UBYTE -> out("$name .byte 0")
DataType.UWORD -> out("$name .word 0")
else -> throw AssemblyError("weird dt")
}
}
if(sub.asmGenInfo.usedRegsaveA) if(sub.asmGenInfo.usedRegsaveA)
out("_prog8_regsaveA .byte 0") out("_prog8_regsaveA .byte 0")
if(sub.asmGenInfo.usedRegsaveX) if(sub.asmGenInfo.usedRegsaveX)
@ -1025,7 +1034,7 @@ internal class AsmGen(private val program: Program,
return return
// no need to explicitly test for 0 iterations as this is done in the count down logic below // no need to explicitly test for 0 iterations as this is done in the count down logic below
val (counterVar: String, declareCounterVarLocally: Boolean) = createRepeatCounterVar(DataType.UWORD, constIterations, stmt) val counterVar: String = createRepeatCounterVar(DataType.UWORD, constIterations, stmt)
out(""" out("""
sta $counterVar sta $counterVar
sty $counterVar+1 sty $counterVar+1
@ -1040,9 +1049,6 @@ $repeatLabel lda $counterVar
""") """)
translate(stmt.body) translate(stmt.body)
jmp(repeatLabel) jmp(repeatLabel)
if(declareCounterVarLocally)
out("$counterVar .word 0")
out(endLabel) out(endLabel)
} }
@ -1053,49 +1059,48 @@ $repeatLabel lda $counterVar
if(constIterations==null) if(constIterations==null)
out(" beq $endLabel ; skip loop if zero iters") out(" beq $endLabel ; skip loop if zero iters")
val (counterVar: String, declareCounterVarLocally: Boolean) = createRepeatCounterVar(DataType.UBYTE, constIterations, stmt) val counterVar = createRepeatCounterVar(DataType.UBYTE, constIterations, stmt)
out(" sta $counterVar") out(" sta $counterVar")
out(repeatLabel) out(repeatLabel)
translate(stmt.body) translate(stmt.body)
out(""" out(" dec $counterVar | bne $repeatLabel")
dec $counterVar if(constIterations==null)
bne $repeatLabel
beq $endLabel""")
if(declareCounterVarLocally)
out("$counterVar .byte 0")
out(endLabel) out(endLabel)
} }
private fun createRepeatCounterVar(dt: DataType, constIterations: Int?, stmt: RepeatLoop): Pair<String, Boolean> { private fun createRepeatCounterVar(dt: DataType, constIterations: Int?, stmt: RepeatLoop): String {
// TODO share counter variables between subroutines or even between repeat loops as long as they're not nested // TODO share counter variables between subroutines or even between repeat loops as long as they're not nested
// var parent = stmt.parent
// while(parent !is ParentSentinel) {
// if(parent is RepeatLoop)
// break
// parent = parent.parent
// }
// val isNested = parent is RepeatLoop
val counterVar = makeLabel("repeatcounter") val counterVar = makeLabel("repeatcounter")
val asmInfo = stmt.definingSubroutine()!!.asmGenInfo
// println("REPEATCOUNTERVAR $counterVar SIZE $dt CTX ${stmt.definingSubroutine()}")
when(dt) { when(dt) {
DataType.UBYTE -> { DataType.UBYTE -> {
return if(constIterations!=null && constIterations>=16 && zeropage.hasByteAvailable()) { if(constIterations!=null && constIterations>=16 && zeropage.hasByteAvailable()) {
// allocate count var on ZP // allocate count var on ZP
val zpAddr = zeropage.allocate(counterVar, DataType.UBYTE, stmt.position, errors) val zpAddr = zeropage.allocate(counterVar, DataType.UBYTE, stmt.position, errors)
out("$counterVar = $zpAddr ; auto zp byte") asmInfo.extraVarsZP.add(Pair(counterVar, zpAddr))
Pair(counterVar, false)
} else { } else {
Pair(counterVar, true) asmInfo.extraVars.add(Pair(DataType.UBYTE, counterVar))
} }
} }
DataType.UWORD -> { DataType.UWORD -> {
return if(constIterations!=null && constIterations>=16 && zeropage.hasWordAvailable()) { if(constIterations!=null && constIterations>=16 && zeropage.hasWordAvailable()) {
// allocate count var on ZP // allocate count var on ZP
val zpAddr = zeropage.allocate(counterVar, DataType.UWORD, stmt.position, errors) val zpAddr = zeropage.allocate(counterVar, DataType.UWORD, stmt.position, errors)
out("$counterVar = $zpAddr ; auto zp word") asmInfo.extraVarsZP.add(Pair(counterVar, zpAddr))
Pair(counterVar, false)
} else { } else {
Pair(counterVar, true) asmInfo.extraVars.add(Pair(DataType.UWORD, counterVar))
} }
} }
else -> throw AssemblyError("invalidt dt") else -> throw AssemblyError("invalidt dt")
} }
return counterVar
} }
private fun translate(stmt: WhileLoop) { private fun translate(stmt: WhileLoop) {

View File

@ -588,6 +588,9 @@ class AsmGenInfo {
var usedRegsaveY = false var usedRegsaveY = false
var usedFloatEvalResultVar1 = false var usedFloatEvalResultVar1 = false
var usedFloatEvalResultVar2 = false var usedFloatEvalResultVar2 = false
val extraVars = mutableListOf<Pair<DataType, String>>()
val extraVarsZP = mutableListOf<Pair<String, Int>>()
} }
// the subroutine class covers both the normal user-defined subroutines, // the subroutine class covers both the normal user-defined subroutines,

View File

@ -5,6 +5,7 @@ main {
; test program for the optimization of repeat var allocation (asmgen.createRepeatCounterVar) ; test program for the optimization of repeat var allocation (asmgen.createRepeatCounterVar)
; output must be: 60 6164 6224 12328 ; output must be: 60 6164 6224 12328
; original program size: $046b
uword xx uword xx