mirror of
https://github.com/irmen/prog8.git
synced 2024-09-30 15:57:06 +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)
|
return assignByteBinExpr(expr, assign)
|
||||||
if (expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
|
if (expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
|
||||||
require(expr.operator in ComparisonOperators)
|
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) {
|
if (expr.left.type==DataType.FLOAT && expr.right.type==DataType.FLOAT) {
|
||||||
require(expr.operator in ComparisonOperators)
|
require(expr.operator in ComparisonOperators)
|
||||||
return assignFloatBinExpr(expr, assign)
|
return assignFloatBinExpr(expr, assign)
|
||||||
}
|
}
|
||||||
TODO("weird expr operand types")
|
throw AssemblyError("weird expr operand types: ${expr.left.type} and {${expr.right.type}")
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
require(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
|
require(expr.left.type in WordDatatypes && expr.right.type in WordDatatypes) {
|
||||||
|
@ -1414,10 +1414,24 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
|
|
||||||
private fun assignOptimizedComparisonWords(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
private fun assignOptimizedComparisonWords(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
val signed = expr.left.type == DataType.WORD || expr.right.type == DataType.WORD
|
val signed = expr.left.type == DataType.WORD || expr.right.type == DataType.WORD
|
||||||
|
|
||||||
when(expr.operator) {
|
when(expr.operator) {
|
||||||
"==" -> {
|
"==" -> {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
if(expr.left is PtIdentifier) {
|
||||||
asmgen.out("""
|
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
|
cmp P8ZP_SCRATCH_W1
|
||||||
bne +
|
bne +
|
||||||
cpy P8ZP_SCRATCH_W1+1
|
cpy P8ZP_SCRATCH_W1+1
|
||||||
@ -1426,10 +1440,24 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"!=" -> {
|
"!=" -> {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
if(expr.left is PtIdentifier) {
|
||||||
asmgen.out("""
|
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
|
cmp P8ZP_SCRATCH_W1
|
||||||
bne +
|
bne +
|
||||||
cpy P8ZP_SCRATCH_W1+1
|
cpy P8ZP_SCRATCH_W1+1
|
||||||
@ -1438,11 +1466,39 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
beq ++
|
beq ++
|
||||||
+ lda #1
|
+ lda #1
|
||||||
+""")
|
+""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"<" -> {
|
"<" -> {
|
||||||
if(signed) {
|
if(expr.right is PtIdentifier) {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1")
|
val varName = asmgen.asmVariableName(expr.right as PtIdentifier)
|
||||||
asmgen.out("""
|
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("""
|
||||||
cmp P8ZP_SCRATCH_W1
|
cmp P8ZP_SCRATCH_W1
|
||||||
tya
|
tya
|
||||||
sbc P8ZP_SCRATCH_W1+1
|
sbc P8ZP_SCRATCH_W1+1
|
||||||
@ -1453,10 +1509,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1")
|
asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1")
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
cpy P8ZP_SCRATCH_W1+1
|
cpy P8ZP_SCRATCH_W1+1
|
||||||
bcc +
|
bcc +
|
||||||
bne ++
|
bne ++
|
||||||
@ -1466,12 +1522,40 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"<=" -> {
|
"<=" -> {
|
||||||
if(signed) {
|
if(expr.left is PtIdentifier) {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
val varName = asmgen.asmVariableName(expr.left as PtIdentifier)
|
||||||
asmgen.out("""
|
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("""
|
||||||
cmp P8ZP_SCRATCH_W1
|
cmp P8ZP_SCRATCH_W1
|
||||||
tya
|
tya
|
||||||
sbc P8ZP_SCRATCH_W1+1
|
sbc P8ZP_SCRATCH_W1+1
|
||||||
@ -1482,10 +1566,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
cpy P8ZP_SCRATCH_W1+1
|
cpy P8ZP_SCRATCH_W1+1
|
||||||
bcc ++
|
bcc ++
|
||||||
bne +
|
bne +
|
||||||
@ -1495,12 +1579,40 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">" -> {
|
">" -> {
|
||||||
if(signed) {
|
if(expr.left is PtIdentifier) {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
val varName = asmgen.asmVariableName(expr.left as PtIdentifier)
|
||||||
asmgen.out("""
|
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("""
|
||||||
cmp P8ZP_SCRATCH_W1
|
cmp P8ZP_SCRATCH_W1
|
||||||
tya
|
tya
|
||||||
sbc P8ZP_SCRATCH_W1+1
|
sbc P8ZP_SCRATCH_W1+1
|
||||||
@ -1511,10 +1623,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "P8ZP_SCRATCH_W1")
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
cpy P8ZP_SCRATCH_W1+1
|
cpy P8ZP_SCRATCH_W1+1
|
||||||
bcc +
|
bcc +
|
||||||
bne ++
|
bne ++
|
||||||
@ -1524,12 +1636,40 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">=" -> {
|
">=" -> {
|
||||||
if(signed) {
|
if(expr.right is PtIdentifier) {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1")
|
val varName = asmgen.asmVariableName(expr.right as PtIdentifier)
|
||||||
asmgen.out("""
|
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("""
|
||||||
cmp P8ZP_SCRATCH_W1
|
cmp P8ZP_SCRATCH_W1
|
||||||
tya
|
tya
|
||||||
sbc P8ZP_SCRATCH_W1+1
|
sbc P8ZP_SCRATCH_W1+1
|
||||||
@ -1540,10 +1680,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1")
|
asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1")
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
cpy P8ZP_SCRATCH_W1+1
|
cpy P8ZP_SCRATCH_W1+1
|
||||||
bcc ++
|
bcc ++
|
||||||
bne +
|
bne +
|
||||||
@ -1553,6 +1693,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
bne ++
|
bne ++
|
||||||
+ lda #0
|
+ lda #0
|
||||||
+""")
|
+""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> return false
|
else -> return false
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
TODO
|
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: 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
|
- [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!
|
- 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
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
|
||||||
uword[] wordarray = [0,1,2,3,4,5,6,7,8,9]
|
sub pget(uword x, uword y) -> ubyte {
|
||||||
ubyte n = 5
|
return lsb(x+y)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub test(ubyte a1 @A, ubyte a2 @X, ubyte a3 @Y) {
|
sub start() {
|
||||||
%asm {{
|
|
||||||
phy
|
word xx
|
||||||
phx
|
word x2
|
||||||
jsr txt.print_ub
|
word yy
|
||||||
jsr txt.spc
|
|
||||||
pla
|
if xx <= x2 and pget(xx as uword, yy as uword) == cx16.r11L
|
||||||
jsr txt.print_ub
|
xx++
|
||||||
jsr txt.spc
|
|
||||||
pla
|
; if xx <= x2
|
||||||
jsr txt.print_ub
|
; if pget(xx as uword, yy as uword) == cx16.r11L
|
||||||
jsr txt.nl
|
; xx++
|
||||||
rts
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user