optimized word comparison expressions

This commit is contained in:
Irmen de Jong 2023-05-07 19:55:06 +02:00
parent 393e914a86
commit 68336a76c5
3 changed files with 132 additions and 40 deletions

View File

@ -820,7 +820,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
private fun assignOptimizedComparisonWords(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
val signed = expr.left.type == DataType.BYTE || expr.right.type == DataType.BYTE
val signed = expr.left.type == DataType.WORD || expr.right.type == DataType.WORD
fun assignExpressionOperandsLeftScratchRightAY() {
if(expr.right.isSimple()) {
assignExpressionToVariable(expr.left, "P8ZP_SCRATCH_W1", expr.left.type)
@ -834,6 +834,19 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.restoreRegisterStack(CpuRegister.A, false)
}
}
fun assignExpressionOperandsLeftAYRightScratch() {
if(expr.left.isSimple()) {
assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_W1", expr.left.type)
assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed)
} else {
assignExpressionToRegister(expr.left, RegisterOrPair.AY, signed)
asmgen.saveRegisterStack(CpuRegister.A, false)
asmgen.saveRegisterStack(CpuRegister.Y, false)
assignExpressionToVariable(expr.right, "P8ZP_SCRATCH_W1", expr.left.type)
asmgen.restoreRegisterStack(CpuRegister.Y, false)
asmgen.restoreRegisterStack(CpuRegister.A, false)
}
}
when(expr.operator) {
"==" -> {
assignExpressionOperandsLeftScratchRightAY()
@ -861,42 +874,118 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
"<" -> {
if(signed) {
// TODO("word <")
return false
assignExpressionOperandsLeftAYRightScratch()
asmgen.out("""
cmp P8ZP_SCRATCH_W1
tya
sbc P8ZP_SCRATCH_W1+1
bvc +
eor #${'$'}80
+ bpl ++
+ lda #1
bne ++
+ lda #0
+""")
}
else {
// TODO("uword <")
return false
assignExpressionOperandsLeftAYRightScratch()
asmgen.out("""
cpy P8ZP_SCRATCH_W1+1
bcc +
bne ++
cmp P8ZP_SCRATCH_W1
bcs ++
+ lda #1
bne ++
+ lda #0
+""")
}
}
"<=" -> {
if(signed) {
// TODO("word <=")
return false
assignExpressionOperandsLeftScratchRightAY()
asmgen.out("""
cmp P8ZP_SCRATCH_W1
tya
sbc P8ZP_SCRATCH_W1+1
bvc +
eor #${'$'}80
+ bmi +
lda #1
bne ++
+ lda #0
+""")
}
else {
// TODO("uword =<")
return false
assignExpressionOperandsLeftScratchRightAY()
asmgen.out("""
cpy P8ZP_SCRATCH_W1+1
bcc ++
bne +
cmp P8ZP_SCRATCH_W1
bcc ++
+ lda #1
bne ++
+ lda #0
+""")
}
}
">" -> {
if(signed) {
// TODO("word >")
return false
assignExpressionOperandsLeftScratchRightAY()
asmgen.out("""
cmp P8ZP_SCRATCH_W1
tya
sbc P8ZP_SCRATCH_W1+1
bvc +
eor #${'$'}80
+ bpl ++
+ lda #1
bne ++
+ lda #0
+""")
}
else {
// TODO("uword >")
return false
assignExpressionOperandsLeftScratchRightAY()
asmgen.out("""
cpy P8ZP_SCRATCH_W1+1
bcc +
bne ++
cmp P8ZP_SCRATCH_W1
bcs ++
+ lda #1
bne ++
+ lda #0
+""")
}
}
">=" -> {
if(signed) {
// TODO("word >=")
return false
assignExpressionOperandsLeftAYRightScratch()
asmgen.out("""
cmp P8ZP_SCRATCH_W1
tya
sbc P8ZP_SCRATCH_W1+1
bvc +
eor #${'$'}80
+ bmi +
lda #1
bne ++
+ lda #0
+""")
}
else {
// TODO("uword >=")
return false
assignExpressionOperandsLeftAYRightScratch()
asmgen.out("""
cpy P8ZP_SCRATCH_W1+1
bcc ++
bne +
cmp P8ZP_SCRATCH_W1
bcc ++
+ lda #1
bne ++
+ lda #0
+""")
}
}
else -> return false

View File

@ -3,8 +3,7 @@ TODO
For next minor release
^^^^^^^^^^^^^^^^^^^^^^
- finish assignOptimizedComparisonWords()
- find bcc/bcs branches that could be a rol?
- find bcc/bcs + lda branches that could be a rol?
- find adc #0 that could be a rol?
- try to optimize newexpr a bit more

View File

@ -6,50 +6,54 @@ main {
sub start() {
ubyte[10] envelope_attacks = 99
; signed and unsigned word:
; signed word:
; >
; >=
; <
; <=
; expect nope nope yep yep yep
cx16.r0 = $ea30
cx16.r2 = $ea31
if (cx16.r0 > cx16.r2) or (envelope_attacks[cx16.r1L]==0) {
; expect yep nope nope nope yep nope
cx16.r0s = -1000
cx16.r2s = -999
if (cx16.r0s < cx16.r2s) or (envelope_attacks[cx16.r1L]==0) {
txt.print("\nyep\n")
} else {
txt.print("\nnope\n")
}
cx16.r0 = $ea31
cx16.r2 = $ea31
if (cx16.r0 > cx16.r2) or (envelope_attacks[cx16.r1L]==0) {
cx16.r0s = -999
cx16.r2s = -999
if (cx16.r0s < cx16.r2s) or (envelope_attacks[cx16.r1L]==0) {
txt.print("\nyep\n")
} else {
txt.print("\nnope\n")
}
cx16.r0 = $ea32
cx16.r2 = $ea31
if (cx16.r0 > cx16.r2) or (envelope_attacks[cx16.r1L]==0) {
cx16.r0s = -998
cx16.r2s = -999
if (cx16.r0s < cx16.r2s) or (envelope_attacks[cx16.r1L]==0) {
txt.print("\nyep\n")
} else {
txt.print("\nnope\n")
}
cx16.r0 = $ee30
cx16.r2 = $ea31
if (cx16.r0 > cx16.r2) or (envelope_attacks[cx16.r1L]==0) {
cx16.r0s = 0
cx16.r2s = -999
if (cx16.r0s < cx16.r2s) or (envelope_attacks[cx16.r1L]==0) {
txt.print("\nyep\n")
} else {
txt.print("\nnope\n")
}
cx16.r0 = $ffff
cx16.r2 = $ee31
if (cx16.r0 > cx16.r2) or (envelope_attacks[cx16.r1L]==0) {
cx16.r0s = -999
cx16.r2s = 0
if (cx16.r0s < cx16.r2s) or (envelope_attacks[cx16.r1L]==0) {
txt.print("\nyep\n")
} else {
txt.print("\nnope\n")
}
cx16.r0s = $7fff
cx16.r2s = $7eff
if (cx16.r0s < cx16.r2s) or (envelope_attacks[cx16.r1L]==0) {
txt.print("\nyep\n")
} else {
txt.print("\nnope\n")