improve word '<', word (u)word '<=' , uword '>=' codegen

This commit is contained in:
Irmen de Jong 2021-03-16 18:15:47 +01:00
parent d2ab5f230d
commit 6381d2b6ac
2 changed files with 89 additions and 64 deletions

View File

@ -501,6 +501,17 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
private fun translateWordLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateWordLessJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
asmgen.out("""
cmp $lsbCmpOperand
tya
sbc $msbCpyOperand
bvc +
eor #$80
+ bpl $jumpIfFalseLabel""")
}
if(rightConstVal!=null) { if(rightConstVal!=null) {
if(leftConstVal!=null) { if(leftConstVal!=null) {
if(rightConstVal>=leftConstVal) if(rightConstVal>=leftConstVal)
@ -508,29 +519,22 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
return return
} else { } else {
if (left is IdentifierReference) { if (left is IdentifierReference) {
val name = asmgen.asmVariableName(left)
return if(rightConstVal.number.toInt()!=0) { return if(rightConstVal.number.toInt()!=0) {
asmgen.out( asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
""" code("#>${rightConstVal.number}", "#<${rightConstVal.number}")
lda $name
cmp #<${rightConstVal.number}
lda $name+1
sbc #>${rightConstVal.number}
bvc +
eor #$80
+ bpl $jumpIfFalseLabel""")
} }
else else {
val name = asmgen.asmVariableName(left)
asmgen.out(" lda $name+1 | bpl $jumpIfFalseLabel") asmgen.out(" lda $name+1 | bpl $jumpIfFalseLabel")
}
} }
} }
} }
if(right is IdentifierReference) { if(right is IdentifierReference) {
// TODO optimize comparison against identifier asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
// asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) val varname = asmgen.asmVariableName(right)
// val varname = asmgen.asmVariableName(right) return code("$varname+1", varname)
// return code("$varname+1", varname)
} }
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
@ -791,6 +795,17 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
private fun translateUwordLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateUwordLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
asmgen.out("""
cpy $msbCpyOperand
beq +
bcs $jumpIfFalseLabel
+ cmp $lsbCmpOperand
bcs $jumpIfFalseLabel
bne $jumpIfFalseLabel""")
}
if(rightConstVal!=null) { if(rightConstVal!=null) {
if(leftConstVal!=null) { if(leftConstVal!=null) {
if(rightConstVal>leftConstVal) if(rightConstVal>leftConstVal)
@ -798,31 +813,27 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
return return
} else { } else {
if (left is IdentifierReference) { if (left is IdentifierReference) {
val name = asmgen.asmVariableName(left) return if(rightConstVal.number.toInt()!=0) {
return if(rightConstVal.number.toInt()!=0) // TODO is this correct? uword <= not-null
asmgen.out(""" asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
lda #>${rightConstVal.number} code("#>${rightConstVal.number}", "#<${rightConstVal.number}")
cmp $name+1 }
bcc $jumpIfFalseLabel else {
bne + val name = asmgen.asmVariableName(left)
lda #<${rightConstVal.number}
cmp $name
bcc $jumpIfFalseLabel
+""")
else
asmgen.out(""" asmgen.out("""
lda $name lda $name
ora $name+1 ora $name+1
bne $jumpIfFalseLabel""") bne $jumpIfFalseLabel""")
}
} }
} }
} }
if(right is IdentifierReference) { if(right is IdentifierReference) {
// TODO optimize comparison against identifier // TODO is this correct? uword <= variable
// asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
// val varname = asmgen.asmVariableName(right) val varname = asmgen.asmVariableName(right)
// return code("$varname+1", varname) return code("$varname+1", varname)
} }
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
@ -831,6 +842,18 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
private fun translateWordLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateWordLessOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
asmgen.out("""
cmp $msbCpyOperand
tya
sbc $lsbCmpOperand
bvc +
eor #$80
+ bpl $jumpIfFalseLabel"""
)
}
if(rightConstVal!=null) { if(rightConstVal!=null) {
if(leftConstVal!=null) { if(leftConstVal!=null) {
if(rightConstVal>leftConstVal) if(rightConstVal>leftConstVal)
@ -838,17 +861,14 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
return return
} else { } else {
if (left is IdentifierReference) { if (left is IdentifierReference) {
val name = asmgen.asmVariableName(left) return if(rightConstVal.number.toInt()!=0) {
return if(rightConstVal.number.toInt()!=0) // TODO is this correct? word <= not-null
asmgen.out(""" asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
lda #<${rightConstVal.number} code("#>${rightConstVal.number}", "#<${rightConstVal.number}")
cmp $name }
lda #>${rightConstVal.number} else {
sbc $name+1 // TODO is this correct? word <= 0 (can be shorter?)
bvc + val name = asmgen.asmVariableName(left)
eor #$80
+ bmi $jumpIfFalseLabel""")
else
asmgen.out(""" asmgen.out("""
lda #0 lda #0
cmp $name cmp $name
@ -856,15 +876,16 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
bvc + bvc +
eor #$80 eor #$80
+ bmi $jumpIfFalseLabel""") + bmi $jumpIfFalseLabel""")
}
} }
} }
} }
if(right is IdentifierReference) { if(right is IdentifierReference) {
// TODO optimize comparison against identifier // TODO is this correct? word <= variable
// asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
// val varname = asmgen.asmVariableName(right) val varname = asmgen.asmVariableName(right)
// return code("$varname+1", varname) return code("$varname+1", varname)
} }
asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
@ -944,6 +965,17 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
} }
private fun translateUwordGreaterOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) { private fun translateUwordGreaterOrEqualJump(left: Expression, right: Expression, leftConstVal: NumericLiteralValue?, rightConstVal: NumericLiteralValue?, jumpIfFalseLabel: String) {
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
asmgen.out("""
cpy $msbCpyOperand
beq +
bcc $jumpIfFalseLabel
+ cmp $lsbCmpOperand
bcc $jumpIfFalseLabel
+""")
}
if(rightConstVal!=null) { if(rightConstVal!=null) {
if(leftConstVal!=null) { if(leftConstVal!=null) {
if(rightConstVal<leftConstVal) if(rightConstVal<leftConstVal)
@ -951,27 +983,20 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
return return
} else { } else {
if (left is IdentifierReference) { if (left is IdentifierReference) {
val name = asmgen.asmVariableName(left) if(rightConstVal.number.toInt()!=0) {
if(rightConstVal.number.toInt()!=0) // TODO is this correct? uword >= not-0
asmgen.out(""" asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
lda $name+1 code("#>${rightConstVal.number}", "#<${rightConstVal.number}")
cmp #>${rightConstVal.number} }
bcc $jumpIfFalseLabel
bne +
lda $name
cmp #<${rightConstVal.number}
bcc $jumpIfFalseLabel
+""")
return
} }
} }
} }
if(right is IdentifierReference) { if(right is IdentifierReference) {
// TODO optimize comparison against identifier // TODO is this correct? uword >= variable
// asmgen.assignExpressionToRegister(left, RegisterOrPair.AY) asmgen.assignExpressionToRegister(left, RegisterOrPair.AY)
// val varname = asmgen.asmVariableName(right) val varname = asmgen.asmVariableName(right)
// return code("$varname+1", varname) return code("$varname+1", varname)
} }
asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.assignExpressionToVariable(left, "P8ZP_SCRATCH_W2", DataType.UWORD, null)

View File

@ -2,8 +2,8 @@
TODO TODO
==== ====
- optimize comparisons followed by a conditional jump ; try to not have to jsr to the comparison routines. (so if/while/do-until are faster) - fix imageviewer only showing first image
see: ExpressionAsmGen translateXXXXXJump() routines, all called from translateComparisonExpressionWithJumpIfFalse() - fix errors in comparison changes
- add cx16 vload() - add cx16 vload()
- optimize several inner loops in gfx2 - optimize several inner loops in gfx2