mirror of
https://github.com/irmen/prog8.git
synced 2025-01-29 09:31:23 +00:00
added some optimizations for >= 0 and <0 comparisons for integers
This commit is contained in:
parent
33647a29d0
commit
9ca1c66f2b
@ -19,9 +19,6 @@ import kotlin.math.pow
|
||||
x + x + x -> ???? x*3 ??? words/bytes?
|
||||
x - x -> 0
|
||||
|
||||
x < 0 (for word, byte as well?): just test the most significant bit for 1
|
||||
x >= 0 (for word, byte as well?): just test the most significant bit for 0
|
||||
|
||||
(assignment) x += y + 1 -> x += y , x++ (add another x++ for +2)
|
||||
(assignment) x += y - 1 -> x += y , x--
|
||||
(assignment) x -= y + 1 -> x -= y , x--
|
||||
@ -187,7 +184,65 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker()
|
||||
}
|
||||
}
|
||||
|
||||
// simplify when a term is constant and directly determines the outcome
|
||||
if(expr.operator == ">=" && rightVal?.number == 0) {
|
||||
if (leftDt == DataType.UBYTE || leftDt == DataType.UWORD) {
|
||||
// unsigned >= 0 --> true
|
||||
return listOf(IAstModification.ReplaceNode(expr, NumericLiteralValue.fromBoolean(true, expr.position), parent))
|
||||
}
|
||||
when(leftDt) {
|
||||
DataType.BYTE -> {
|
||||
// signed >=0 --> signed ^ $80
|
||||
return listOf(IAstModification.ReplaceNode(
|
||||
expr,
|
||||
BinaryExpression(expr.left, "^", NumericLiteralValue.optimalInteger(0x80, expr.position), expr.position),
|
||||
parent
|
||||
))
|
||||
}
|
||||
DataType.WORD -> {
|
||||
// signedw >=0 --> msb(signedw) ^ $80
|
||||
return listOf(IAstModification.ReplaceNode(
|
||||
expr,
|
||||
BinaryExpression(FunctionCall(IdentifierReference(listOf("msb"), expr.position),
|
||||
mutableListOf(expr.left),
|
||||
expr.position
|
||||
), "^", NumericLiteralValue.optimalInteger(0x80, expr.position), expr.position),
|
||||
parent
|
||||
))
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
if(expr.operator == "<" && rightVal?.number == 0) {
|
||||
if (leftDt == DataType.UBYTE || leftDt == DataType.UWORD) {
|
||||
// unsigned < 0 --> false
|
||||
return listOf(IAstModification.ReplaceNode(expr, NumericLiteralValue.fromBoolean(false, expr.position), parent))
|
||||
}
|
||||
when(leftDt) {
|
||||
DataType.BYTE -> {
|
||||
// signed < 0 --> signed & $80
|
||||
return listOf(IAstModification.ReplaceNode(
|
||||
expr,
|
||||
BinaryExpression(expr.left, "&", NumericLiteralValue.optimalInteger(0x80, expr.position), expr.position),
|
||||
parent
|
||||
))
|
||||
}
|
||||
DataType.WORD -> {
|
||||
// signedw < 0 --> msb(signedw) & $80
|
||||
return listOf(IAstModification.ReplaceNode(
|
||||
expr,
|
||||
BinaryExpression(FunctionCall(IdentifierReference(listOf("msb"), expr.position),
|
||||
mutableListOf(expr.left),
|
||||
expr.position
|
||||
), "&", NumericLiteralValue.optimalInteger(0x80, expr.position), expr.position),
|
||||
parent
|
||||
))
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
// simplify when a term is constant and directly determines the outcome
|
||||
val constTrue = NumericLiteralValue.fromBoolean(true, expr.position)
|
||||
val constFalse = NumericLiteralValue.fromBoolean(false, expr.position)
|
||||
val newExpr: Expression? = when (expr.operator) {
|
||||
|
@ -6,7 +6,88 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
;...
|
||||
|
||||
ubyte ubb
|
||||
byte bb
|
||||
uword uww
|
||||
word ww
|
||||
|
||||
bb = -1
|
||||
ww = -1
|
||||
|
||||
if bb<0
|
||||
c64scr.print("1 ok\n")
|
||||
else
|
||||
c64scr.print("1 fail\n")
|
||||
|
||||
if ww<0
|
||||
c64scr.print("2 ok\n")
|
||||
else
|
||||
c64scr.print("2 fail\n")
|
||||
|
||||
bb = 0
|
||||
ww = 0
|
||||
|
||||
if bb>=0
|
||||
c64scr.print("4 ok\n")
|
||||
else
|
||||
c64scr.print("4 fail\n")
|
||||
|
||||
if ww>=0
|
||||
c64scr.print("5 ok\n")
|
||||
else
|
||||
c64scr.print("5 fail\n")
|
||||
|
||||
bb = 0
|
||||
ww = 0
|
||||
|
||||
if bb>=0
|
||||
c64scr.print("7 ok\n")
|
||||
else
|
||||
c64scr.print("7 fail\n")
|
||||
|
||||
if ww>=0
|
||||
c64scr.print("8 ok\n")
|
||||
else
|
||||
c64scr.print("8 fail\n")
|
||||
|
||||
ubb = 0
|
||||
uww = 0
|
||||
if ubb>=0
|
||||
c64scr.print("10 ok\n")
|
||||
else
|
||||
c64scr.print("10 fail\n")
|
||||
if uww>=0
|
||||
c64scr.print("11 ok\n")
|
||||
else
|
||||
c64scr.print("11 fail\n")
|
||||
if ubb<0
|
||||
c64scr.print("12 fail\n")
|
||||
else
|
||||
c64scr.print("12 ok\n")
|
||||
if uww<0
|
||||
c64scr.print("13 fail\n")
|
||||
else
|
||||
c64scr.print("13 ok\n")
|
||||
ubb = $ff
|
||||
uww = $ffff
|
||||
if ubb>=0
|
||||
c64scr.print("14 ok\n")
|
||||
else
|
||||
c64scr.print("14 fail\n")
|
||||
if uww>=0
|
||||
c64scr.print("15 ok\n")
|
||||
else
|
||||
c64scr.print("15 fail\n")
|
||||
if ubb<0
|
||||
c64scr.print("16 fail\n")
|
||||
else
|
||||
c64scr.print("16 ok\n")
|
||||
if uww<0
|
||||
c64scr.print("17 fail\n")
|
||||
else
|
||||
c64scr.print("17 ok\n")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user