mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
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:
parent
0a356ba73a
commit
7de665d1e4
@ -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) {
|
||||
|
@ -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]) {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
...
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user