optimize asm: don't use temp var for some additions

This commit is contained in:
Irmen de Jong 2023-09-01 22:24:17 +02:00
parent 5cd4b874ea
commit 04959dbd8b
4 changed files with 48 additions and 40 deletions

View File

@ -43,6 +43,13 @@ internal fun optimizeAssembly(lines: MutableList<String>, machine: IMachineDefin
numberOfOptimizations++
}
mods = optimizeUnneededTempvarInAdd(linesByFour)
if(mods.isNotEmpty()) {
apply(mods, lines)
linesByFour = getLinesBy(lines, 4)
numberOfOptimizations++
}
var linesByFourteen = getLinesBy(lines, 14)
mods = optimizeSameAssignments(linesByFourteen, machine, symbolTable)
if(mods.isNotEmpty()) {
@ -509,3 +516,26 @@ private fun optimizeUselessPushPopStack(linesByFour: List<List<IndexedValue<Stri
}
return mods
}
private fun optimizeUnneededTempvarInAdd(linesByFour: List<List<IndexedValue<String>>>): List<Modification> {
// sequence: sta P8ZP_SCRATCH_XX / lda something / clc / adc P8ZP_SCRATCH_XX
// this can be performed without the scratch variable: clc / adc something
val mods = mutableListOf<Modification>()
for(lines in linesByFour) {
val first = lines[0].value.trimStart()
val second = lines[1].value.trimStart()
val third = lines[2].value.trimStart()
val fourth = lines[3].value.trimStart()
if(first.startsWith("sta P8ZP_SCRATCH_") && second.startsWith("lda") && third.startsWith("clc") && fourth.startsWith("adc P8ZP_SCRATCH_") ) {
if(fourth.substring(4)==first.substring(4)) {
mods.add(Modification(lines[0].index, false, " clc"))
mods.add(Modification(lines[1].index, false, " adc ${second.substring(3).trimStart()}"))
mods.add(Modification(lines[2].index, true, null))
mods.add(Modification(lines[3].index, true, null))
}
}
}
return mods
}

View File

@ -707,6 +707,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
private fun inplacemodificationByteVariableWithValue(name: String, dt: DataType, operator: String, value: PtExpression) {
// TODO optimize: don't use scratch var if possible
val tmpVar = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG"
asmgen.assignExpressionToVariable(value, tmpVar, value.type)
asmgen.out(" lda $name")
@ -1080,6 +1081,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
"-" -> {
asmgen.translateDirectMemReadExpressionToRegA(memread)
// TODO optimize: don't use scratch var if possible
val tmpByte = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG"
asmgen.out("""
sta $tmpByte
@ -2025,8 +2027,9 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
// the other variable is a BYTE type so optimize for that
when (operator) {
"+" -> {
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt)
if(valueDt==DataType.UBYTE)
if(valueDt==DataType.UBYTE) {
// TODO optimize: don't use scratch var
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt)
asmgen.out("""
lda $name
clc
@ -2035,7 +2038,9 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
bcc +
inc $name+1
+""")
else
} else {
// TODO optimize: don't use scratch var
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt)
asmgen.out("""
ldy #0
lda P8ZP_SCRATCH_B1
@ -2047,8 +2052,10 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
tya
adc $name+1
sta $name+1""")
}
}
"-" -> {
// TODO optimize: don't use scratch var
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt)
if(valueDt==DataType.UBYTE)
asmgen.out("""

View File

@ -1,5 +1,7 @@
TODO
====
- optimize: search for TODO optimize: don't use scratch var
- prefix prog8 subroutines with p8s_ instead of p8_ to not let them clash with variables in the asm?
- allow 'chained' array indexing for expressions: value = ptrarray[0][0]
- allow 'chained' array indexing for assign targets: ptrarray[0][0] = 42 this is just evaluating the lhs as a uword pointer expression

View File

@ -4,42 +4,11 @@
main {
sub start() {
uword w1
uword w2
ubyte index
ubyte[] t_index = [1,2,3,4,5]
ubyte nibble = 0
ubyte b1
ubyte b2
b1 = 255
b2 = 1
txt.print_ub(b1&b2!=0) ; true
txt.spc()
txt.print_ub(b1&b2==0) ; false
txt.nl()
b1 = 255
b2 = 0
txt.print_ub(b1&b2!=0) ; false
txt.spc()
txt.print_ub(b1&b2==0) ; true
txt.nl()
w1 = $ff0f
w2 = $0101
txt.print_ub(w1&w2!=0) ; true
txt.spc()
txt.print_ub(w1&w2==0) ; false
txt.nl()
w1 = $ff0f
w2 = $00f0
txt.print_ub(w1&w2!=0) ; false
txt.spc()
txt.print_ub(w1&w2==0) ; true
txt.nl()
; if w1 & w2
; cx16.r0++
index -= t_index[4]
index -= t_index[nibble]
}
}