mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 22:16:16 +00:00
fix large code for some compares
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user