float-const comparison optimizations

This commit is contained in:
Irmen de Jong 2020-11-22 16:38:01 +01:00
parent 38d06a7e94
commit 8136f3df5c
2 changed files with 124 additions and 17 deletions

View File

@ -32,7 +32,8 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
internal fun translateComparisonExpressionWithJumpIfFalse(expr: BinaryExpression, jumpIfFalseLabel: String) { internal fun translateComparisonExpressionWithJumpIfFalse(expr: BinaryExpression, jumpIfFalseLabel: String) {
// first, if it is of the form: <constvalue> <comparison> X , swap the operands around // first, if it is of the form: <constvalue> <comparison> X , swap the operands around,
// so that the constant value is always the right operand.
var left = expr.left var left = expr.left
var right = expr.right var right = expr.right
var operator = expr.operator var operator = expr.operator
@ -182,7 +183,26 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
private fun translateFloatLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateFloatLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
if(left is IdentifierReference && right is IdentifierReference) { if(leftConstVal!=null && rightConstVal!=null) {
throw AssemblyError("const-compare should have been optimized away")
}
else if(leftConstVal!=null && right is IdentifierReference) {
throw AssemblyError("const-compare should have been optimized to have const as right operand")
}
else if(left is IdentifierReference && rightConstVal!=null) {
val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.getFloatAsmConst(rightConstVal.number.toDouble())
asmgen.out("""
lda #<$rightName
ldy #>$rightName
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1
lda #<$leftName
ldy #>$leftName
jsr floats.vars_less_f
beq $jumpIfFalseLabel""")
}
else if(left is IdentifierReference && right is IdentifierReference) {
val leftName = asmgen.asmVariableName(left) val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.asmVariableName(right) val rightName = asmgen.asmVariableName(right)
asmgen.out(""" asmgen.out("""
@ -204,7 +224,26 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
private fun translateFloatLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateFloatLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
if(left is IdentifierReference && right is IdentifierReference) { if(leftConstVal!=null && rightConstVal!=null) {
throw AssemblyError("const-compare should have been optimized away")
}
else if(leftConstVal!=null && right is IdentifierReference) {
throw AssemblyError("const-compare should have been optimized to have const as right operand")
}
else if(left is IdentifierReference && rightConstVal!=null) {
val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.getFloatAsmConst(rightConstVal.number.toDouble())
asmgen.out("""
lda #<$rightName
ldy #>$rightName
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1
lda #<$leftName
ldy #>$leftName
jsr floats.vars_lesseq_f
beq $jumpIfFalseLabel""")
}
else if(left is IdentifierReference && right is IdentifierReference) {
val leftName = asmgen.asmVariableName(left) val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.asmVariableName(right) val rightName = asmgen.asmVariableName(right)
asmgen.out(""" asmgen.out("""
@ -226,7 +265,26 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
private fun translateFloatGreaterJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateFloatGreaterJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
if(left is IdentifierReference && right is IdentifierReference) { if(leftConstVal!=null && rightConstVal!=null) {
throw AssemblyError("const-compare should have been optimized away")
}
else if(left is IdentifierReference && rightConstVal!=null) {
val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.getFloatAsmConst(rightConstVal.number.toDouble())
asmgen.out("""
lda #<$leftName
ldy #>$leftName
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1
lda #<$rightName
ldy #>$rightName
jsr floats.vars_less_f
beq $jumpIfFalseLabel""")
}
else if(leftConstVal!=null && right is IdentifierReference) {
throw AssemblyError("const-compare should have been optimized to have const as right operand")
}
else if(left is IdentifierReference && right is IdentifierReference) {
val leftName = asmgen.asmVariableName(left) val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.asmVariableName(right) val rightName = asmgen.asmVariableName(right)
asmgen.out(""" asmgen.out("""
@ -248,7 +306,26 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
private fun translateFloatGreaterOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateFloatGreaterOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
if(left is IdentifierReference && right is IdentifierReference) { if(leftConstVal!=null && rightConstVal!=null) {
throw AssemblyError("const-compare should have been optimized away")
}
else if(left is IdentifierReference && rightConstVal!=null) {
val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.getFloatAsmConst(rightConstVal.number.toDouble())
asmgen.out("""
lda #<$leftName
ldy #>$leftName
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1
lda #<$rightName
ldy #>$rightName
jsr floats.vars_lesseq_f
beq $jumpIfFalseLabel""")
}
else if(leftConstVal!=null && right is IdentifierReference) {
throw AssemblyError("const-compare should have been optimized to have const as right operand")
}
else if(left is IdentifierReference && right is IdentifierReference) {
val leftName = asmgen.asmVariableName(left) val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.asmVariableName(right) val rightName = asmgen.asmVariableName(right)
asmgen.out(""" asmgen.out("""
@ -1006,7 +1083,26 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(left is IdentifierReference && right is IdentifierReference) { if(leftConstVal!=null && rightConstVal!=null) {
throw AssemblyError("const-compare should have been optimized away")
}
else if(leftConstVal!=null && right is IdentifierReference) {
throw AssemblyError("const-compare should have been optimized to have const as right operand")
}
else if(left is IdentifierReference && rightConstVal!=null) {
val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.getFloatAsmConst(rightConstVal.number.toDouble())
asmgen.out("""
lda #<$leftName
ldy #>$leftName
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #<$rightName
ldy #>$rightName
jsr floats.vars_equal_f
beq $jumpIfFalseLabel""")
}
else if(left is IdentifierReference && right is IdentifierReference) {
val leftName = asmgen.asmVariableName(left) val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.asmVariableName(right) val rightName = asmgen.asmVariableName(right)
asmgen.out(""" asmgen.out("""
@ -1068,7 +1164,26 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
} }
if(left is IdentifierReference && right is IdentifierReference) { if(leftConstVal!=null && rightConstVal!=null) {
throw AssemblyError("const-compare should have been optimized away")
}
else if(leftConstVal!=null && right is IdentifierReference) {
throw AssemblyError("const-compare should have been optimized to have const as right operand")
}
else if(left is IdentifierReference && rightConstVal!=null) {
val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.getFloatAsmConst(rightConstVal.number.toDouble())
asmgen.out("""
lda #<$leftName
ldy #>$leftName
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #<$rightName
ldy #>$rightName
jsr floats.vars_equal_f
bne $jumpIfFalseLabel""")
}
else if(left is IdentifierReference && right is IdentifierReference) {
val leftName = asmgen.asmVariableName(left) val leftName = asmgen.asmVariableName(left)
val rightName = asmgen.asmVariableName(right) val rightName = asmgen.asmVariableName(right)
asmgen.out(""" asmgen.out("""

View File

@ -7,17 +7,10 @@ main {
sub start() { sub start() {
byte ub1
byte ub2
byte bb1
byte bb2
float uw1 float uw1
float uw2 const float uw2 = 2.2
word ww1
word ww2
uw1 = 1.1 uw1 = 1.1
uw2 = 2.2
if uw1<uw2 if uw1<uw2
txt.chrout('.') txt.chrout('.')
else else
@ -46,8 +39,7 @@ main {
txt.chrout(' ') txt.chrout(' ')
uw1 = -1.1 uw1 = 2.2
uw2 = -1.1
if uw1<uw2 if uw1<uw2
txt.chrout('!') txt.chrout('!')