From 84d9040b57213fca02ac821b905bb0cac21428e6 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 23 Oct 2024 22:04:25 +0200 Subject: [PATCH] make BIT test also work on signed byte variables. Fixed an address-of optimization error. --- codeCore/src/prog8/code/ast/AstExpressions.kt | 2 +- codeCore/src/prog8/code/optimize/Optimizer.kt | 14 ++++++++++--- docs/source/todo.rst | 1 + examples/test.p8 | 20 ++++++++++++------- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/codeCore/src/prog8/code/ast/AstExpressions.kt b/codeCore/src/prog8/code/ast/AstExpressions.kt index ff088aa6e..6578432e0 100644 --- a/codeCore/src/prog8/code/ast/AstExpressions.kt +++ b/codeCore/src/prog8/code/ast/AstExpressions.kt @@ -85,7 +85,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit fun isSimple(): Boolean { return when(this) { - is PtAddressOf -> this.arrayIndexExpr!=null || this.arrayIndexExpr?.isSimple()==true + is PtAddressOf -> this.arrayIndexExpr==null || this.arrayIndexExpr?.isSimple()==true is PtArray -> true is PtArrayIndexer -> index is PtNumber || index is PtIdentifier is PtBinaryExpression -> false diff --git a/codeCore/src/prog8/code/optimize/Optimizer.kt b/codeCore/src/prog8/code/optimize/Optimizer.kt index 2fcc81673..10374f9d4 100644 --- a/codeCore/src/prog8/code/optimize/Optimizer.kt +++ b/codeCore/src/prog8/code/optimize/Optimizer.kt @@ -95,10 +95,18 @@ private fun optimizeBitTest(program: PtProgram, options: CompilationOptions): In if (condition.right.asConstInteger() == 0) { val and = condition.left as? PtBinaryExpression if (and != null && and.operator == "&" && and.type == DataType.UBYTE) { - val variable = and.left as? PtIdentifier val bitmask = and.right.asConstInteger() - if(variable!=null && variable.type in ByteDatatypes && (bitmask==128 || bitmask==64)) { - return Triple(and, variable, bitmask) + if(bitmask==128 || bitmask==64) { + val variable = and.left as? PtIdentifier + if (variable != null && variable.type in ByteDatatypes) { + return Triple(and, variable, bitmask) + } + val typecast = and.left as? PtTypeCast + if (typecast != null && typecast.type == DataType.UBYTE) { + val castedVariable = typecast.value as? PtIdentifier + if(castedVariable!=null && castedVariable.type in ByteDatatypes) + return Triple(and, castedVariable, bitmask) + } } } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 00243a178..c4ab889b3 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -40,6 +40,7 @@ Future Things and Ideas - ir: the @split arrays are currently also split in _lsb/_msb arrays in the IR, and operations take multiple (byte) instructions that may lead to verbose and slow operation and machine code generation down the line. maybe another representation is needed once actual codegeneration is done from the IR...? - ir: getting it in shape for code generation... +- ir: make optimizeBitTest work for IR too to use the BIT instruction? - ir: make sure that a 6502 codegen based off the IR, still generates BIT instructions when testing bit 7 or 6 of a byte var. - [problematic due to using 64tass:] better support for building library programs, where unused .proc are NOT deleted from the assembly. Perhaps replace all uses of .proc/.pend/.endproc by .block/.bend will fix that with a compiler flag? diff --git a/examples/test.p8 b/examples/test.p8 index 2e3ff110f..c40a607cc 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,15 +5,21 @@ main { sub start() { - word @shared ww = 1234 + byte @shared ww = -99 + ww++ - txt.print_ub(if ww==0 111 else 222) + if ww&1 ==0 + txt.print("x ") + + if ww&64 ==0 + txt.print("a ") + + if ww&128!=0 + txt.print("neg ") + + txt.print_ub(if ww & 64==0 111 else 222) txt.spc() - txt.print_ub(if ww!=0 111 else 222) + txt.print_ub(if ww & 128!=0 111 else 222) txt.spc() - txt.print_ub(if ww==1000 111 else 222) - txt.spc() - txt.print_ub(if ww!=1000 111 else 222) - txt.nl() } }