diff --git a/compiler/res/prog8lib/math.asm b/compiler/res/prog8lib/math.asm index 4e794abdb..c24c18336 100644 --- a/compiler/res/prog8lib/math.asm +++ b/compiler/res/prog8lib/math.asm @@ -1469,3 +1469,22 @@ shift_right_w_3 .proc jmp shift_right_w_7._shift3 .pend + + +; support for bit shifting that is too large to be unrolled: + +lsr_byte_A .proc + ; -- lsr signed byte in A times the value in Y (assume >0) + cmp #0 + bmi _negative +- lsr a + dey + bne - + rts +_negative lsr a + ora #$80 + dey + bne _negative + rts + .pend + diff --git a/compiler/res/prog8lib/prog8_lib.asm b/compiler/res/prog8lib/prog8_lib.asm index 90cc30bf6..934e55a1a 100644 --- a/compiler/res/prog8lib/prog8_lib.asm +++ b/compiler/res/prog8lib/prog8_lib.asm @@ -2145,34 +2145,3 @@ func_strcmp .proc sta P8ESTACK_LO+1,x rts .pend - - - -; support for bit shifting that is too large to be unrolled: - -lsr_byte_A .proc - ; -- lsr signed byte in A times the value in Y (assume >0) - cmp #0 - bmi _negative -- lsr a - dey - bne - - rts -_negative lsr a - ora #$80 - dey - bne _negative - rts - .pend - -lsr_word_AY .proc - .error "make" - .pend - -lsr_uword_AY .proc - .error "make" - .pend - -asl_word_AY .proc - .error "make" - .pend diff --git a/compiler/src/prog8/ast/statements/AstStatements.kt b/compiler/src/prog8/ast/statements/AstStatements.kt index 85d6b4988..f8aceafb5 100644 --- a/compiler/src/prog8/ast/statements/AstStatements.kt +++ b/compiler/src/prog8/ast/statements/AstStatements.kt @@ -415,6 +415,10 @@ open class Assignment(var target: AssignTarget, var value: Expression, override return if(subCast!=null) subCast.expression isSameAs target else castExpr.expression isSameAs target } + if(target.identifier!=null) { + return value.referencesIdentifier(*(target.identifier!!.nameInSource.toTypedArray())) + } + return false } } diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt index 239f5ca10..c2d2e0cb4 100644 --- a/compiler/src/prog8/compiler/Main.kt +++ b/compiler/src/prog8/compiler/Main.kt @@ -221,7 +221,7 @@ private fun writeAssembly(programAst: Program, errors: ErrorReporter, outputDir: programAst.processAstBeforeAsmGeneration(errors) errors.handle() - // printAst(programAst) + printAst(programAst) // TODO CompilationTarget.instance.machine.initializeZeropage(compilerOptions) val assembly = CompilationTarget.instance.asmGenerator( diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt index b6f0bdce8..136b85c04 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt @@ -575,21 +575,30 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, sta $name""") } "<<" -> { - repeat(value) { asmgen.out(" asl $name") } + if(value>=8) asmgen.out(" lda #0 | sta $name") + else repeat(value) { asmgen.out(" asl $name") } } ">>" -> { if(value>0) { if (dt == DataType.UBYTE) { - repeat(value) { asmgen.out(" lsr $name") } + if(value>=8) asmgen.out(" lda #0 | sta $name") + else repeat(value) { asmgen.out(" lsr $name") } } else { - if(value>3) - asmgen.out(""" + when { + value>=8 -> asmgen.out(""" + lda $name + bmi + + lda #0 + beq ++ ++ lda #-1 ++ sta $name""") + value>3 -> asmgen.out(""" lda $name ldy #$value - jsr prog8_lib.lsr_byte_A - sta $name""") // TODO make prog8_lib.lsr_byte_A - else - repeat(value) { asmgen.out(" lda $name | asl a | ror $name") } + jsr math.lsr_byte_A + sta $name""") + else -> repeat(value) { asmgen.out(" lda $name | asl a | ror $name") } + } } } } @@ -798,38 +807,63 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, """) } "<<" -> { - if(value>4) - asmgen.out(""" - lda #$value - sta P8ZP_SCRATCH_B1 - lda #<$name - ldy #>$name - jsr prog8_lib.asl_word_AY""") // TODO make prog8_lib.asl_word_AY - else - repeat(value) { asmgen.out(" asl $name | rol $name+1") } + when { + value>=16 -> asmgen.out(" lda #0 | sta $name | sta $name+1") + value==8 -> asmgen.out(" lda $name | sta $name+1 | lda #0 | sta $name") + value>2 -> asmgen.out(""" + ldy #$value +- asl $name + rol $name+1 + dey + bne - + """) + else -> repeat(value) { asmgen.out(" asl $name | rol $name+1") } + } } ">>" -> { if (value > 0) { if(dt==DataType.UWORD) { - if(value>4) - asmgen.out(""" - lda #$value - sta P8ZP_SCRATCH_B1 - lda #<$name - ldy #>$name - jsr prog8_lib.lsr_uword_AY""") // TODO make prog8_lib.lsr_uword_AY - else - repeat(value) { asmgen.out(" lsr $name+1 | ror $name")} + when { + value>=16 -> asmgen.out(" lda #0 | sta $name | sta $name+1") + value==8 -> asmgen.out(" lda $name+1 | sta $name | lda #0 | sta $name+1") + value>2 -> asmgen.out(""" + ldy #$value +- lsr $name+1 + ror $name + dey + bne -""") + else -> repeat(value) { asmgen.out(" lsr $name+1 | ror $name")} + } } else { - if(value>2) - asmgen.out(""" - lda #$value - sta P8ZP_SCRATCH_B1 - lda #<$name - ldy #>$name - jsr prog8_lib.lsr_word_AY""") // TODO make prog8_lib.lsr_word_AY - else - repeat(value) { asmgen.out(" lda $name+1 | asl a | ror $name+1 | ror $name") } + when { + value>=16 -> asmgen.out(""" + lda $name+1 + bmi + + lda #0 + beq ++ ++ lda #-1 ++ sta $name + sta $name+1""") + value==8 -> asmgen.out(""" + lda $name+1 + sta $name + bmi + + lda #0 +- sta $name+1 + beq ++ ++ lda #-1 + sta $name+1 ++""") + value>2 -> asmgen.out(""" + ldy #$value +- lda $name+1 + asl a + ror $name+1 + ror $name + dey + bne -""") + else -> repeat(value) { asmgen.out(" lda $name+1 | asl a | ror $name+1 | ror $name") } + } } } } diff --git a/compiler/src/prog8/optimizer/ExpressionSimplifier.kt b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt index 9bab6d40c..5fa293397 100644 --- a/compiler/src/prog8/optimizer/ExpressionSimplifier.kt +++ b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt @@ -605,6 +605,7 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() if (amount >= 16) { return NumericLiteralValue(targetDt, 0, expr.position) } else if (amount >= 8) { + // TODO is this correct??? val lsb = TypecastExpression(expr.left, DataType.UBYTE, true, expr.position) if (amount == 8) { return FunctionCall(IdentifierReference(listOf("mkword"), expr.position), mutableListOf(lsb, NumericLiteralValue.optimalInteger(0, expr.position)), expr.position) @@ -644,8 +645,9 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() return NumericLiteralValue.optimalInteger(0, expr.position) } else if (amount >= 8) { val msb = FunctionCall(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position) - if (amount == 8) - return msb + if (amount == 8) { + return TypecastExpression(msb, DataType.UWORD, true, expr.position) + } return BinaryExpression(msb, ">>", NumericLiteralValue.optimalInteger(amount - 8, expr.position), expr.position) } } @@ -653,14 +655,6 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() if (amount > 16) { expr.right = NumericLiteralValue.optimalInteger(16, expr.right.position) return null - } else if (amount >= 8) { - val msbAsByte = TypecastExpression( - FunctionCall(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position), - DataType.BYTE, - true, expr.position) - if (amount == 8) - return msbAsByte - return BinaryExpression(msbAsByte, ">>", NumericLiteralValue.optimalInteger(amount - 8, expr.position), expr.position) } } else -> { diff --git a/examples/test.p8 b/examples/test.p8 index 27de7d4bc..d61628b51 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -7,68 +7,47 @@ main { sub start() { - word zz - uword uu + word ww + uword uw ubyte ub byte bb - bb = -111 - bb >>= 0 - txt.print_ubbin(bb as ubyte, true) + uw = 21111 + uw >>= 9 ; TODO fix this shift! + txt.print_uwbin(uw as uword, true) txt.chrout('\n') - bb = -111 - bb >>= 1 - txt.print_ubbin(bb as ubyte, true) + uw = 21111 + uw >>= 10 ; TODO fix this shift! + txt.print_uwbin(uw as uword, true) txt.chrout('\n') - bb = -111 - bb >>= 2 - txt.print_ubbin(bb as ubyte, true) + uw = 21111 + uw >>= 11 ; TODO fix this shift! + txt.print_uwbin(uw as uword, true) txt.chrout('\n') - bb = -111 - bb >>= 3 - txt.print_ubbin(bb as ubyte, true) + uw = 21111 + uw >>= 12 ; TODO fix this shift! + txt.print_uwbin(uw as uword, true) txt.chrout('\n') - bb = -111 - bb >>= 4 - txt.print_ubbin(bb as ubyte, true) + uw = 21111 + uw >>= 13 ; TODO fix this shift! + txt.print_uwbin(uw as uword, true) txt.chrout('\n') - bb = -111 - bb >>= 5 - txt.print_ubbin(bb as ubyte, true) + uw = 21111 + uw >>= 14 ; TODO fix this shift! + txt.print_uwbin(uw as uword, true) txt.chrout('\n') - bb = -111 - bb >>= 6 - txt.print_ubbin(bb as ubyte, true) + uw = 21111 + uw >>= 15 ; TODO fix this shift! + txt.print_uwbin(uw as uword, true) txt.chrout('\n') - bb = -111 - bb >>= 7 - txt.print_ubbin(bb as ubyte, true) + uw = 21111 + uw >>= 16 ; TODO fix this shift! + txt.print_uwbin(uw as uword, true) txt.chrout('\n') - bb = -111 - bb >>= 8 - txt.print_ubbin(bb as ubyte, true) + uw = 21111 + uw >>= 17 ; TODO fix this shift! + txt.print_uwbin(uw as uword, true) txt.chrout('\n') - bb = -111 - bb >>= 9 - txt.print_ubbin(bb as ubyte, true) - txt.chrout('\n') - -; for ub in 0 to 8 { -; bb = 111 -; bb >>= ub -; txt.print_ubbin(bb as ubyte, true) -; txt.chrout('\n') -; } -; txt.chrout('\n') -; -; for ub in 0 to 8 { -; bb = -111 -; bb >>= ub -; txt.print_ubbin(bb as ubyte, true) -; txt.chrout('\n') -; } -; txt.chrout('\n') - ; ub >>= 7 ; ub <<= 7 ; @@ -81,7 +60,7 @@ main { ; bb >>=7 ; bb <<=7 - ; testX() + testX() } asmsub testX() {