optimization of < in expressions

This commit is contained in:
Irmen de Jong 2023-08-07 01:49:00 +02:00
parent 60781bcfc4
commit 68a6f99c9f
2 changed files with 71 additions and 31 deletions

View File

@ -996,8 +996,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
private fun assignOptimizedComparisonBytes(expr: PtBinaryExpression, assign: AsmAssignment): Boolean { private fun assignOptimizedComparisonBytes(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
val signed = expr.left.type == DataType.BYTE || expr.right.type == DataType.BYTE val signed = expr.left.type == DataType.BYTE || expr.right.type == DataType.BYTE
when(expr.operator) { when(expr.operator) {
"==" -> byteEquals(expr, signed) "==" -> byteEquals(expr)
"!=" -> byteNotEquals(expr, signed) "!=" -> byteNotEquals(expr)
"<" -> byteLess(expr, signed) "<" -> byteLess(expr, signed)
"<=" -> byteLessEquals(expr, signed) "<=" -> byteLessEquals(expr, signed)
">" -> byteGreater(expr, signed) ">" -> byteGreater(expr, signed)
@ -1005,15 +1005,15 @@ internal class AssignmentAsmGen(private val program: PtProgram,
else -> return false else -> return false
} }
assignRegisterByte(assign.target, CpuRegister.A, signed) assignRegisterByte(assign.target, CpuRegister.A, false)
return true return true
} }
private fun byteEquals(expr: PtBinaryExpression, signed: Boolean) { private fun byteEquals(expr: PtBinaryExpression) {
when (expr.right) { when (expr.right) {
is PtNumber -> { is PtNumber -> {
val number = (expr.right as PtNumber).number.toInt() val number = (expr.right as PtNumber).number.toInt()
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, signed) asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A)
asmgen.out(""" asmgen.out("""
cmp #$number cmp #$number
beq + beq +
@ -1024,7 +1024,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
is PtIdentifier -> { is PtIdentifier -> {
val varname = (expr.right as PtIdentifier).name val varname = (expr.right as PtIdentifier).name
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, signed) asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A)
asmgen.out(""" asmgen.out("""
cmp $varname cmp $varname
beq + beq +
@ -1046,11 +1046,11 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
} }
private fun byteNotEquals(expr: PtBinaryExpression, signed: Boolean) { private fun byteNotEquals(expr: PtBinaryExpression) {
when(expr.right) { when(expr.right) {
is PtNumber -> { is PtNumber -> {
val number = (expr.right as PtNumber).number.toInt() val number = (expr.right as PtNumber).number.toInt()
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, signed) asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A)
asmgen.out(""" asmgen.out("""
cmp #$number cmp #$number
bne + bne +
@ -1061,7 +1061,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
is PtIdentifier -> { is PtIdentifier -> {
val varname = (expr.right as PtIdentifier).name val varname = (expr.right as PtIdentifier).name
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, signed) asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A)
asmgen.out(""" asmgen.out("""
cmp $varname cmp $varname
bne + bne +
@ -1084,27 +1084,61 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
private fun byteLess(expr: PtBinaryExpression, signed: Boolean) { private fun byteLess(expr: PtBinaryExpression, signed: Boolean) {
// TODO no need to use a temporary variable if the right expression is a literal number or a variable name (or register name)
when(expr.right) { when(expr.right) {
// is PtNumber -> { is PtNumber -> {
// TODO("< number") val number = (expr.right as PtNumber).number.toInt()
// } asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, signed)
// is PtIdentifier -> { if(signed) {
// TODO("< variable") asmgen.out("""
// } sec
sbc #$number
bvs +
eor #$80
+ asl a
rol a
and #1
eor #1""")
}
else
asmgen.out("""
cmp #$number
asl a
and #1
eor #1""")
}
is PtIdentifier -> {
val varname = (expr.right as PtIdentifier).name
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, signed)
if(signed) {
asmgen.out("""
sec
sbc $varname
bvs +
eor #$80
+ asl a
rol a
and #1
eor #1""")
}
else
asmgen.out("""
cmp $varname
rol a
and #1
eor #1""")
}
else -> { else -> {
asmgen.assignByteOperandsToAAndVar(expr.right, expr.left, "P8ZP_SCRATCH_B1") asmgen.assignByteOperandsToAAndVar(expr.right, expr.left, "P8ZP_SCRATCH_B1")
if(signed) if(signed)
asmgen.out(""" asmgen.out("""
clc clc
sbc P8ZP_SCRATCH_B1 sbc P8ZP_SCRATCH_B1
bvc + bvs +
eor #$80 eor #$80
+ bpl + + asl a
lda #0 rol a
beq ++ and #1
+ lda #1 eor #1""")
+""")
else else
asmgen.out(""" asmgen.out("""
tay tay

View File

@ -4,21 +4,27 @@
main { main {
sub start() { sub start() {
ubyte a = 1 ubyte a = 1
ubyte var1 = 1 ubyte var1 = 2
ubyte var2 = 4 ubyte var2 = 4
if a==1 and a<4 {
a++
}
if a==var1 and a<var2 { if a==var1 and a<var2 {
a++ a++
} }
txt.print_ub(a) ; 2 code 1e8 txt.print_ub(a) ; 3
; if a>4 or a<2 { byte sa = 1
; a++ byte svar1 = 2
; } byte svar2 = 4
;
; if a>=2 and a<4 {
; a++
; }
if sa==1 and sa<4 {
sa++
}
if sa==svar1 and sa<svar2 {
sa++
}
txt.print_b(sa) ; 3 code 287
} }
} }