mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
improved codegen for testing for single bits: x & mask == mask
This commit is contained in:
parent
26d0a174db
commit
535ec13072
@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user