fix some split array issues in 6502 codegen

This commit is contained in:
Irmen de Jong 2023-05-28 22:49:33 +02:00
parent ca60f8ecdd
commit 9896bc110e
3 changed files with 44 additions and 92 deletions

View File

@ -362,16 +362,15 @@ class AsmGen6502Internal (
internal fun loadScaledArrayIndexIntoRegister(
expr: PtArrayIndexer,
elementDt: DataType,
register: CpuRegister,
addOneExtra: Boolean = false
register: CpuRegister
) {
val reg = register.toString().lowercase()
val indexnum = expr.index.asConstInteger()
if (indexnum != null) {
val indexValue = if(expr.splitWords)
indexnum + if (addOneExtra) 1 else 0
indexnum
else
indexnum * options.compTarget.memorySize(elementDt) + if (addOneExtra) 1 else 0
indexnum * options.compTarget.memorySize(elementDt)
out(" ld$reg #$indexValue")
return
}
@ -382,89 +381,40 @@ class AsmGen6502Internal (
val indexName = asmVariableName(indexVar)
if(expr.splitWords) {
if(addOneExtra) {
out(" ldy $indexName | iny")
when (register) {
CpuRegister.A -> out(" tya")
CpuRegister.X -> out(" txy")
CpuRegister.Y -> {}
}
} else {
when (register) {
CpuRegister.A -> out(" lda $indexName")
CpuRegister.X -> out(" ldx $indexName")
CpuRegister.Y -> out(" ldy $indexName")
}
when (register) {
CpuRegister.A -> out(" lda $indexName")
CpuRegister.X -> out(" ldx $indexName")
CpuRegister.Y -> out(" ldy $indexName")
}
return
}
if (addOneExtra) {
// add 1 to the result
when (elementDt) {
in ByteDatatypes -> {
out(" ldy $indexName | iny")
when (register) {
CpuRegister.A -> out(" tya")
CpuRegister.X -> out(" tyx")
CpuRegister.Y -> {}
}
when (elementDt) {
in ByteDatatypes -> out(" ld$reg $indexName")
in WordDatatypes -> {
out(" lda $indexName | asl a")
when (register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
in WordDatatypes -> {
out(" lda $indexName | sec | rol a")
when (register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
}
DataType.FLOAT -> {
require(options.compTarget.memorySize(DataType.FLOAT) == 5) {"invalid float size ${expr.position}"}
out(
"""
lda $indexName
asl a
asl a
sec
adc $indexName"""
)
when (register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
}
else -> throw AssemblyError("weird dt")
}
} else {
when (elementDt) {
in ByteDatatypes -> out(" ld$reg $indexName")
in WordDatatypes -> {
out(" lda $indexName | asl a")
when (register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
DataType.FLOAT -> {
require(options.compTarget.memorySize(DataType.FLOAT) == 5) {"invalid float size ${expr.position}"}
out("""
lda $indexName
asl a
asl a
clc
adc $indexName"""
)
when (register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
DataType.FLOAT -> {
require(options.compTarget.memorySize(DataType.FLOAT) == 5) {"invalid float size ${expr.position}"}
out(
"""
lda $indexName
asl a
asl a
clc
adc $indexName"""
)
when (register) {
CpuRegister.A -> {}
CpuRegister.X -> out(" tax")
CpuRegister.Y -> out(" tay")
}
}
else -> throw AssemblyError("weird dt")
}
else -> throw AssemblyError("weird dt")
}
}

View File

@ -1896,7 +1896,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" inx | lda P8ESTACK_LO,x | sta ${target.asmVarname},y")
}
DataType.UWORD, DataType.WORD -> {
if(target.array!!.splitWords)
if(target.array.splitWords)
TODO("assign into split words ${target.position}")
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
asmgen.out("""
@ -2332,7 +2332,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" lda $sourceName | sta ${target.asmVarname}+$scaledIdx")
}
else {
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, target.datatype, CpuRegister.Y)
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
asmgen.out(" lda $sourceName | sta ${target.asmVarname},y")
}
}
@ -2778,15 +2778,15 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
else -> throw AssemblyError("expected reg pair")
}
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y, true)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y)
asmgen.out("""
pla
sta ${target.asmVarname}_lsb,y
sta ${target.asmVarname}_msb,y
pla
sta ${target.asmVarname}_msb,y""")
sta ${target.asmVarname}_lsb,y""")
} else {
val srcReg = asmgen.asmSymbolName(regs)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y, true)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y)
asmgen.out("""
lda $srcReg
sta ${target.asmVarname}_lsb,y
@ -2821,8 +2821,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
else -> throw AssemblyError("expected reg pair")
}
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y, true)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y)
asmgen.out("""
iny
pla
sta ${target.asmVarname},y
dey
@ -2830,8 +2831,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
sta ${target.asmVarname},y""")
} else {
val srcReg = asmgen.asmSymbolName(regs)
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UWORD, CpuRegister.Y, true)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y)
asmgen.out("""
iny
lda $srcReg+1
sta ${target.asmVarname},y
dey
@ -2933,7 +2935,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
TargetStorageKind.ARRAY -> {
if(target.array!!.splitWords)
TODO("assign into split words ${target.position}")
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UWORD, CpuRegister.Y)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y)
if(target.array.splitWords)
asmgen.out("""
lda #0
@ -2992,7 +2994,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
TargetStorageKind.ARRAY -> {
if(target.array!!.splitWords)
TODO("assign into split words ${target.position}")
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UWORD, CpuRegister.Y)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y)
if(target.array.splitWords)
asmgen.out("""
lda #<${word.toHex()}
@ -3069,7 +3071,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" stz ${target.asmVarname}+$indexValue")
}
else {
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UBYTE, CpuRegister.Y)
asmgen.out(" lda #0 | sta ${target.asmVarname},y")
}
}
@ -3127,7 +3129,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname}+$indexValue")
}
else {
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UBYTE, CpuRegister.Y)
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname},y")
}
}

View File

@ -171,7 +171,7 @@ psg {
}
ubyte[16] envelope_states
uword[16] envelope_volumes ; scaled by 256
uword[16] @split envelope_volumes ; scaled by 256
ubyte[16] envelope_attacks
ubyte[16] envelope_sustains
ubyte[16] envelope_releases