optimized integer comparison expressions some more

This commit is contained in:
Irmen de Jong
2021-04-12 01:08:43 +02:00
parent 8d567f6b06
commit ae1b62e147
2 changed files with 221 additions and 152 deletions

View File

@@ -63,31 +63,20 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
// if the left operand is an expression, and the right is 0, we can just evaluate that expression, // if the left operand is an expression, and the right is 0, we can just evaluate that expression,
// and use the result value directly to determine the boolean result. Shortcut only for integers. // and use the result value directly to determine the boolean result. Shortcut only for integers.
if(rightConstVal?.number?.toDouble() == 0.0) { if(rightConstVal?.number?.toDouble() == 0.0) {
when(left) { if(dt in ByteDatatypes) {
is PrefixExpression, asmgen.assignExpressionToRegister(left, RegisterOrPair.A)
is BinaryExpression, if(left is FunctionCall)
is ArrayIndexedExpression, asmgen.out(" cmp #0")
is TypecastExpression, asmgen.out(" bne $jumpIfFalseLabel")
is AddressOf, return
is RangeExpr, }
is FunctionCall -> { else if(dt in WordDatatypes) {
if(dt in ByteDatatypes) { asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out("""
if(left is FunctionCall) sty P8ZP_SCRATCH_B1
asmgen.out(" cmp #0") ora P8ZP_SCRATCH_B1
asmgen.out(" bne $jumpIfFalseLabel") bne $jumpIfFalseLabel""")
return return
}
else if(dt in WordDatatypes) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.out("""
sty P8ZP_SCRATCH_B1
ora P8ZP_SCRATCH_B1
bne $jumpIfFalseLabel""")
return
}
}
else -> {}
} }
} }
@@ -103,31 +92,20 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
// if the left operand is an expression, and the right is 0, we can just evaluate that expression, // if the left operand is an expression, and the right is 0, we can just evaluate that expression,
// and use the result value directly to determine the boolean result. Shortcut only for integers. // and use the result value directly to determine the boolean result. Shortcut only for integers.
if(rightConstVal?.number?.toDouble() == 0.0) { if(rightConstVal?.number?.toDouble() == 0.0) {
when(left) { if(dt in ByteDatatypes) {
is PrefixExpression, asmgen.assignExpressionToRegister(left, RegisterOrPair.A)
is BinaryExpression, if(left is FunctionCall)
is ArrayIndexedExpression, asmgen.out(" cmp #0")
is TypecastExpression, asmgen.out(" beq $jumpIfFalseLabel")
is AddressOf, return
is RangeExpr, }
is FunctionCall -> { else if(dt in WordDatatypes) {
if(dt in ByteDatatypes) { asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.out("""
if(left is FunctionCall) sty P8ZP_SCRATCH_B1
asmgen.out(" cmp #0") ora P8ZP_SCRATCH_B1
asmgen.out(" beq $jumpIfFalseLabel") beq $jumpIfFalseLabel""")
return return
}
else if(dt in WordDatatypes) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.out("""
sty P8ZP_SCRATCH_B1
ora P8ZP_SCRATCH_B1
beq $jumpIfFalseLabel""")
return
}
}
else -> {}
} }
} }
@@ -397,7 +375,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -432,7 +410,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -440,7 +418,36 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
return code("P8ZP_SCRATCH_B1") return code("P8ZP_SCRATCH_B1")
} }
private fun byteJumpForSimpleRightOperands(left: Expression, right: Expression, code: (String)->Unit): Boolean { private fun wordJumpForSimpleLeftOperand(left: Expression, right: Expression, code: (String, String)->Unit): Boolean {
when (left) {
is NumericLiteralValue -> {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY)
val number = left.number.toHex()
code("#>$number", "#<$number")
return true
}
is AddressOf -> {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY)
val name = asmgen.asmSymbolName(left.identifier)
code("#>$name", "#<$name")
return true
}
is IdentifierReference -> {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY)
val varname = asmgen.asmVariableName(left)
code("$varname+1", varname)
return true
}
else -> return false
}
}
private fun byteJumpForSimpleRightOperand(left: Expression, right: Expression, code: (String)->Unit): Boolean {
if(right is NumericLiteralValue) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.A)
code("#${right.number.toHex()}")
return true
}
if(right is IdentifierReference) { if(right is IdentifierReference) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.A) asmgen.assignExpressionToRegister(left, RegisterOrPair.A)
code(asmgen.asmVariableName(right)) code(asmgen.asmVariableName(right))
@@ -460,6 +467,30 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
return false return false
} }
private fun wordJumpForSimpleRightOperands(left: Expression, right: Expression, code: (String, String)->Unit): Boolean {
when (right) {
is NumericLiteralValue -> {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
val number = right.number.toHex()
code("#>$number", "#<$number")
return true
}
is AddressOf -> {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
val name = asmgen.asmSymbolName(right.identifier)
code("#>$name", "#<$name")
return true
}
is IdentifierReference -> {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
val varname = asmgen.asmVariableName(right)
code("$varname+1", varname)
return true
}
else -> return false
}
}
private fun translateUwordLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateUwordLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
fun code(msbCpyOperand: String, lsbCmpOperand: String) { fun code(msbCpyOperand: String, lsbCmpOperand: String) {
@@ -489,11 +520,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(right is IdentifierReference) { if(wordJumpForSimpleRightOperands(left, right, ::code))
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) return
val varname = asmgen.asmVariableName(right)
return code("$varname+1", varname)
}
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
@@ -531,11 +559,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(right is IdentifierReference) { if(wordJumpForSimpleRightOperands(left, right, ::code))
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) return
val varname = asmgen.asmVariableName(right)
return code("$varname+1", varname)
}
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
@@ -574,7 +599,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -611,7 +636,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -654,11 +679,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(right is IdentifierReference) { if(wordJumpForSimpleRightOperands(left, right, ::code))
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) return
val varname = asmgen.asmVariableName(right)
return code("$varname+1", varname)
}
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
@@ -667,11 +689,11 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
private fun translateWordGreaterJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateWordGreaterJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
fun code(leftName: String) { fun code(msbCmpOperand: String, lsbCmpOperand: String) {
asmgen.out(""" asmgen.out("""
cmp $leftName cmp $lsbCmpOperand
tya tya
sbc $leftName+1 sbc $msbCmpOperand
bvc + bvc +
eor #$80 eor #$80
+ bpl $jumpIfFalseLabel""") + bpl $jumpIfFalseLabel""")
@@ -686,7 +708,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
if (left is IdentifierReference) { if (left is IdentifierReference) {
return if(rightConstVal.number.toInt()!=0) { return if(rightConstVal.number.toInt()!=0) {
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY) asmgen.assignExpressionToRegister(right, RegisterOrPair.AY)
code(asmgen.asmVariableName(left)) val varname = asmgen.asmVariableName(left)
code("$varname+1", varname)
} }
else { else {
val name = asmgen.asmVariableName(left) val name = asmgen.asmVariableName(left)
@@ -700,10 +723,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(left is IdentifierReference) { if(wordJumpForSimpleLeftOperand(left, right, ::code))
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY) return
return code(asmgen.asmVariableName(left))
}
asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY) asmgen.assignExpressionToRegister(right, RegisterOrPair.AY)
@@ -743,7 +764,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -780,7 +801,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -825,11 +846,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(right is IdentifierReference) { if(wordJumpForSimpleRightOperands(left, right, ::code))
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) return
val varname = asmgen.asmVariableName(right)
return code("$varname+1", varname)
}
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
@@ -913,7 +931,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -947,7 +965,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -982,11 +1000,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(right is IdentifierReference) { if(wordJumpForSimpleRightOperands(left, right, ::code))
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) return
val varname = asmgen.asmVariableName(right)
return code("$varname+1", varname)
}
asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY) asmgen.assignExpressionToRegister(right, RegisterOrPair.AY)
@@ -1024,11 +1039,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(right is IdentifierReference) { if(wordJumpForSimpleRightOperands(left, right, ::code))
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) return
val varname = asmgen.asmVariableName(right)
return code("$varname+1", varname)
}
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
@@ -1063,7 +1075,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -1100,7 +1112,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(byteJumpForSimpleRightOperands(left, right, ::code)) if(byteJumpForSimpleRightOperand(left, right, ::code))
return return
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE, null)
@@ -1136,24 +1148,47 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(right is IdentifierReference) { when (right) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) is NumericLiteralValue -> {
asmgen.out(""" asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
cmp ${asmgen.asmVariableName(right)} val number = right.number.toHex()
bne $jumpIfFalseLabel asmgen.out("""
cpy ${asmgen.asmVariableName(right)}+1 cmp #<$number
bne $jumpIfFalseLabel bne $jumpIfFalseLabel
""") cpy #>$number
return bne $jumpIfFalseLabel
""")
}
is IdentifierReference -> {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.out("""
cmp ${asmgen.asmVariableName(right)}
bne $jumpIfFalseLabel
cpy ${asmgen.asmVariableName(right)}+1
bne $jumpIfFalseLabel
""")
}
is AddressOf -> {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
val name = asmgen.asmSymbolName(right.identifier)
asmgen.out("""
cmp #<$name
bne $jumpIfFalseLabel
cpy #>$name
bne $jumpIfFalseLabel
""")
}
else -> {
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.out("""
cmp P8ZP_SCRATCH_W2
bne $jumpIfFalseLabel
cpy P8ZP_SCRATCH_W2+1
bne $jumpIfFalseLabel""")
}
} }
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.out("""
cmp P8ZP_SCRATCH_W2
bne $jumpIfFalseLabel
cpy P8ZP_SCRATCH_W2+1
bne $jumpIfFalseLabel""")
} }
private fun translateWordNotEqualsJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateWordNotEqualsJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
@@ -1187,25 +1222,49 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(right is IdentifierReference) { when (right) {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) is NumericLiteralValue -> {
asmgen.out(""" asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
cmp ${asmgen.asmVariableName(right)} val number = right.number.toHex()
bne + asmgen.out("""
cpy ${asmgen.asmVariableName(right)}+1 cmp #<$number
beq $jumpIfFalseLabel bne +
cpy #>$number
beq $jumpIfFalseLabel
+""") +""")
return }
is IdentifierReference -> {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.out("""
cmp ${asmgen.asmVariableName(right)}
bne +
cpy ${asmgen.asmVariableName(right)}+1
beq $jumpIfFalseLabel
+""")
}
is AddressOf -> {
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
val name = asmgen.asmSymbolName(right.identifier)
asmgen.out("""
cmp #<$name
bne +
cpy #>$name
beq $jumpIfFalseLabel
+""")
}
else -> {
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.out("""
cmp P8ZP_SCRATCH_W2
bne +
cpy P8ZP_SCRATCH_W2+1
beq $jumpIfFalseLabel
+"""
)
}
} }
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
asmgen.out("""
cmp P8ZP_SCRATCH_W2
bne +
cpy P8ZP_SCRATCH_W2+1
beq $jumpIfFalseLabel
+""")
} }
private fun translateFloatEqualsJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateFloatEqualsJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {

View File

@@ -4,30 +4,40 @@
main { main {
sub start() { sub start() {
ubyte j1 ubyte yy
ubyte j2 ubyte joy=1
ubyte j3 ubyte zz
str foobar="foobar"
uword joyw=1
repeat { if joyw + 1000 > 1000
%asm {{ txt.print(">1000")
lda #0 if joyw + 1000 > 1011
jsr cx16.joystick_get txt.print(">1011")
sta j1 if joyw + 1000 > & foobar
stx j2 txt.print(">&foobar")
sty j3 if joyw + 1000 > joyw
}} txt.print(">&foobar")
txt.print_ubbin(j1, false) if joy + 10 > 10
txt.spc() txt.print(">10")
txt.print_ubbin(j2, false) if joy + 10 >11
txt.spc() txt.print(">11")
txt.print_ubbin(j3, false)
joy >>= 1
if_cs
yy++
joy >>= 1
if_cs
yy++
; TODO the shifting checks above result in way smaller code than this:
if joy & %00000001
yy++
if joy & %00000010
yy++
txt.spc()
uword qq = cx16.joystick_get2(0)
txt.print_uwbin(qq, false)
txt.nl()
}
} }
} }