fix large code for some compares

This commit is contained in:
Irmen de Jong
2024-02-27 02:37:03 +01:00
parent bc2ede76bf
commit bed629998a
4 changed files with 100 additions and 57 deletions

View File

@@ -1019,6 +1019,14 @@ _jump jmp ($asmLabel)
val varname = asmgen.asmVariableName(value) val varname = asmgen.asmVariableName(value)
asmgen.out(" lda $varname+1") asmgen.out(" lda $varname+1")
} }
is PtAddressOf -> {
if(value.isFromArrayElement) {
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
asmgen.out(" cpy #0")
} else {
asmgen.out(" lda #>${asmgen.asmVariableName(value.identifier)}")
}
}
else -> { else -> {
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true) asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
asmgen.out(" cpy #0") asmgen.out(" cpy #0")
@@ -1217,22 +1225,22 @@ _jump jmp ($asmLabel)
// special case for (u)word == X and (u)word != X // special case for (u)word == X and (u)word != X
fun translateLoadFromVarNotEquals(varname: String) { fun translateNotEquals(valueLsb: String, valueMsb: String) {
if(jump!=null) { if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump) val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) { if(indirect) {
asmgen.out(""" asmgen.out("""
cmp $varname cmp $valueLsb
bne + bne +
cpy $varname+1 cpy $valueMsb
beq ++ beq ++
+ jmp ($asmLabel) + jmp ($asmLabel)
+""") +""")
} else { } else {
asmgen.out(""" asmgen.out("""
cmp $varname cmp $valueLsb
bne $asmLabel bne $asmLabel
cpy $varname+1 cpy $valueMsb
bne $asmLabel""") bne $asmLabel""")
} }
asmgen.translate(stmt.elseScope) asmgen.translate(stmt.elseScope)
@@ -1242,9 +1250,9 @@ _jump jmp ($asmLabel)
// if and else blocks // if and else blocks
val elseLabel = asmgen.makeLabel("else") val elseLabel = asmgen.makeLabel("else")
asmgen.out(""" asmgen.out("""
cmp $varname cmp $valueLsb
bne + bne +
cpy $varname+1 cpy $valueMsb
beq $elseLabel beq $elseLabel
+""") +""")
asmgen.translate(stmt.ifScope) asmgen.translate(stmt.ifScope)
@@ -1254,9 +1262,9 @@ _jump jmp ($asmLabel)
} else { } else {
// no else block // no else block
asmgen.out(""" asmgen.out("""
cmp $varname cmp $valueLsb
bne + bne +
cpy $varname+1 cpy $valueMsb
beq $afterIfLabel beq $afterIfLabel
+""") +""")
asmgen.translate(stmt.ifScope) asmgen.translate(stmt.ifScope)
@@ -1265,22 +1273,22 @@ _jump jmp ($asmLabel)
} }
} }
fun translateLoadFromVarEquals(varname: String) { fun translateEquals(valueLsb: String, valueMsb: String) {
return if(jump!=null) { return if(jump!=null) {
val (asmLabel, indirect) = asmgen.getJumpTarget(jump) val (asmLabel, indirect) = asmgen.getJumpTarget(jump)
if(indirect) { if(indirect) {
asmgen.out(""" asmgen.out("""
cmp $varname cmp $valueLsb
bne + bne +
cpy $varname+1 cpy $valueMsb
bne + bne +
jmp ($asmLabel) jmp ($asmLabel)
+""") +""")
} else { } else {
asmgen.out(""" asmgen.out("""
cmp $varname cmp $valueLsb
bne + bne +
cpy $varname+1 cpy $valueMsb
beq $asmLabel beq $asmLabel
+""") +""")
} }
@@ -1291,9 +1299,9 @@ _jump jmp ($asmLabel)
// if and else blocks // if and else blocks
val elseLabel = asmgen.makeLabel("else") val elseLabel = asmgen.makeLabel("else")
asmgen.out(""" asmgen.out("""
cmp $varname cmp $valueLsb
bne $elseLabel bne $elseLabel
cpy $varname+1 cpy $valueMsb
bne $elseLabel""") bne $elseLabel""")
asmgen.translate(stmt.ifScope) asmgen.translate(stmt.ifScope)
asmgen.jmp(afterIfLabel, false) asmgen.jmp(afterIfLabel, false)
@@ -1302,9 +1310,9 @@ _jump jmp ($asmLabel)
} else { } else {
// no else block // no else block
asmgen.out(""" asmgen.out("""
cmp $varname cmp $valueLsb
bne $afterIfLabel bne $afterIfLabel
cpy $varname+1 cpy $valueMsb
bne $afterIfLabel""") bne $afterIfLabel""")
asmgen.translate(stmt.ifScope) asmgen.translate(stmt.ifScope)
} }
@@ -1321,14 +1329,28 @@ _jump jmp ($asmLabel)
val offset = constIndex * program.memsizer.memorySize(left.type) val offset = constIndex * program.memsizer.memorySize(left.type)
if(offset<256) { if(offset<256) {
val varName = asmgen.asmVariableName(left.variable) val varName = asmgen.asmVariableName(left.variable)
return translateLoadFromVarNotEquals("$varName+$offset") return translateNotEquals("$varName+$offset", "$varName+$offset+1")
} }
} }
fallbackTranslate(stmt, false) fallbackTranslate(stmt, false)
} }
is PtIdentifier -> { is PtIdentifier -> {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
return translateLoadFromVarNotEquals(asmgen.asmVariableName(left)) val varname = asmgen.asmVariableName(left)
return translateNotEquals(varname, varname+"+1")
}
is PtAddressOf -> {
if(left.isFromArrayElement)
fallbackTranslate(stmt, false)
else {
if(left.isFromArrayElement)
fallbackTranslate(stmt, false)
else {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
val varname = asmgen.asmVariableName(left.identifier)
return translateNotEquals("#<$varname", "#>$varname")
}
}
} }
else -> fallbackTranslate(stmt, false) else -> fallbackTranslate(stmt, false)
} }
@@ -1341,14 +1363,24 @@ _jump jmp ($asmLabel)
val offset = constIndex * program.memsizer.memorySize(left.type) val offset = constIndex * program.memsizer.memorySize(left.type)
if(offset<256) { if(offset<256) {
val varName = asmgen.asmVariableName(left.variable) val varName = asmgen.asmVariableName(left.variable)
return translateLoadFromVarEquals("$varName+$offset") return translateEquals("$varName+$offset", "$varName+$offset+1")
} }
} }
fallbackTranslate(stmt, false) fallbackTranslate(stmt, false)
} }
is PtIdentifier -> { is PtIdentifier -> {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed) asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
return translateLoadFromVarEquals(asmgen.asmVariableName(left)) val varname = asmgen.asmVariableName(left)
return translateEquals(varname, varname+"+1")
}
is PtAddressOf -> {
if(left.isFromArrayElement)
fallbackTranslate(stmt, false)
else {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
val varname = asmgen.asmVariableName(left.identifier)
return translateEquals("#<$varname", "#>$varname")
}
} }
else -> fallbackTranslate(stmt, false) else -> fallbackTranslate(stmt, false)
} }

View File

@@ -131,4 +131,37 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
return noModifications return noModifications
} }
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
if(options.compTarget.name!=VMTarget.NAME) {
val rightNum = expr.right.constValue(program)
if(rightNum!=null && rightNum.type in IntegerDatatypes) {
//val signed = expr.left.inferType(program).getOr(DataType.UNDEFINED) in SignedDatatypes
when(expr.operator) {
">" -> {
// X>N -> X>=N+1, easier to do in 6502
// TODO check if useful for words as well
val maximum = if(rightNum.type in ByteDatatypes) 255 else 65535
if(rightNum.number<maximum) {
val numPlusOne = rightNum.number.toInt()+1
val newExpr = BinaryExpression(expr.left, ">=", NumericLiteral(rightNum.type, numPlusOne.toDouble(), rightNum.position), expr.position)
return listOf(IAstModification.ReplaceNode(expr, newExpr, parent))
}
}
"<=" -> {
// X<=N -> X<N+1, easier to do in 6502
// TODO check if useful for words as well
val maximum = if(rightNum.type in ByteDatatypes) 255 else 65535
if(rightNum.number<maximum) {
val numPlusOne = rightNum.number.toInt()+1
val newExpr = BinaryExpression(expr.left, "<", NumericLiteral(rightNum.type, numPlusOne.toDouble(), rightNum.position), expr.position)
return listOf(IAstModification.ReplaceNode(expr, newExpr, parent))
}
}
}
}
}
return noModifications
}
} }

View File

@@ -1,12 +1,8 @@
TODO TODO
==== ====
fix large code for while wptr!=&buffer optimize signed word wordGreaterValue, wordLessEqualsValue (can it be without scratch vars?)
optimize signed word wordGreaterZero, wordLessEqualsZero (by comparing msb/lsb separately?)
explore possible optimizations when comparing to a constant number:
X < N --> X<=N-1
X > N --> X>=N+1 etc etc some yield shorter code!!
verify ifelse codegens to be shortest code: (some are using too many scratch vars?) verify ifelse codegens to be shortest code: (some are using too many scratch vars?)
uword >= uword >=
@@ -18,9 +14,11 @@ word >
word <= word <=
word < word <
explore possible optimizations for words when comparing to a constant number (BeforeAsmAstChanger)
floatparse is a bit larger floatparse is a bit larger
testgfx2 is a bit larger testgfx2 is a quite a bit larger
amiga is a bit larger amiga is a bit larger
halloween is 1 byte larger halloween is 1 byte larger
rockrunner is bigger than on 10.1 rockrunner is bigger than on 10.1

View File

@@ -5,34 +5,14 @@
main { main {
sub start() { sub start() {
uword @shared wptr if cx16.r0sL > 10
str buffer=" " cx16.r1L++
if cx16.r0sL >= 10
; TODO: these generate LARGE code cx16.r1L++
while wptr!=&buffer if cx16.r0sL < 10
cx16.r0L++ cx16.r1L++
while wptr==&buffer if cx16.r0sL <= 10
cx16.r0L++ cx16.r1L++
; ... these are fine:
while wptr!=cx16.r0
cx16.r0L++
while wptr==cx16.r0
cx16.r0L++
if ub() > 5
cx16.r0L++
if ub() < 5
cx16.r0L++
if sb() > 5
cx16.r0L++
if sb() < 5
cx16.r0L++
} }
sub ub() -> ubyte { sub ub() -> ubyte {