fixed split-word array in-place element +/- (other operators not yet...)

This commit is contained in:
Irmen de Jong 2024-01-28 22:30:45 +01:00
parent 64d8943b7d
commit 0800033b47
2 changed files with 148 additions and 13 deletions

View File

@ -208,10 +208,23 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
TargetStorageKind.ARRAY -> {
val indexNum = target.array!!.index as? PtNumber
if (indexNum!=null) {
val targetVarName = if(target.array.splitWords)
"${target.asmVarname} + ${indexNum.number.toInt()}"
else
"${target.asmVarname} + ${indexNum.number.toInt()*program.memsizer.memorySize(target.datatype)}"
val index = indexNum.number.toInt()
if(target.array.splitWords) {
when(value.kind) {
SourceStorageKind.LITERALNUMBER -> inplacemodificationSplitWordWithLiteralval(target.asmVarname, index, operator, value.number!!.number.toInt())
else -> {
// TODO: more optimized code for VARIABLE, REGISTER, MEMORY, ARRAY, EXPRESSION in the case of split-word arrays
val scope = target.origAstTarget?.definingSub()
val regTarget = AsmAssignTarget.fromRegisters(RegisterOrPair.R0, false, target.position, scope, asmgen)
val assignToReg = AsmAssignment(value, regTarget, program.memsizer, target.position)
assignmentAsmGen.translateNormalAssignment(assignToReg, scope)
inplacemodificationSplitWordWithR0(target.asmVarname, index, operator)
}
}
return
}
// normal array
val targetVarName = "${target.asmVarname} + ${index*program.memsizer.memorySize(target.datatype)}"
when (target.datatype) {
in ByteDatatypes -> {
when(value.kind) {
@ -458,6 +471,91 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
}
private fun inplacemodificationSplitWordWithR0(arrayVar: String, index: Int, operator: String) {
when (operator) {
"+" -> {
asmgen.out("""
lda ${arrayVar}_lsb+$index
clc
adc cx16.r0L
sta ${arrayVar}_lsb+$index
lda ${arrayVar}_msb+$index
adc cx16.r0H
sta ${arrayVar}_msb+$index""")
}
"-" -> {
asmgen.out("""
lda ${arrayVar}_lsb+$index
sec
sbc cx16.r0L
sta ${arrayVar}_lsb+$index
lda ${arrayVar}_msb+$index
sbc cx16.r0H
sta ${arrayVar}_msb+$index""")
}
else -> TODO("in-place modify split-words array value for operator $operator")
}
}
private fun inplacemodificationSplitWordWithLiteralval(arrayVar: String, index: Int, operator: String, value: Int) {
// note: this contains special optimized cases because we know the exact value. Don't replace this with another routine.
when (operator) {
"+" -> {
when {
value==0 -> {}
value in 1..0xff -> asmgen.out("""
lda ${arrayVar}_lsb+$index
clc
adc #$value
sta ${arrayVar}_lsb+$index
bcc +
inc ${arrayVar}_msb+$index
+""")
value==0x0100 -> asmgen.out(" inc ${arrayVar}_msb+$index")
value==0x0200 -> asmgen.out(" inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index")
value==0x0300 -> asmgen.out(" inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index")
value==0x0400 -> asmgen.out(" inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index | inc ${arrayVar}_msb+$index")
value and 255==0 -> asmgen.out(" lda ${arrayVar}_msb+$index | clc | adc #>$value | sta ${arrayVar}_msb+$index")
else -> asmgen.out("""
lda ${arrayVar}_lsb+$index
clc
adc #<$value
sta ${arrayVar}_lsb+$index
lda ${arrayVar}_msb+$index
adc #>$value
sta ${arrayVar}_msb+$index""")
}
}
"-" -> {
when {
value==0 -> {}
value in 1..0xff -> asmgen.out("""
lda ${arrayVar}_lsb+$index
sec
sbc #$value
sta ${arrayVar}_lsb+$index
bcs +
dec ${arrayVar}_msb+$index
+""")
value==0x0100 -> asmgen.out(" dec ${arrayVar}_msb+$index")
value==0x0200 -> asmgen.out(" dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index")
value==0x0300 -> asmgen.out(" dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index")
value==0x0400 -> asmgen.out(" dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index | dec ${arrayVar}_msb+$index")
value and 255==0 -> asmgen.out(" lda ${arrayVar}_msb+$index | sec | sbc #>$value | sta ${arrayVar}_msb+$index")
else -> asmgen.out("""
lda ${arrayVar}_lsb+$index
sec
sbc #<$value
sta ${arrayVar}_lsb+$index
lda ${arrayVar}_msb+$index
sbc #>$value
sta ${arrayVar}_msb+$index""")
}
}
else -> TODO("in-place modify split-words array value for operator $operator")
}
}
private fun inplacemodificationRegisterAXwithVariable(operator: String, variable: String, varDt: DataType): Boolean {
when(operator) {
"+" -> {

View File

@ -5,16 +5,53 @@
main {
sub start() {
ubyte @shared xx
uword[3] ubarr
bool[3] barr
float[3] flarr
bool @shared bb
ubyte @shared index = 1
ubarr[1] = ubarr[1] < 2
ubarr[1] = ubarr[1] <= 2
ubarr[1] = ubarr[1] > 3
ubarr[1] = ubarr[1] >= 3
; @(2000) = 99
; uword @shared ptr = 2000
; txt.print_ub(@(2000))
; txt.nl()
; @(2000) ++
; @(2000) ++
; @(2000) --
; txt.print_ub(@(2000))
; txt.nl()
uword[3] @split arr
arr[1] = 9999
txt.print_uw(arr[1])
txt.nl()
arr[1] = arr[1]*5
cx16.r0=2222
arr[1] *= cx16.r0
arr[1] -=5
arr[1] -=index
txt.print_uw(arr[1])
txt.nl()
; arr[index] = 9999
; txt.print_uw(arr[index])
; txt.nl()
; arr[index] += 5
; arr[index] += 5
; arr[index] -= 5
; txt.print_uw(arr[index])
; txt.nl()
;
; ubyte @shared xx
; uword[3] ubarr
; bool[3] barr
; float[3] flarr
; bool @shared bb
;
; ubarr[1] = ubarr[1] < 2
; ubarr[1] = ubarr[1] <= 2
; ubarr[1] = ubarr[1] > 3
; ubarr[1] = ubarr[1] >= 3
; barr[1] = barr[0] and barr[2]
; barr[1] = barr[0] or barr[2]