mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +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++
|
numberOfOptimizations++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mods = optimizeUnneededTempvarInAdd(linesByFour)
|
||||||
|
if(mods.isNotEmpty()) {
|
||||||
|
apply(mods, lines)
|
||||||
|
linesByFour = getLinesBy(lines, 4)
|
||||||
|
numberOfOptimizations++
|
||||||
|
}
|
||||||
|
|
||||||
var linesByFourteen = getLinesBy(lines, 14)
|
var linesByFourteen = getLinesBy(lines, 14)
|
||||||
mods = optimizeSameAssignments(linesByFourteen, machine, symbolTable)
|
mods = optimizeSameAssignments(linesByFourteen, machine, symbolTable)
|
||||||
if(mods.isNotEmpty()) {
|
if(mods.isNotEmpty()) {
|
||||||
@ -509,3 +516,26 @@ private fun optimizeUselessPushPopStack(linesByFour: List<List<IndexedValue<Stri
|
|||||||
}
|
}
|
||||||
return mods
|
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) {
|
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"
|
val tmpVar = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG"
|
||||||
asmgen.assignExpressionToVariable(value, tmpVar, value.type)
|
asmgen.assignExpressionToVariable(value, tmpVar, value.type)
|
||||||
asmgen.out(" lda $name")
|
asmgen.out(" lda $name")
|
||||||
@ -1080,6 +1081,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
asmgen.translateDirectMemReadExpressionToRegA(memread)
|
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"
|
val tmpByte = if(name!="P8ZP_SCRATCH_B1") "P8ZP_SCRATCH_B1" else "P8ZP_SCRATCH_REG"
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
sta $tmpByte
|
sta $tmpByte
|
||||||
@ -2025,8 +2027,9 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
// the other variable is a BYTE type so optimize for that
|
// the other variable is a BYTE type so optimize for that
|
||||||
when (operator) {
|
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("""
|
asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
clc
|
clc
|
||||||
@ -2035,7 +2038,9 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
bcc +
|
bcc +
|
||||||
inc $name+1
|
inc $name+1
|
||||||
+""")
|
+""")
|
||||||
else
|
} else {
|
||||||
|
// TODO optimize: don't use scratch var
|
||||||
|
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
lda P8ZP_SCRATCH_B1
|
lda P8ZP_SCRATCH_B1
|
||||||
@ -2047,8 +2052,10 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
tya
|
tya
|
||||||
adc $name+1
|
adc $name+1
|
||||||
sta $name+1""")
|
sta $name+1""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
|
// TODO optimize: don't use scratch var
|
||||||
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt)
|
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_B1", valueDt)
|
||||||
if(valueDt==DataType.UBYTE)
|
if(valueDt==DataType.UBYTE)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
TODO
|
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?
|
- 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 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
|
- 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 {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
uword w1
|
ubyte index
|
||||||
uword w2
|
ubyte[] t_index = [1,2,3,4,5]
|
||||||
|
ubyte nibble = 0
|
||||||
|
|
||||||
ubyte b1
|
index -= t_index[4]
|
||||||
ubyte b2
|
index -= t_index[nibble]
|
||||||
|
|
||||||
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++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user