diff --git a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt index 5d55d2544..64d830d7e 100644 --- a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt @@ -431,6 +431,28 @@ class StatementOptimizer(private val program: Program, } } + // word = msb(word) , word=lsb(word) + if(assignment.target.inferType(program).isWords) { + var fcall = assignment.value as? FunctionCallExpression + if (fcall == null) + fcall = (assignment.value as? TypecastExpression)?.expression as? FunctionCallExpression + if (fcall != null && (fcall.target.nameInSource == listOf("lsb") || fcall.target.nameInSource == listOf("msb"))) { + if (fcall.args.single() isSameAs assignment.target) { + return if (fcall.target.nameInSource == listOf("lsb")) { + // optimize word=lsb(word) ==> word &= $00ff + val and255 = BinaryExpression(fcall.args[0], "&", NumericLiteralValue(DataType.UWORD, 255.0, fcall.position), fcall.position) + val newAssign = Assignment(assignment.target, and255, AssignmentOrigin.OPTIMIZER, fcall.position) + listOf(IAstModification.ReplaceNode(assignment, newAssign, parent)) + } else { + // optimize word=msb(word) ==> word >>= 8 + val shift8 = BinaryExpression(fcall.args[0], ">>", NumericLiteralValue(DataType.UBYTE, 8.0, fcall.position), fcall.position) + val newAssign = Assignment(assignment.target, shift8, AssignmentOrigin.OPTIMIZER, fcall.position) + listOf(IAstModification.ReplaceNode(assignment, newAssign, parent)) + } + } + } + } + return noModifications } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index b02846815..0a61f9711 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- optimize w=msb(w) => w >>=8, w=lsb(w) ==> w &= $00ff - fix the value of ww being wrong (with optimizations enabled) in : sub start() { byte ub1 = -50 @@ -20,9 +18,6 @@ fix the value of ww being wrong (with optimizations enabled) in : } -... - - Need help with ^^^^^^^^^^^^^^ - c128 target: various machine specific things (free zp locations, how banking works, getting the floating point routines working, ...) diff --git a/examples/test.p8 b/examples/test.p8 index 050046cf2..6d5d99e82 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,25 +3,25 @@ main { sub start() { - uword @shared xx=$ea31 - ;xx &= $00ff - ;xx = lsb(xx) - ;txt.print_uwhex(xx, true) - ;xx = $ea31 - ;xx &= $ff00 - ; xx = msb(xx) -; %asm {{ -; nop -; nop -; }} - xx >>= 8 - %asm {{ - nop - }} - xx <<= 8 - %asm {{ - nop - }} - txt.print_uwhex(xx, true) + byte bb1 = -50 + byte bb2 = -51 + + word ww = func(bb1, bb2) + txt.print_w(ww) + txt.print(" <- must be -50\n") ; TODO fix this with noopt (prints 0) ! + + ubyte ub1 = 50 + ubyte ub2 = 51 + uword uw = funcu(ub1, ub2) + txt.print_uw(uw) + txt.print(" <- must be 50\n") ; TODO fix this with noopt (prints 0) ! + } + + sub func(word x1, word y1) -> word { + return x1 + } + + sub funcu(uword x1, uword y1) -> uword { + return x1 } }