mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
optimization of < and >= in expressions
This commit is contained in:
parent
68a6f99c9f
commit
0d63cdcb96
@ -1084,6 +1084,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun byteLess(expr: PtBinaryExpression, signed: Boolean) {
|
||||
// note: this is the inverse of byteGreaterEqual
|
||||
when(expr.right) {
|
||||
is PtNumber -> {
|
||||
val number = (expr.right as PtNumber).number.toInt()
|
||||
@ -1102,7 +1103,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
else
|
||||
asmgen.out("""
|
||||
cmp #$number
|
||||
asl a
|
||||
rol a
|
||||
and #1
|
||||
eor #1""")
|
||||
}
|
||||
@ -1128,6 +1129,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
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("""
|
||||
@ -1137,22 +1139,18 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
eor #$80
|
||||
+ asl a
|
||||
rol a
|
||||
and #1
|
||||
eor #1""")
|
||||
and #1""")
|
||||
else
|
||||
asmgen.out("""
|
||||
tay
|
||||
lda #0
|
||||
cpy P8ZP_SCRATCH_B1
|
||||
beq +
|
||||
cmp P8ZP_SCRATCH_B1
|
||||
rol a
|
||||
+""")
|
||||
and #1""")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun byteLessEquals(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)
|
||||
// TODO optimize: no need to use a temporary variable if the right expression is a literal number or a variable name (or register name)
|
||||
asmgen.assignByteOperandsToAAndVar(expr.right, expr.left, "P8ZP_SCRATCH_B1")
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
@ -1173,7 +1171,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun byteGreater(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)
|
||||
// TODO optimize: no need to use a temporary variable if the right expression is a literal number or a variable name (or register name)
|
||||
asmgen.assignByteOperandsToAAndVar(expr.right, expr.left, "P8ZP_SCRATCH_B1")
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
@ -1195,28 +1193,67 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun byteGreaterEquals(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)
|
||||
asmgen.assignByteOperandsToAAndVar(expr.right, expr.left, "P8ZP_SCRATCH_B1")
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
clc
|
||||
sbc P8ZP_SCRATCH_B1
|
||||
bvc +
|
||||
eor #$80
|
||||
+ bmi +
|
||||
lda #0
|
||||
beq ++
|
||||
+ lda #1
|
||||
+""")
|
||||
else
|
||||
asmgen.out("""
|
||||
cmp P8ZP_SCRATCH_B1
|
||||
beq +
|
||||
bcc +
|
||||
lda #0
|
||||
beq ++
|
||||
+ lda #1
|
||||
+""")
|
||||
// note: this is the inverse of byteLess
|
||||
when(expr.right) {
|
||||
is PtNumber -> {
|
||||
val number = (expr.right as PtNumber).number.toInt()
|
||||
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.A, signed)
|
||||
if(signed) {
|
||||
asmgen.out("""
|
||||
sec
|
||||
sbc #$number
|
||||
bvs +
|
||||
eor #$80
|
||||
+ asl a
|
||||
rol a
|
||||
and #1""")
|
||||
}
|
||||
else
|
||||
asmgen.out("""
|
||||
cmp #$number
|
||||
rol a
|
||||
and #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""")
|
||||
}
|
||||
else
|
||||
asmgen.out("""
|
||||
cmp $varname
|
||||
rol a
|
||||
and #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("""
|
||||
clc
|
||||
sbc P8ZP_SCRATCH_B1
|
||||
bvs +
|
||||
eor #$80
|
||||
+ asl a
|
||||
rol a
|
||||
and #1
|
||||
eor #1""")
|
||||
else
|
||||
asmgen.out("""
|
||||
cmp P8ZP_SCRATCH_B1
|
||||
rol a
|
||||
and #1
|
||||
eor #1""")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignOptimizedComparisonWords(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||
|
@ -1,7 +1,8 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- try to reduce the number of temp variables in comparison expressions like if a>4 or a<2 .... See assignOptimizedComparisonBytes().
|
||||
- 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 ....
|
||||
|
||||
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
|
||||
|
@ -3,28 +3,28 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
ubyte a = 1
|
||||
ubyte var1 = 2
|
||||
ubyte var2 = 4
|
||||
ubyte a = 2
|
||||
ubyte var1 = 3
|
||||
ubyte var2 = 1
|
||||
|
||||
if a==1 and a<4 {
|
||||
if a==2 and a>=1 {
|
||||
a++
|
||||
}
|
||||
if a==var1 and a<var2 {
|
||||
if a==var1 and a>=var2 {
|
||||
a++
|
||||
}
|
||||
txt.print_ub(a) ; 3
|
||||
txt.print_ub(a) ; 4
|
||||
|
||||
byte sa = 1
|
||||
byte svar1 = 2
|
||||
byte svar2 = 4
|
||||
byte sa = 2
|
||||
byte svar1 = 3
|
||||
byte svar2 = 1
|
||||
|
||||
if sa==1 and sa<4 {
|
||||
if sa==2 and sa>=1 {
|
||||
sa++
|
||||
}
|
||||
if sa==svar1 and sa<svar2 {
|
||||
if sa==svar1 and sa>=svar2 {
|
||||
sa++
|
||||
}
|
||||
txt.print_b(sa) ; 3 code 287
|
||||
txt.print_b(sa) ; 4 code 287
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user