optimize byte comparison assignment to use rol trick instead of branching

This commit is contained in:
Irmen de Jong 2024-03-02 23:29:00 +01:00
parent fe8b6e820c
commit f39ef8f565
3 changed files with 106 additions and 47 deletions

View File

@ -454,6 +454,101 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
}
if(expr.left.type==DataType.UBYTE) {
if(expr.operator=="<") {
assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
when(val right = expr.right) {
is PtIdentifier -> {
asmgen.out("""
cmp ${right.name}
rol a
and #1
eor #1""")
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
is PtMemoryByte -> {
val addr = right.address as? PtNumber
if(addr!=null) {
asmgen.out("""
cmp ${addr.number.toHex()}
rol a
and #1
eor #1""")
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
if(asmgen.isTargetCpu(CpuType.CPU65c02)) {
val ptrvar = right.address as? PtIdentifier
if (ptrvar != null && asmgen.isZpVar(ptrvar)) {
asmgen.out("""
cmp (${ptrvar.name})
rol a
and #1
eor #1""")
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
}
}
is PtNumber -> {
asmgen.out("""
cmp #${right.number.toInt()}
rol a
and #1
eor #1""")
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
else -> { /* not optimizable */ }
}
}
else if(expr.operator==">=") {
assignExpressionToRegister(expr.left, RegisterOrPair.A, false)
when(val right = expr.right) {
is PtIdentifier -> {
asmgen.out("""
cmp ${right.name}
rol a
and #1""")
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
is PtMemoryByte -> {
val addr = right.address as? PtNumber
if(addr!=null) {
asmgen.out("""
cmp ${addr.number.toHex()}
rol a
and #1""")
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
if(asmgen.isTargetCpu(CpuType.CPU65c02)) {
val ptrvar = right.address as? PtIdentifier
if (ptrvar != null && asmgen.isZpVar(ptrvar)) {
asmgen.out("""
cmp (${ptrvar.name})
rol a
and #1""")
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
}
}
is PtNumber -> {
asmgen.out("""
cmp #${right.number.toInt()}
rol a
and #1""")
assignRegisterByte(assign.target, CpuRegister.A, false, false)
return true
}
else -> { /* not optimizable */ }
}
}
}
// b = v > 99 --> b=false , if v>99 b=true
val targetReg=assign.target.register
if(targetReg!=null) {

View File

@ -1,23 +1,8 @@
TODO
====
After merging master:
optimize byte < and byte >= assignment to use the rol trick instead of branching:
bool @shared bb = cx16.r0L >= 128
bool @shared bb2 = cx16.r0L < 99
; source: examples/test.p8:10 bool @shared bb = cx16.r0L >= 128
lda cx16.r0L
cmp #128
rol a
and #1
sta p8v_bb
; source: examples/test.p8:11 bool @shared bb2 = cx16.r0L < 99
lda cx16.r0L
cmp #99
rol a
and #1
eor #1
sta p8v_bb2
imageviewer is larger after the master-rebase!
===== ====== =======

View File

@ -6,37 +6,16 @@
main {
sub start() {
bool @shared ba1, ba2, ba3, ba4, bb1, bb2, bb3, bb4
ba1 = cx16.r0L >= 128
ba2 = cx16.r0L >= cx16.r1L
ba3 = cx16.r0L >= @($2000)
ba4 = cx16.r0L >= @(cx16.r1)
bb1 = cx16.r0L < 128
bb2 = cx16.r0L < cx16.r1L
bb3 = cx16.r0L < @($2000)
bb4 = cx16.r0L < @(cx16.r1)
uword[] flakes = [1,2,3,4]
if cx16.r0==5555
cx16.r0L++
if cx16.r0!=5555
cx16.r0L++
if max(cx16.r0, cx16.r1)==9999
cx16.r0L++
if max(cx16.r0, cx16.r1)!=9999
cx16.r0L++
if derp()==1000
cx16.r0L++
if derp()!=1000
cx16.r0L++
cx16.r0=2
if flakes[cx16.r0L]==239
cx16.r0L++
if flakes[cx16.r0L]!=239
cx16.r0L++
sub derp() -> uword {
cx16.r0++
return cx16.r0
}
;
; ubyte[] barray = [11,22,33]