support for split wordarrays rol/ror and rol2/ror2

optimized rol and ror codegen

optimize/fix ror/ror2/rol/rol2 on word arrays
This commit is contained in:
Irmen de Jong 2024-01-14 19:03:49 +01:00
parent 0a356ba73a
commit 7de665d1e4
5 changed files with 116 additions and 206 deletions

View File

@ -527,6 +527,7 @@ class AsmGen6502Internal (
elementDt: DataType,
register: CpuRegister
) {
require(elementDt==expr.type) // TODO remove this if it is ok
val reg = register.toString().lowercase()
val indexnum = expr.index.asConstInteger()
if (indexnum != null) {

View File

@ -409,8 +409,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
DataType.UBYTE -> {
when (what) {
is PtArrayIndexer -> {
translateRolRorArrayArgs(what.variable, what, "ror2", 'b')
asmgen.out(" jsr prog8_lib.ror2_array_ub")
asmgen.loadScaledArrayIndexIntoRegister(what, what.type, CpuRegister.X)
val varname = asmgen.asmVariableName(what.variable)
asmgen.out(" lda ${varname},x | lsr a | bcc + | ora #\$80 |+ | sta ${varname},x")
}
is PtMemoryByte -> {
if (what.address is PtNumber) {
@ -431,10 +432,12 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
DataType.UWORD -> {
when (what) {
is PtArrayIndexer -> {
asmgen.loadScaledArrayIndexIntoRegister(what, what.type, CpuRegister.X)
val varname = asmgen.asmVariableName(what.variable)
if(what.splitWords)
TODO("ror2 split words ${what.position}")
translateRolRorArrayArgs(what.variable, what, "ror2", 'w')
asmgen.out(" jsr prog8_lib.ror2_array_uw")
asmgen.out(" lsr ${varname}_msb,x | ror ${varname}_lsb,x | bcc + | lda ${varname}_msb,x | ora #\$80 | sta ${varname}_msb,x |+ ")
else
asmgen.out(" lsr ${varname}+1,x | ror ${varname},x | bcc + | lda ${varname}+1,x | ora #\$80 | sta ${varname}+1,x |+ ")
}
is PtIdentifier -> {
val variable = asmgen.asmVariableName(what)
@ -453,8 +456,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
DataType.UBYTE -> {
when (what) {
is PtArrayIndexer -> {
translateRolRorArrayArgs(what.variable, what, "ror", 'b')
asmgen.out(" jsr prog8_lib.ror_array_ub")
asmgen.loadScaledArrayIndexIntoRegister(what, what.type, CpuRegister.X)
val varname = asmgen.asmVariableName(what.variable)
asmgen.out(" ror ${varname},x")
}
is PtMemoryByte -> {
if (what.address is PtNumber) {
@ -489,10 +493,12 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
DataType.UWORD -> {
when (what) {
is PtArrayIndexer -> {
asmgen.loadScaledArrayIndexIntoRegister(what, what.type, CpuRegister.X)
val varname = asmgen.asmVariableName(what.variable)
if(what.splitWords)
TODO("ror split words ${what.position}")
translateRolRorArrayArgs(what.variable, what, "ror", 'w')
asmgen.out(" jsr prog8_lib.ror_array_uw")
asmgen.out(" ror ${varname}_msb,x | ror ${varname}_lsb,x")
else
asmgen.out(" ror ${varname}+1,x | ror ${varname},x")
}
is PtIdentifier -> {
val variable = asmgen.asmVariableName(what)
@ -511,8 +517,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
DataType.UBYTE -> {
when (what) {
is PtArrayIndexer -> {
translateRolRorArrayArgs(what.variable, what, "rol2", 'b')
asmgen.out(" jsr prog8_lib.rol2_array_ub")
asmgen.loadScaledArrayIndexIntoRegister(what, what.type, CpuRegister.X)
val varname = asmgen.asmVariableName(what.variable)
asmgen.out(" lda ${varname},x | cmp #\$80 | rol a | sta ${varname},x")
}
is PtMemoryByte -> {
if (what.address is PtNumber) {
@ -533,10 +540,12 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
DataType.UWORD -> {
when (what) {
is PtArrayIndexer -> {
asmgen.loadScaledArrayIndexIntoRegister(what, what.type, CpuRegister.X)
val varname = asmgen.asmVariableName(what.variable)
if(what.splitWords)
TODO("rol2 split words ${what.position}")
translateRolRorArrayArgs(what.variable, what, "rol2", 'w')
asmgen.out(" jsr prog8_lib.rol2_array_uw")
asmgen.out(" asl ${varname}_lsb,x | rol ${varname}_msb,x | bcc + | inc ${varname}_lsb |+")
else
asmgen.out(" asl ${varname},x | rol ${varname}+1,x | bcc + | inc ${varname},x |+ ")
}
is PtIdentifier -> {
val variable = asmgen.asmVariableName(what)
@ -555,8 +564,9 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
DataType.UBYTE -> {
when (what) {
is PtArrayIndexer -> {
translateRolRorArrayArgs(what.variable, what, "rol", 'b')
asmgen.out(" jsr prog8_lib.rol_array_ub")
asmgen.loadScaledArrayIndexIntoRegister(what, what.type, CpuRegister.X)
val varname = asmgen.asmVariableName(what.variable)
asmgen.out(" rol ${varname},x")
}
is PtMemoryByte -> {
if (what.address is PtNumber) {
@ -591,10 +601,12 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
DataType.UWORD -> {
when (what) {
is PtArrayIndexer -> {
asmgen.loadScaledArrayIndexIntoRegister(what, what.type, CpuRegister.X)
val varname = asmgen.asmVariableName(what.variable)
if(what.splitWords)
TODO("rol split words ${what.position}")
translateRolRorArrayArgs(what.variable, what, "rol", 'w')
asmgen.out(" jsr prog8_lib.rol_array_uw")
asmgen.out(" rol ${varname}_lsb,x | rol ${varname}_msb,x")
else
asmgen.out(" rol ${varname},x | rol ${varname}+1,x")
}
is PtIdentifier -> {
val variable = asmgen.asmVariableName(what)
@ -607,23 +619,6 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
}
}
private fun translateRolRorArrayArgs(arrayvar: PtIdentifier, indexer: PtArrayIndexer, operation: String, dt: Char) {
if(indexer.splitWords)
TODO("rol/ror split words access ${indexer.position}")
if(arrayvar.type==DataType.UWORD) {
if(dt!='b')
throw AssemblyError("non-array var indexing requires bytes dt")
asmgen.assignExpressionToVariable(arrayvar, "prog8_lib.${operation}_array_u${dt}._arg_target", DataType.UWORD)
} else {
val p = arrayvar.parent
val addressOf = PtAddressOf(arrayvar.position)
addressOf.add(arrayvar)
addressOf.parent = p
asmgen.assignExpressionToVariable(addressOf, "prog8_lib.${operation}_array_u${dt}._arg_target", DataType.UWORD)
}
asmgen.assignExpressionToVariable(indexer.index, "prog8_lib.${operation}_array_u${dt}._arg_index", DataType.UBYTE)
}
private fun funcSetLsbMsb(fcall: PtBuiltinFunctionCall, msb: Boolean) {
val target: AsmAssignTarget
when(fcall.args[0]) {

View File

@ -218,170 +218,6 @@ rol2_mem_ub .proc
rts
.pend
rol_array_ub .proc
; -- rol a ubyte in an array
lda _arg_target
ldy _arg_target+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy _arg_index
lda (P8ZP_SCRATCH_W1),y
rol a
sta (P8ZP_SCRATCH_W1),y
rts
_arg_target .word 0
_arg_index .byte 0
.pend
ror_array_ub .proc
; -- ror a ubyte in an array
lda _arg_target
ldy _arg_target+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy _arg_index
lda (P8ZP_SCRATCH_W1),y
ror a
sta (P8ZP_SCRATCH_W1),y
rts
_arg_target .word 0
_arg_index .byte 0
.pend
ror2_array_ub .proc
; -- ror2 (8-bit ror) a ubyte in an array
lda _arg_target
ldy _arg_target+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy _arg_index
lda (P8ZP_SCRATCH_W1),y
lsr a
bcc +
ora #$80
+ sta (P8ZP_SCRATCH_W1),y
rts
_arg_target .word 0
_arg_index .byte 0
.pend
rol2_array_ub .proc
; -- rol2 (8-bit rol) a ubyte in an array
lda _arg_target
ldy _arg_target+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy _arg_index
lda (P8ZP_SCRATCH_W1),y
cmp #$80
rol a
sta (P8ZP_SCRATCH_W1),y
rts
_arg_target .word 0
_arg_index .byte 0
.pend
ror_array_uw .proc
; -- ror a uword in an array
php
lda _arg_target
ldy _arg_target+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda _arg_index
asl a
tay
iny
lda (P8ZP_SCRATCH_W1),y
plp
ror a
sta (P8ZP_SCRATCH_W1),y
dey
lda (P8ZP_SCRATCH_W1),y
ror a
sta (P8ZP_SCRATCH_W1),y
rts
_arg_target .word 0
_arg_index .byte 0
.pend
rol_array_uw .proc
; -- rol a uword in an array
php
lda _arg_target
ldy _arg_target+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda _arg_index
asl a
tay
lda (P8ZP_SCRATCH_W1),y
plp
rol a
sta (P8ZP_SCRATCH_W1),y
iny
lda (P8ZP_SCRATCH_W1),y
rol a
sta (P8ZP_SCRATCH_W1),y
rts
_arg_target .word 0
_arg_index .byte 0
.pend
rol2_array_uw .proc
; -- rol2 (16-bit rol) a uword in an array
lda _arg_target
ldy _arg_target+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda _arg_index
asl a
tay
lda (P8ZP_SCRATCH_W1),y
asl a
sta (P8ZP_SCRATCH_W1),y
iny
lda (P8ZP_SCRATCH_W1),y
rol a
sta (P8ZP_SCRATCH_W1),y
bcc +
dey
lda (P8ZP_SCRATCH_W1),y
adc #0
sta (P8ZP_SCRATCH_W1),y
+ rts
_arg_target .word 0
_arg_index .byte 0
.pend
ror2_array_uw .proc
; -- ror2 (16-bit ror) a uword in an array
lda _arg_target
ldy _arg_target+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda _arg_index
asl a
tay
iny
lda (P8ZP_SCRATCH_W1),y
lsr a
sta (P8ZP_SCRATCH_W1),y
dey
lda (P8ZP_SCRATCH_W1),y
ror a
sta (P8ZP_SCRATCH_W1),y
bcc +
iny
lda (P8ZP_SCRATCH_W1),y
ora #$80
sta (P8ZP_SCRATCH_W1),y
+ rts
_arg_target .word 0
_arg_index .byte 0
.pend
strcpy .proc
; copy a string (must be 0-terminated) from A/Y to (P8ZP_SCRATCH_W1)

View File

@ -1,10 +1,14 @@
TODO
====
funcRor()/funcRol(): save carry flag before calculating array index otherwise it gets clobbered
rol/ror a membyte through a uword ptr
split words sort and reverse
split words rol and ror and rol2/ror2
split words any and all
loadScaledArrayIndexIntoRegister(): the type arg can be removed?
Mark had a compiler crash FatalAstException: invalid dt
...

View File

@ -1,13 +1,87 @@
%import textio
%import floats
%zeropage basicsafe
%option no_sysinit
main {
sub start() {
float[] fa = [1.1, 2.2, 3.3]
float @shared fl = 2.2
/*
mem()
bytes()
*/
words()
}
txt.print_ub(fl in fa)
sub mem() {
@($2000) = $7a
rol(@($2000))
txt.print_ubbin(@($2000), true)
txt.nl()
rol2(@($2000))
txt.print_ubbin(@($2000), true)
txt.nl()
ror(@($2000))
txt.print_ubbin(@($2000), true)
txt.nl()
ror2(@($2000))
txt.print_ubbin(@($2000), true)
txt.nl()
txt.nl()
}
sub bytes() {
ubyte[] wa = [$1a, $2b, $3c]
txt.print_ubbin(wa[2], true)
txt.nl()
rol(wa[2])
txt.print_ubbin(wa[2], true)
txt.nl()
rol2(wa[2])
txt.print_ubbin(wa[2], true)
txt.nl()
ror(wa[2])
txt.print_ubbin(wa[2], true)
txt.nl()
ror2(wa[2])
txt.print_ubbin(wa[2], true)
txt.nl()
txt.nl()
}
sub words() {
uword[] wa = [$11aa, $22bb, $33cc]
uword[] @split swa = [$11aa, $22bb, $33cc]
txt.print_uwbin(wa[2], true)
txt.nl()
rol(wa[2])
txt.print_uwbin(wa[2], true)
txt.nl()
rol2(wa[2])
txt.print_uwbin(wa[2], true)
txt.nl()
ror(wa[2])
txt.print_uwbin(wa[2], true)
txt.nl()
ror2(wa[2])
txt.print_uwbin(wa[2], true)
txt.nl()
txt.nl()
txt.print_uwbin(swa[2], true)
txt.nl()
rol(swa[2])
txt.print_uwbin(swa[2], true)
txt.nl()
rol2(swa[2])
txt.print_uwbin(swa[2], true)
txt.nl()
ror(swa[2])
txt.print_uwbin(swa[2], true)
txt.nl()
ror2(swa[2])
txt.print_uwbin(swa[2], true)
txt.nl()
txt.nl()
}
}