From 9edc92ec29ad01b4112fbf6c7a38071e337b9b27 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 23 Aug 2019 23:06:36 +0200 Subject: [PATCH] more bitshift asm stubs (actual functions still to be done) --- compiler/res/prog8lib/prog8lib.asm | 83 ++++++++++++++--- .../c64/codegen/BuiltinFunctionsAsmGen.kt | 91 +++++++++++++++---- .../target/c64/codegen/ExpressionsAsmGen.kt | 6 +- examples/arithmetic/bitshift.p8 | 11 +++ 4 files changed, 157 insertions(+), 34 deletions(-) diff --git a/compiler/res/prog8lib/prog8lib.asm b/compiler/res/prog8lib/prog8lib.asm index 78cfd381e..9e6a878db 100644 --- a/compiler/res/prog8lib/prog8lib.asm +++ b/compiler/res/prog8lib/prog8lib.asm @@ -1672,37 +1672,90 @@ _loop_hi sty c64.SCRATCH_ZPREG rts .pend -ror2_mem_b .proc +ror2_mem_ub .proc ; -- in-place 8-bit ror of byte at memory location on stack inx lda c64.ESTACK_LO,x - sta _mod1+1 - sta _mod2+1 + sta c64.SCRATCH_ZPWORD1 lda c64.ESTACK_HI,x - sta _mod1+2 - sta _mod2+2 -_mod1 lda $ffff ; modified + sta c64.SCRATCH_ZPWORD1+1 + ldy #0 + lda (c64.SCRATCH_ZPWORD1),y lsr a - bcc _mod2 + bcc + ora #$80 -_mod2 sta $ffff ; modified ++ sta (c64.SCRATCH_ZPWORD1),y rts .pend -rol2_mem_b .proc +rol2_mem_ub .proc ; -- in-place 8-bit rol of byte at memory location on stack ;" lda ${number.toHex()} | cmp #\$80 | rol a | sta ${number.toHex()}" inx lda c64.ESTACK_LO,x - sta _mod1+1 - sta _mod2+1 + sta c64.SCRATCH_ZPWORD1 lda c64.ESTACK_HI,x - sta _mod1+2 - sta _mod2+2 -_mod1 lda $ffff ; modified + sta c64.SCRATCH_ZPWORD1+1 + ldy #0 + lda (c64.SCRATCH_ZPWORD1),y cmp #$80 rol a -_mod2 sta $ffff ; modified + sta (c64.SCRATCH_ZPWORD1),y rts .pend +lsl_array_b .proc + .warn "lsl_array_b" ; TODO + .pend + +lsl_array_w .proc + .warn "lsl_array_w" ; TODO + .pend + +lsr_array_ub .proc + .warn "lsr_array_ub" ; TODO + .pend + +lsr_array_b .proc + .warn "lsr_array_b" ; TODO + .pend + +lsr_array_uw .proc + .warn "lsl_array_uw" ; TODO + .pend + +lsr_array_w .proc + .warn "lsr_array_w" ; TODO + .pend + +rol_array_ub .proc + .warn "rol_array_ub" ; TODO + .pend + +rol_array_uw .proc + .warn "rol_array_uw" ; TODO + .pend + +rol2_array_ub .proc + .warn "rol2_array_ub" ; TODO + .pend + +rol2_array_uw .proc + .warn "rol2_array_uw" ; TODO + .pend + +ror_array_ub .proc + .warn "ror_array_ub" ; TODO + .pend + +ror_array_uw .proc + .warn "ror_array_uw" ; TODO + .pend + +ror2_array_ub .proc + .warn "ror2_array_ub" ; TODO + .pend + +ror2_array_uw .proc + .warn "ror2_array_uw" ; TODO + .pend diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index 8320bc4d2..95163d2b2 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -152,13 +152,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val """) } } - is ArrayIndexedExpression -> TODO("lsl byte array $what") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.lsl_array_b") + } else -> throw AssemblyError("weird type") } } in WordDatatypes -> { when (what) { - is ArrayIndexedExpression -> TODO("lsl sbyte $what") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.lsl_array_w") + } is IdentifierReference -> { val variable = asmgen.asmIdentifierName(what) asmgen.out(" asl $variable | rol $variable+1") @@ -200,13 +208,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val """) } } - is ArrayIndexedExpression -> TODO("lsr byte array $what") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.lsr_array_ub") + } else -> throw AssemblyError("weird type") } } DataType.BYTE -> { when (what) { - is ArrayIndexedExpression -> TODO("lsr sbyte $what") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.lsr_array_b") + } is IdentifierReference -> { val variable = asmgen.asmIdentifierName(what) asmgen.out(" lda $variable | asl a | ror $variable") @@ -216,7 +232,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } DataType.UWORD -> { when (what) { - is ArrayIndexedExpression -> TODO("lsr uword $what") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.lsr_array_uw") + } is IdentifierReference -> { val variable = asmgen.asmIdentifierName(what) asmgen.out(" lsr $variable+1 | ror $variable") @@ -226,7 +246,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } DataType.WORD -> { when (what) { - is ArrayIndexedExpression -> TODO("lsr sword $what") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.lsr_array_w") + } is IdentifierReference -> { val variable = asmgen.asmIdentifierName(what) asmgen.out(" lda $variable+1 | asl a | ror $variable+1 | ror $variable") @@ -244,7 +268,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val when (dt.typeOrElse(DataType.STRUCT)) { DataType.UBYTE -> { when(what) { - is ArrayIndexedExpression -> TODO("rol ubyte array") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.rol_array_ub") + } is DirectMemoryRead -> { if (what.addressExpression is NumericLiteralValue) { val number = (what.addressExpression as NumericLiteralValue).number @@ -277,7 +305,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } DataType.UWORD -> { when(what) { - is ArrayIndexedExpression -> TODO("rol uword array") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.rol_array_uw") + } is IdentifierReference -> { val variable = asmgen.asmIdentifierName(what) asmgen.out(" rol $variable | rol $variable+1") @@ -295,14 +327,18 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val when (dt.typeOrElse(DataType.STRUCT)) { DataType.UBYTE -> { when(what) { - is ArrayIndexedExpression -> TODO("rol2 ubyte array") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.rol2_array_ub") + } is DirectMemoryRead -> { if (what.addressExpression is NumericLiteralValue) { val number = (what.addressExpression as NumericLiteralValue).number asmgen.out(" lda ${number.toHex()} | cmp #\$80 | rol a | sta ${number.toHex()}") } else { asmgen.translateExpression(what.addressExpression) - asmgen.out(" jsr prog8_lib.rol2_mem_b") + asmgen.out(" jsr prog8_lib.rol2_mem_ub") } } is RegisterExpr -> { @@ -321,7 +357,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } DataType.UWORD -> { when(what) { - is ArrayIndexedExpression -> TODO("rol2 uword array") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.rol2_array_uw") + } is IdentifierReference -> { val variable = asmgen.asmIdentifierName(what) asmgen.out(" asl $variable | rol $variable+1 | bcc + | inc $variable |+ ") @@ -339,7 +379,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val when (dt.typeOrElse(DataType.STRUCT)) { DataType.UBYTE -> { when(what) { - is ArrayIndexedExpression -> TODO("ror ubyte array") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.ror_array_ub") + } is DirectMemoryRead -> { if (what.addressExpression is NumericLiteralValue) { val number = (what.addressExpression as NumericLiteralValue).number @@ -371,7 +415,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } DataType.UWORD -> { when(what) { - is ArrayIndexedExpression -> TODO("ror uword array") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.ror_array_uw") + } is IdentifierReference -> { val variable = asmgen.asmIdentifierName(what) asmgen.out(" ror $variable+1 | ror $variable") @@ -389,14 +437,18 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val when (dt.typeOrElse(DataType.STRUCT)) { DataType.UBYTE -> { when(what) { - is ArrayIndexedExpression -> TODO("ror2 ubyte array") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.ror2_array_ub") + } is DirectMemoryRead -> { if (what.addressExpression is NumericLiteralValue) { val number = (what.addressExpression as NumericLiteralValue).number asmgen.out(" lda ${number.toHex()} | lsr a | bcc + | ora #\$80 |+ | sta ${number.toHex()}") } else { asmgen.translateExpression(what.addressExpression) - asmgen.out(" jsr prog8_lib.ror2_mem_b") + asmgen.out(" jsr prog8_lib.ror2_mem_ub") } } is RegisterExpr -> { @@ -411,10 +463,15 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen.out(" lda $variable | lsr a | bcc + | ora #\$80 |+ | sta $variable") } else -> throw AssemblyError("weird type") - } } + } + } DataType.UWORD -> { when(what) { - is ArrayIndexedExpression -> TODO("ror2 uword array") + is ArrayIndexedExpression -> { + asmgen.translateExpression(what.identifier) + asmgen.translateExpression(what.arrayspec.index) + asmgen.out(" jsr prog8_lib.ror2_array_uw") + } is IdentifierReference -> { val variable = asmgen.asmIdentifierName(what) asmgen.out(" lsr $variable+1 | ror $variable | bcc + | lda $variable+1 | ora #\$80 | sta $variable+1 |+ ") diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt index 999814aa1..c91cceccd 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ExpressionsAsmGen.kt @@ -164,10 +164,12 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge DataType.UBYTE, DataType.BYTE -> { asmgen.out(" lda $varname | sta ${MachineDefinition.ESTACK_LO_HEX},x | dex") } - DataType.UWORD, DataType.WORD, in ArrayDatatypes, in StringDatatypes -> { - // (for arrays and strings, push their address) + DataType.UWORD, DataType.WORD -> { asmgen.out(" lda $varname | sta ${MachineDefinition.ESTACK_LO_HEX},x | lda $varname+1 | sta ${MachineDefinition.ESTACK_HI_HEX},x | dex") } + in ArrayDatatypes, in StringDatatypes -> { + asmgen.out(" lda #<$varname | sta ${MachineDefinition.ESTACK_LO_HEX},x | lda #>$varname | sta ${MachineDefinition.ESTACK_HI_HEX},x | dex") + } DataType.FLOAT -> { asmgen.out(" lda #<$varname | ldy #>$varname| jsr c64flt.push_float") } diff --git a/examples/arithmetic/bitshift.p8 b/examples/arithmetic/bitshift.p8 index 2ed032903..c9c866438 100644 --- a/examples/arithmetic/bitshift.p8 +++ b/examples/arithmetic/bitshift.p8 @@ -12,7 +12,9 @@ main { &ubyte membyte=9999 &uword memword=9999 ubyte[10] ubarray + uword[10] uwarray byte[10] bbarray + word[10] wwarray sub start() { ; lsr(A) @@ -61,6 +63,15 @@ main { lsr(bbarray[1]) lsl(bbarray[1]) + lsr(uwarray[1]) + lsl(uwarray[1]) + ror(uwarray[1]) + rol(uwarray[1]) + ror2(uwarray[1]) + rol2(uwarray[1]) + lsr(wwarray[1]) + lsl(wwarray[1]) + bb /= 2 bb >>= 1