diff --git a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt index 18290b502..9234081fb 100644 --- a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt +++ b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt @@ -592,7 +592,7 @@ class ExpressionSimplifier(private val program: Program, return NumericLiteral(targetDt, 0.0, expr.position) } } - DataType.UWORD, DataType.WORD -> { + DataType.UWORD -> { if (amount >= 16) { errors.warn("shift always results in 0", expr.position) return NumericLiteral(targetDt, 0.0, expr.position) @@ -609,6 +609,25 @@ class ExpressionSimplifier(private val program: Program, return FunctionCallExpression(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(shifted, NumericLiteral.optimalInteger(0, expr.position)), expr.position) } } + DataType.WORD -> { + if (amount >= 16) { + errors.warn("shift always results in 0", expr.position) + return NumericLiteral(targetDt, 0.0, expr.position) + } + else if(amount==8) { + // shift left by 8 bits is just a byte operation: mkword(lsb(X), 0) + val lsb = FunctionCallExpression(IdentifierReference(listOf("lsb"), expr.position), mutableListOf(expr.left), expr.position) + val mkword = FunctionCallExpression(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(lsb, NumericLiteral(DataType.UBYTE, 0.0, expr.position)), expr.position) + return TypecastExpression(mkword, DataType.WORD, true, expr.position) + } + else if (amount > 8) { + // same as above but with residual shifts. + val lsb = FunctionCallExpression(IdentifierReference(listOf("lsb"), expr.position), mutableListOf(expr.left), expr.position) + val shifted = BinaryExpression(lsb, "<<", NumericLiteral.optimalInteger(amount - 8, expr.position), expr.position) + val mkword = FunctionCallExpression(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(shifted, NumericLiteral.optimalInteger(0, expr.position)), expr.position) + return TypecastExpression(mkword, DataType.WORD, true, expr.position) + } + } else -> { } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 521ecd8c4..be9a59dea 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- word << 12 is suddenly an uword - ir/vm: allow label in block scope - regression test the various projects - 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway)