diff --git a/compiler/res/prog8lib/prog8_lib.asm b/compiler/res/prog8lib/prog8_lib.asm index 934e55a1a..90cc30bf6 100644 --- a/compiler/res/prog8lib/prog8_lib.asm +++ b/compiler/res/prog8lib/prog8_lib.asm @@ -2145,3 +2145,34 @@ 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/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt index 6cd784fc3..b6f0bdce8 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AugmentableAssignmentAsmGen.kt @@ -1,6 +1,5 @@ package prog8.compiler.target.c64.codegen.assignment -import prog8.ast.INameScope import prog8.ast.Program import prog8.ast.base.* import prog8.ast.expressions.* @@ -497,25 +496,31 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, "<<" -> { asmgen.out(""" ldy $otherName + beq + - asl $name dey - bne -""") + bne - ++""") } ">>" -> { if(dt==DataType.UBYTE) { asmgen.out(""" ldy $otherName + beq + - lsr $name dey - bne -""") + bne - ++""") } else { asmgen.out(""" ldy $otherName + beq + - lda $name asl a ror $name dey - bne -""") + bne - ++""") } } "&" -> asmgen.out(" lda $name | and $otherName | sta $name") @@ -577,7 +582,14 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, if (dt == DataType.UBYTE) { repeat(value) { asmgen.out(" lsr $name") } } else { - repeat(value) { asmgen.out(" lda $name | asl a | ror $name") } + if(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") } } } } @@ -786,14 +798,38 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, """) } "<<" -> { - repeat(value) { asmgen.out(" asl $name | rol $name+1") } + 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") } } ">>" -> { if (value > 0) { if(dt==DataType.UWORD) { - repeat(value) { asmgen.out(" lsr $name+1 | ror $name")} + 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")} } else { - repeat(value) { asmgen.out(" lda $name+1 | asl a | ror $name+1 | ror $name") } + 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") } } } } @@ -917,28 +953,34 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, "<<" -> { asmgen.out(""" ldy $otherName + beq + - asl $name rol $name+1 dey - bne -""") + bne - ++""") } ">>" -> { if(dt==DataType.UWORD) { asmgen.out(""" ldy $otherName + beq + - lsr $name+1 ror $name dey - bne -""") + bne - ++""") } else { asmgen.out(""" ldy $otherName + beq + - lda $name+1 asl a ror $name+1 ror $name dey - bne -""") + bne - ++""") } } "&" -> { diff --git a/examples/test.p8 b/examples/test.p8 index 507c57ff1..27de7d4bc 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -7,21 +7,81 @@ main { sub start() { - uword zc + word zz + uword uu + ubyte ub + byte bb - zc = 99 - scolor2=scolor + bb = -111 + bb >>= 0 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') + bb = -111 + bb >>= 1 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') + bb = -111 + bb >>= 2 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') + bb = -111 + bb >>= 3 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') + bb = -111 + bb >>= 4 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') + bb = -111 + bb >>= 5 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') + bb = -111 + bb >>= 6 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') + bb = -111 + bb >>= 7 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') + bb = -111 + bb >>= 8 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') + bb = -111 + bb >>= 9 + txt.print_ubbin(bb as ubyte, true) + txt.chrout('\n') - ; TODO WHy does this compile with stack eval: - ubyte scolor = (zc>>13) as ubyte + 4 +; 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') - ; TODO this is more optimized: - ubyte scolor2 - scolor2 = (zc>>13) as ubyte + 4 +; ub >>= 7 +; ub <<= 7 +; +; uu >>=7 +; uu <<= 7 +; +; zz >>=7 +; zz <<=7 +; +; bb >>=7 +; bb <<=7 - scolor2=scolor - - testX() + ; testX() } asmsub testX() {