mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
optimize asm: don't use temp var for some additions
This commit is contained in:
parent
5cd4b874ea
commit
04959dbd8b
@ -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()) {
|
||||
@ -508,4 +515,27 @@ private fun optimizeUselessPushPopStack(linesByFour: List<List<IndexedValue<Stri
|
||||
optimize('y', lines)
|
||||
}
|
||||
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
|
||||
}
|
||||
|
@ -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("""
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user