optimization of > and <= in expressions

This commit is contained in:
Irmen de Jong 2023-08-07 21:20:02 +02:00
parent 0d63cdcb96
commit 017ef8a837
3 changed files with 134 additions and 45 deletions

View File

@ -1150,46 +1150,138 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
private fun byteLessEquals(expr: PtBinaryExpression, signed: Boolean) { private fun byteLessEquals(expr: PtBinaryExpression, signed: Boolean) {
// TODO optimize: no need to use a temporary variable if the right expression is a literal number or a variable name (or register name) // note: this is the inverse of byteGreater
asmgen.assignByteOperandsToAAndVar(expr.right, expr.left, "P8ZP_SCRATCH_B1") when(expr.right) {
if(signed) is PtNumber -> {
asmgen.out(""" val number = (expr.right as PtNumber).number.toInt()
sec asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, signed)
sbc P8ZP_SCRATCH_B1 if(signed)
bvc + asmgen.out("""
eor #$80 sec
+ bpl + sbc #$number
lda #0 bvc +
beq ++ eor #$80
+ lda #1 + bmi +
lda #0
beq ++
+ lda #1
+""") +""")
else else
asmgen.out(""" asmgen.out("""
cmp P8ZP_SCRATCH_B1 cmp #$number
lda #0 lda #0
rol a""") rol a
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
bvc +
eor #$80
+ bmi +
lda #0
beq ++
+ lda #1
+""")
else
asmgen.out("""
cmp $varname
lda #0
rol a
eor #1""")
}
else -> {
// note: left and right operands get reversed here to reduce code size
asmgen.assignByteOperandsToAAndVar(expr.right, expr.left, "P8ZP_SCRATCH_B1")
if(signed)
asmgen.out("""
sec
sbc P8ZP_SCRATCH_B1
bvc +
eor #$80
+ bmi +
lda #1
bne ++
+ lda #0
+""")
else
asmgen.out("""
cmp P8ZP_SCRATCH_B1
lda #0
rol a""")
}
}
} }
private fun byteGreater(expr: PtBinaryExpression, signed: Boolean) { private fun byteGreater(expr: PtBinaryExpression, signed: Boolean) {
// TODO optimize: no need to use a temporary variable if the right expression is a literal number or a variable name (or register name) // note: this is the inverse of byteLessEqual
asmgen.assignByteOperandsToAAndVar(expr.right, expr.left, "P8ZP_SCRATCH_B1") when(expr.right) {
if(signed) is PtNumber -> {
asmgen.out(""" val number = (expr.right as PtNumber).number.toInt()
sec asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, signed)
sbc P8ZP_SCRATCH_B1 if(signed)
bvc + asmgen.out("""
eor #$80 sec
+ bmi + sbc #$number
lda #0 bvc +
beq ++ eor #$80
+ lda #1 + bmi +
lda #1
bne ++
+ lda #0
+""") +""")
else else
asmgen.out(""" asmgen.out("""
cmp P8ZP_SCRATCH_B1 cmp #$number
lda #0 lda #0
rol a rol a""")
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
bvc +
eor #$80
+ bmi +
lda #1
bne ++
+ lda #0
+""")
else
asmgen.out("""
cmp $varname
lda #0
rol a""")
}
else -> {
// note: left and right operands get reversed here to reduce code size
asmgen.assignByteOperandsToAAndVar(expr.right, expr.left, "P8ZP_SCRATCH_B1")
if(signed)
asmgen.out("""
sec
sbc P8ZP_SCRATCH_B1
bvc +
eor #$80
+ bmi +
lda #0
beq ++
+ lda #1
+""")
else
asmgen.out("""
cmp P8ZP_SCRATCH_B1
lda #0
rol a
eor #1""")
}
}
} }
private fun byteGreaterEquals(expr: PtBinaryExpression, signed: Boolean) { private fun byteGreaterEquals(expr: PtBinaryExpression, signed: Boolean) {

View File

@ -1,8 +1,6 @@
TODO TODO
==== ====
- optimize byteLessEquals() and byteGreater() in AssignmentAsmGen.
- in other codegen for comparisons, try to reduce lda #0/lda #1 by rol a using the carry from the cmp if possible.
- investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... - investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction - IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction

View File

@ -5,26 +5,25 @@ main {
sub start() { sub start() {
ubyte a = 2 ubyte a = 2
ubyte var1 = 3 ubyte var1 = 3
ubyte var2 = 1 ubyte var2 = 10
if a==2 and a<=10 {
if a==2 and a>=1 {
a++ a++
} }
if a==var1 and a>=var2 { if a==var1 and a<=var2 {
a++ a++
} }
txt.print_ub(a) ; 4 txt.print_ub(a) ; 4
byte sa = 2 byte sa = 2
byte svar1 = 3 byte svar1 = 3
byte svar2 = 1 byte svar2 = 10
if sa==2 and sa>=1 { if sa==2 and sa<=10 {
sa++ sa++
} }
if sa==svar1 and sa>=svar2 { if sa==svar1 and sa<=svar2 {
sa++ sa++
} }
txt.print_b(sa) ; 4 code 287 txt.print_b(sa) ; 4 code 28f
} }
} }