added some optimizations for >= 0 and <0 comparisons for integers

This commit is contained in:
Irmen de Jong 2020-06-04 01:43:37 +02:00
parent 33647a29d0
commit 9ca1c66f2b
2 changed files with 141 additions and 5 deletions

View File

@ -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) {

View File

@ -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")
}
}