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