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

View File

@ -131,4 +131,37 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
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
====
fix large code for while wptr!=&buffer
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!!
optimize signed word wordGreaterValue, wordLessEqualsValue (can it be without scratch vars?)
optimize signed word wordGreaterZero, wordLessEqualsZero (by comparing msb/lsb separately?)
verify ifelse codegens to be shortest code: (some are using too many scratch vars?)
uword >=
@ -18,9 +14,11 @@ word >
word <=
word <
explore possible optimizations for words when comparing to a constant number (BeforeAsmAstChanger)
floatparse is a bit larger
testgfx2 is a bit larger
testgfx2 is a quite a bit larger
amiga is a bit larger
halloween is 1 byte larger
rockrunner is bigger than on 10.1

View File

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