improved codegen for testing for single bits: x & mask == mask

This commit is contained in:
Irmen de Jong 2024-12-09 03:58:56 +01:00
parent 26d0a174db
commit 535ec13072
3 changed files with 86 additions and 73 deletions

View File

@ -378,30 +378,44 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
if (rightVal!=null && (expr.operator == "==" || expr.operator == "!=")) {
val bitwise = expr.left as? BinaryExpression
if(bitwise!=null && bitwise.operator=="&" && bitwise.inferType(program).isWords) {
val andNum = (bitwise.right as? NumericLiteral)?.number?.toInt()
if (andNum!=null) {
if ((andNum and 0x00ff) == 0) {
// (WORD & $xx00)==y -> (msb(WORD) & $xx)==y
val msb = FunctionCallExpression(IdentifierReference(listOf("msb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val bytevalue = NumericLiteral(BaseDataType.UBYTE, (andNum shr 8).toDouble(), bitwise.right.position)
val rightvalByte = NumericLiteral(BaseDataType.UBYTE, (rightVal.number.toInt() shr 8).toDouble(), rightVal.position)
return listOf(
IAstModification.ReplaceNode(bitwise.left, msb, bitwise),
IAstModification.ReplaceNode(bitwise.right, bytevalue, bitwise),
IAstModification.ReplaceNode(expr.right, rightvalByte, expr)
)
if (bitwise!=null && bitwise.operator=="&") {
if(rightVal.number in powersOfTwoFloat && bitwise.right.constValue(program) == rightVal) {
if(expr.operator=="==") {
// x & const == const -> x & const != 0 (if const has only a single bit set!)
val notZero = BinaryExpression(bitwise, "!=", NumericLiteral(rightDt.base, 0.0, rightVal.position), expr.position)
return listOf(IAstModification.ReplaceNode(expr, notZero, parent))
} else {
// x & const != const -> x & const == 0 (if const has only a single bit set!)
val equalsZero = BinaryExpression(bitwise, "==", NumericLiteral(rightDt.base, 0.0, rightVal.position), expr.position)
return listOf(IAstModification.ReplaceNode(expr, equalsZero, parent))
}
else if((andNum and 0xff00) == 0) {
// (WORD & $00xx)==y -> (lsb(WORD) & $xx)==y
val lsb = FunctionCallExpression(IdentifierReference(listOf("lsb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val bytevalue = NumericLiteral(BaseDataType.UBYTE, andNum.toDouble(), bitwise.right.position)
val rightvalByte = NumericLiteral(BaseDataType.UBYTE, (rightVal.number.toInt() and 255).toDouble(), rightVal.position)
return listOf(
IAstModification.ReplaceNode(bitwise.left, lsb, bitwise),
IAstModification.ReplaceNode(bitwise.right, bytevalue, bitwise),
IAstModification.ReplaceNode(expr.right, rightvalByte, expr)
)
}
if (bitwise.inferType(program).isWords) {
val andNum = (bitwise.right as? NumericLiteral)?.number?.toInt()
if (andNum!=null) {
if ((andNum and 0x00ff) == 0) {
// (WORD & $xx00)==y -> (msb(WORD) & $xx)==y
val msb = FunctionCallExpression(IdentifierReference(listOf("msb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val bytevalue = NumericLiteral(BaseDataType.UBYTE, (andNum shr 8).toDouble(), bitwise.right.position)
val rightvalByte = NumericLiteral(BaseDataType.UBYTE, (rightVal.number.toInt() shr 8).toDouble(), rightVal.position)
return listOf(
IAstModification.ReplaceNode(bitwise.left, msb, bitwise),
IAstModification.ReplaceNode(bitwise.right, bytevalue, bitwise),
IAstModification.ReplaceNode(expr.right, rightvalByte, expr)
)
} else if((andNum and 0xff00) == 0) {
// (WORD & $00xx)==y -> (lsb(WORD) & $xx)==y
val lsb = FunctionCallExpression(IdentifierReference(listOf("lsb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val bytevalue = NumericLiteral(BaseDataType.UBYTE, andNum.toDouble(), bitwise.right.position)
val rightvalByte = NumericLiteral(BaseDataType.UBYTE, (rightVal.number.toInt() and 255).toDouble(), rightVal.position)
return listOf(
IAstModification.ReplaceNode(bitwise.left, lsb, bitwise),
IAstModification.ReplaceNode(bitwise.right, bytevalue, bitwise),
IAstModification.ReplaceNode(expr.right, rightvalByte, expr)
)
}
}
}
}

View File

@ -4,13 +4,11 @@ TODO
Halloween is stuck on a black screen
Optimize bitwise operations on word values where only the msb or lsb is touched: (already done for simple expressions!)
Optimize 6502 bitwise operations on word values where only the msb or lsb is touched: (already done for simple augmented expressions!)
cx16.r0 = (cx16.r0 & $a000) | $0055
cx16.r0 = (cx16.r0 | $a000) ^ $0055
cx16.r0 = (cx16.r0 ^ $a000) & $0055
Optimize (x & y) == y expressions especially in loop conditions
update zsmkit to newest version that includes the on_deck routines when stabilized

View File

@ -1,68 +1,69 @@
%import textio
%zeropage basicsafe
%option no_sysinit
main {
sub start() {
while cx16.r0L & 1 == 0 {
cx16.r0L = %11111110
while cx16.r0L &32 == 32 {
cx16.r0L <<= 1
txt.print_ubbin(cx16.r0L, true)
txt.nl()
}
txt.nl()
while cx16.r0L & 1 == 1 {
cx16.r0L = %11111110
while cx16.r0L &32 != 0 {
cx16.r0L <<= 1
txt.print_ubbin(cx16.r0L, true)
txt.nl()
}
txt.nl()
while cx16.r0L & 64 == 0 {
}
while cx16.r0L & 64 == 64 {
}
do { }
until cx16.r0L & 1 == 0
do { }
until cx16.r0L & 1 == 1
do { }
until cx16.r0L & 64 == 0
do { }
until cx16.r0L & 64 == 64
while cx16.r0L & 1 == 0 {
cx16.r0L++
}
while cx16.r0L & 1 == 1 {
cx16.r0L++
}
while cx16.r0L & 64 == 0 {
cx16.r0L++
}
while cx16.r0L & 64 == 64 {
cx16.r0L++
; this one must not be changed and stop after 3 iterations instead of 5!
cx16.r0L = %11111110
while cx16.r0L &40 == 40 {
cx16.r0L <<= 1
txt.print_ubbin(cx16.r0L, true)
txt.nl()
}
txt.nl()
txt.nl()
cx16.r0L = %11111110
do {
cx16.r0L++
}
until cx16.r0L & 1 == 0
cx16.r0L <<= 1
txt.print_ubbin(cx16.r0L, true)
txt.nl()
} until cx16.r0L &32 != 32
txt.nl()
cx16.r0L = %11111110
do {
cx16.r0L++
}
until cx16.r0L & 1 == 1
cx16.r0L <<= 1
txt.print_ubbin(cx16.r0L, true)
txt.nl()
} until cx16.r0L &32 == 0
txt.nl()
; this one must not be changed and stop after 3 iterations instead of 5!
cx16.r0L = %11111110
do {
cx16.r0L++
}
until cx16.r0L & 64 == 0
cx16.r0L <<= 1
txt.print_ubbin(cx16.r0L, true)
txt.nl()
} until cx16.r0L &40 != 40
txt.nl()
do {
cx16.r0L++
}
until cx16.r0L & 64 == 64
; while cx16.r0L & cx16.r1L == 0 {
; cx16.r0L++
; }
;
; while cx16.r0L & cx16.r1L == cx16.r1L {
; cx16.r0L++
; }
/*
sys.set_irqd()