better optimize WORD & $xx00 , WORD & $00xx

This commit is contained in:
Irmen de Jong 2024-01-06 21:47:59 +01:00
parent 806654fc44
commit 7dd758a753
2 changed files with 75 additions and 21 deletions

View File

@ -13,7 +13,6 @@ import prog8.ast.statements.Jump
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.code.core.*
import prog8.code.target.VMTarget
import kotlin.math.abs
import kotlin.math.log2
import kotlin.math.pow
@ -76,18 +75,26 @@ class ExpressionSimplifier(private val program: Program,
}
}
if(compTarget.name!=VMTarget.NAME) {
val booleanCondition = ifElse.condition as? BinaryExpression
if(booleanCondition!=null && booleanCondition.operator=="&") {
// special optimization of WORD & $ff00 -> just and the msb of WORD with $ff
val rightNum = booleanCondition.right as? NumericLiteral
if(rightNum!=null && rightNum.type==DataType.UWORD && (rightNum.number.toInt() and 0x00ff)==0) {
val booleanCondition = ifElse.condition as? BinaryExpression
if(booleanCondition!=null && booleanCondition.operator=="&") {
val rightNum = booleanCondition.right as? NumericLiteral
if (rightNum!=null && rightNum.type==DataType.UWORD) {
if ((rightNum.number.toInt() and 0x00ff) == 0) {
// if WORD & $xx00 -> if msb(WORD) & $xx
val msb = BuiltinFunctionCall(IdentifierReference(listOf("msb"), booleanCondition.left.position), mutableListOf(booleanCondition.left), booleanCondition.left.position)
val bytevalue = NumericLiteral(DataType.UBYTE, (rightNum.number.toInt() shr 8).toDouble(), booleanCondition.right.position)
return listOf(
IAstModification.ReplaceNode(booleanCondition.left, msb, booleanCondition),
IAstModification.ReplaceNode(booleanCondition.right, bytevalue, booleanCondition))
}
else if ((rightNum.number.toInt() and 0xff00) == 0) {
// if WORD & $00ff -> if lsb(WORD) & $ff
val lsb = BuiltinFunctionCall(IdentifierReference(listOf("lsb"), booleanCondition.left.position), mutableListOf(booleanCondition.left), booleanCondition.left.position)
val bytevalue = NumericLiteral(DataType.UBYTE, rightNum.number, booleanCondition.right.position)
return listOf(
IAstModification.ReplaceNode(booleanCondition.left, lsb, booleanCondition),
IAstModification.ReplaceNode(booleanCondition.right, bytevalue, booleanCondition))
}
}
}
@ -331,6 +338,37 @@ class ExpressionSimplifier(private val program: Program,
if(newExpr2 != null)
return listOf(IAstModification.ReplaceNode(expr, newExpr2, parent))
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 = BuiltinFunctionCall(IdentifierReference(listOf("msb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val bytevalue = NumericLiteral(DataType.UBYTE, (andNum shr 8).toDouble(), bitwise.right.position)
val rightvalByte = NumericLiteral(DataType.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 = BuiltinFunctionCall(IdentifierReference(listOf("lsb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val bytevalue = NumericLiteral(DataType.UBYTE, andNum.toDouble(), bitwise.right.position)
val rightvalByte = NumericLiteral(DataType.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)
)
}
}
}
}
return noModifications
}

View File

@ -5,22 +5,38 @@
main {
sub start() {
str s = "the quick brown fox jumps over the lazy dog."
uword sp = &s
uword @shared uw = $3f2f
cbm.SETTIM(0,0,0)
repeat 5000 {
cx16.r0L = 'v' in s
}
txt.print_uw(cbm.RDTIM16())
txt.nl()
if uw & $0800
txt.print("ok1\n")
cbm.SETTIM(0,0,0)
repeat 5000 {
cx16.r0L = string.contains(s, 'v')
}
txt.print_uw(cbm.RDTIM16())
txt.nl()
if uw & 8
txt.print("ok2\n")
if uw & $0800 ==0
txt.print("fail1\n")
if uw & $0800 !=0
txt.print("ok3\n")
if uw & 8 ==0
txt.print("fail2\n")
if uw & 8 !=0
txt.print("ok4\n")
if uw & $ff00 == $3f00
txt.print("ok5\n")
if uw & $ff00 != $3f00
txt.print("fail5\n")
if uw & $00ff == $002f
txt.print("ok6\n")
if uw & $00ff != $002f
txt.print("fail6\n")
}
}