From 70ed2b4203f54ac7f21b064a0b097b74979fe4be Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 22 Jul 2023 23:08:22 +0200 Subject: [PATCH] fix compilation of large bitshifts --- .../cpu6502/assignment/AssignmentAsmGen.kt | 5 +-- .../optimizer/ConstantFoldingOptimizer.kt | 41 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 9e21cbcb2..acbf6d728 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -590,7 +590,6 @@ internal class AssignmentAsmGen(private val program: PtProgram, assignExpressionToRegister(expr.left, RegisterOrPair.A, signed) when (shifts) { in 0..7 -> { - require(dt==DataType.UBYTE) if (expr.operator == "<<") { repeat(shifts) { asmgen.out(" asl a") @@ -609,7 +608,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, } else -> { if(signed && expr.operator==">>") { - TODO("signed byte >> overshift should have been compiled away?") + asmgen.out(" ldy #$shifts | jsr math.lsr_byte_A") } else { asmgen.out(" lda #0") } @@ -660,7 +659,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, } else -> { if(signed && expr.operator==">>") { - TODO("signed word >> overshift should have been compiled away?") + asmgen.out(" ldx #$shifts | jsr math.lsr_word_AY") } else { asmgen.out(" lda #0 | ldy #0") } diff --git a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt index 033e5065b..b4a36aa8c 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -235,6 +235,47 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { } } + if(rightconst!=null && (expr.operator=="<<" || expr.operator==">>")) { + val dt = expr.left.inferType(program) + if(dt.isBytes && rightconst.number>=8) { + if(dt.istype(DataType.UBYTE)) { + val zeroUB = NumericLiteral(DataType.UBYTE, 0.0, expr.position) + modifications.add(IAstModification.ReplaceNode(expr, zeroUB, parent)) + } else { + if(leftconst!=null) { + val zeroB = NumericLiteral(DataType.BYTE, 0.0, expr.position) + val minusoneB = NumericLiteral(DataType.BYTE, -1.0, expr.position) + if(leftconst.number<0.0) { + if(expr.operator=="<<") + modifications.add(IAstModification.ReplaceNode(expr, zeroB, parent)) + else + modifications.add(IAstModification.ReplaceNode(expr, minusoneB, parent)) + } else { + modifications.add(IAstModification.ReplaceNode(expr, zeroB, parent)) + } + } + } + } + else if(dt.isWords && rightconst.number>=16) { + if(dt.istype(DataType.UWORD)) { + val zeroUW = NumericLiteral(DataType.UWORD, 0.0, expr.position) + modifications.add(IAstModification.ReplaceNode(expr, zeroUW, parent)) + } else { + if(leftconst!=null) { + val zeroW = NumericLiteral(DataType.WORD, 0.0, expr.position) + val minusoneW = NumericLiteral(DataType.WORD, -1.0, expr.position) + if(leftconst.number<0.0) { + if(expr.operator=="<<") + modifications.add(IAstModification.ReplaceNode(expr, zeroW, parent)) + else + modifications.add(IAstModification.ReplaceNode(expr, minusoneW, parent)) + } else { + modifications.add(IAstModification.ReplaceNode(expr, zeroW, parent)) + } + } + } + } + } return modifications }