mirror of
https://github.com/irmen/prog8.git
synced 2024-11-18 19:12:44 +00:00
optimized comparison with word variables
This commit is contained in:
parent
d5f35bb3fb
commit
e7178ee496
@ -23,13 +23,13 @@ internal class AnyExprAsmGen(
|
||||
return assignByteBinExpr(expr, assign)
|
||||
if (expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
|
||||
require(expr.operator in ComparisonOperators)
|
||||
TODO("words operands comparison -> byte")
|
||||
throw AssemblyError("words operands comparison -> byte, should have been handled by assignOptimizedComparisonWords()")
|
||||
}
|
||||
if (expr.left.type==DataType.FLOAT && expr.right.type==DataType.FLOAT) {
|
||||
require(expr.operator in ComparisonOperators)
|
||||
return assignFloatBinExpr(expr, assign)
|
||||
}
|
||||
TODO("weird expr operand types")
|
||||
throw AssemblyError("weird expr operand types: ${expr.left.type} and {${expr.right.type}")
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
require(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
|
||||
|
@ -1414,8 +1414,22 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
|
||||
private fun assignOptimizedComparisonWords(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||
val signed = expr.left.type == DataType.WORD || expr.right.type == DataType.WORD
|
||||
|
||||
when(expr.operator) {
|
||||
"==" -> {
|
||||
if(expr.left is PtIdentifier) {
|
||||
val varName = asmgen.asmVariableName(expr.left as PtIdentifier)
|
||||
asmgen.assignExpressionToRegister(expr.right, RegisterOrPair.AY)
|
||||
asmgen.out("""
|
||||
cmp $varName
|
||||
bne +
|
||||
cpy $varName+1
|
||||
bne +
|
||||
lda #1
|
||||
bne ++
|
||||
+ lda #0
|
||||
+""")
|
||||
} else {
|
||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
||||
asmgen.out("""
|
||||
cmp P8ZP_SCRATCH_W1
|
||||
@ -1427,7 +1441,21 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
+ lda #0
|
||||
+""")
|
||||
}
|
||||
}
|
||||
"!=" -> {
|
||||
if(expr.left is PtIdentifier) {
|
||||
val varName = asmgen.asmVariableName(expr.left as PtIdentifier)
|
||||
asmgen.assignExpressionToRegister(expr.right, RegisterOrPair.AY)
|
||||
asmgen.out("""
|
||||
cmp $varName
|
||||
bne +
|
||||
cpy $varName+1
|
||||
bne +
|
||||
lda #0
|
||||
beq ++
|
||||
+ lda #1
|
||||
+""")
|
||||
} else {
|
||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
||||
asmgen.out("""
|
||||
cmp P8ZP_SCRATCH_W1
|
||||
@ -1439,7 +1467,35 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
+ lda #1
|
||||
+""")
|
||||
}
|
||||
}
|
||||
"<" -> {
|
||||
if(expr.right is PtIdentifier) {
|
||||
val varName = asmgen.asmVariableName(expr.right as PtIdentifier)
|
||||
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.AY)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
cmp $varName
|
||||
tya
|
||||
sbc $varName+1
|
||||
bvc +
|
||||
eor #${'$'}80
|
||||
+ bpl ++
|
||||
+ lda #1
|
||||
bne ++
|
||||
+ lda #0
|
||||
+""")
|
||||
else
|
||||
asmgen.out("""
|
||||
cpy $varName+1
|
||||
bcc +
|
||||
bne ++
|
||||
cmp $varName
|
||||
bcs ++
|
||||
+ lda #1
|
||||
bne ++
|
||||
+ lda #0
|
||||
+""")
|
||||
} else {
|
||||
if(signed) {
|
||||
asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1")
|
||||
asmgen.out("""
|
||||
@ -1468,7 +1524,35 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
+""")
|
||||
}
|
||||
}
|
||||
}
|
||||
"<=" -> {
|
||||
if(expr.left is PtIdentifier) {
|
||||
val varName = asmgen.asmVariableName(expr.left as PtIdentifier)
|
||||
asmgen.assignExpressionToRegister(expr.right, RegisterOrPair.AY)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
cmp $varName
|
||||
tya
|
||||
sbc $varName+1
|
||||
bvc +
|
||||
eor #${'$'}80
|
||||
+ bmi +
|
||||
lda #1
|
||||
bne ++
|
||||
+ lda #0
|
||||
+""")
|
||||
else
|
||||
asmgen.out("""
|
||||
cpy $varName+1
|
||||
bcc ++
|
||||
bne +
|
||||
cmp $varName
|
||||
bcc ++
|
||||
+ lda #1
|
||||
bne ++
|
||||
+ lda #0
|
||||
+""")
|
||||
} else {
|
||||
if(signed) {
|
||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
||||
asmgen.out("""
|
||||
@ -1497,7 +1581,35 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
+""")
|
||||
}
|
||||
}
|
||||
}
|
||||
">" -> {
|
||||
if(expr.left is PtIdentifier) {
|
||||
val varName = asmgen.asmVariableName(expr.left as PtIdentifier)
|
||||
asmgen.assignExpressionToRegister(expr.right, RegisterOrPair.AY)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
cmp $varName
|
||||
tya
|
||||
sbc $varName+1
|
||||
bvc +
|
||||
eor #${'$'}80
|
||||
+ bpl ++
|
||||
+ lda #1
|
||||
bne ++
|
||||
+ lda #0
|
||||
+""")
|
||||
else
|
||||
asmgen.out("""
|
||||
cpy $varName+1
|
||||
bcc +
|
||||
bne ++
|
||||
cmp $varName
|
||||
bcs ++
|
||||
+ lda #1
|
||||
bne ++
|
||||
+ lda #0
|
||||
+""")
|
||||
} else {
|
||||
if(signed) {
|
||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
||||
asmgen.out("""
|
||||
@ -1526,7 +1638,35 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
+""")
|
||||
}
|
||||
}
|
||||
}
|
||||
">=" -> {
|
||||
if(expr.right is PtIdentifier) {
|
||||
val varName = asmgen.asmVariableName(expr.right as PtIdentifier)
|
||||
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.AY)
|
||||
if(signed)
|
||||
asmgen.out("""
|
||||
cmp $varName
|
||||
tya
|
||||
sbc $varName+1
|
||||
bvc +
|
||||
eor #${'$'}80
|
||||
+ bmi +
|
||||
lda #1
|
||||
bne ++
|
||||
+ lda #0
|
||||
+""")
|
||||
else
|
||||
asmgen.out("""
|
||||
cpy $varName+1
|
||||
bcc ++
|
||||
bne +
|
||||
cmp $varName
|
||||
bcc ++
|
||||
+ lda #1
|
||||
bne ++
|
||||
+ lda #0
|
||||
+""")
|
||||
} else {
|
||||
if(signed) {
|
||||
asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1")
|
||||
asmgen.out("""
|
||||
@ -1555,6 +1695,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
+""")
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> return false
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- what makes while xx <= x2 and pget(xx as uword, yy as uword) == cx16.r11L so large
|
||||
|
||||
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||
- [on branch: ir-less-branch-opcodes] IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
|
||||
- IR: reduce amount of CMP/CMPI after instructions that set the status bits correctly (LOADs? INC? Bitwise operations, etc), but only after setting the status bits is verified!
|
||||
|
@ -1,30 +1,22 @@
|
||||
%import syslib
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
uword[] wordarray = [0,1,2,3,4,5,6,7,8,9]
|
||||
ubyte n = 5
|
||||
n = lsb(wordarray[n])
|
||||
n = wordarray[n] as ubyte
|
||||
test(wordarray[n] as ubyte,wordarray[n] as ubyte,0)
|
||||
test(lsb(wordarray[n]), lsb(wordarray[n]),0)
|
||||
|
||||
sub pget(uword x, uword y) -> ubyte {
|
||||
return lsb(x+y)
|
||||
}
|
||||
|
||||
asmsub test(ubyte a1 @A, ubyte a2 @X, ubyte a3 @Y) {
|
||||
%asm {{
|
||||
phy
|
||||
phx
|
||||
jsr txt.print_ub
|
||||
jsr txt.spc
|
||||
pla
|
||||
jsr txt.print_ub
|
||||
jsr txt.spc
|
||||
pla
|
||||
jsr txt.print_ub
|
||||
jsr txt.nl
|
||||
rts
|
||||
}}
|
||||
sub start() {
|
||||
|
||||
word xx
|
||||
word x2
|
||||
word yy
|
||||
|
||||
if xx <= x2 and pget(xx as uword, yy as uword) == cx16.r11L
|
||||
xx++
|
||||
|
||||
; if xx <= x2
|
||||
; if pget(xx as uword, yy as uword) == cx16.r11L
|
||||
; xx++
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user