mirror of
https://github.com/irmen/prog8.git
synced 2024-11-16 22:09:56 +00:00
more array access optimizations
This commit is contained in:
parent
5c62f612cc
commit
1f17c22132
@ -181,12 +181,68 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
storeByteViaRegisterAInMemoryAddress("$ESTACK_LO_HEX,x", target.memory!!)
|
storeByteViaRegisterAInMemoryAddress("$ESTACK_LO_HEX,x", target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
// if(target.constArrayIndexValue!=null) {
|
val index = target.array!!.arrayspec.index
|
||||||
// TODO("const index ${target.constArrayIndexValue}")
|
when {
|
||||||
// }
|
target.constArrayIndexValue!=null -> {
|
||||||
asmgen.translateExpression(target.array!!.arrayspec.index)
|
val scaledIdx = target.constArrayIndexValue!! * target.datatype.memorySize()
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
when(target.datatype) {
|
||||||
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
in ByteDatatypes -> {
|
||||||
|
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta ${target.asmVarname}+$scaledIdx")
|
||||||
|
}
|
||||||
|
in WordDatatypes -> {
|
||||||
|
asmgen.out("""
|
||||||
|
inx
|
||||||
|
lda $ESTACK_LO_HEX,x
|
||||||
|
sta ${target.asmVarname}+$scaledIdx
|
||||||
|
lda $ESTACK_HI_HEX,x
|
||||||
|
sta ${target.asmVarname}+$scaledIdx+1
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
DataType.FLOAT -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<${target.asmVarname}+$scaledIdx
|
||||||
|
ldy #>${target.asmVarname}+$scaledIdx
|
||||||
|
jsr c64flt.pop_float
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird target variable type ${target.datatype}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index is IdentifierReference -> {
|
||||||
|
when(target.datatype) {
|
||||||
|
DataType.UBYTE, DataType.BYTE -> {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
|
||||||
|
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta ${target.asmVarname},y")
|
||||||
|
}
|
||||||
|
DataType.UWORD, DataType.WORD -> {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
|
||||||
|
asmgen.out("""
|
||||||
|
inx
|
||||||
|
lda $ESTACK_LO_HEX,x
|
||||||
|
sta ${target.asmVarname},y
|
||||||
|
lda $ESTACK_HI_HEX,x
|
||||||
|
sta ${target.asmVarname}+1,y
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
DataType.FLOAT -> {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.A)
|
||||||
|
asmgen.out("""
|
||||||
|
ldy #>${target.asmVarname}
|
||||||
|
clc
|
||||||
|
adc #<${target.asmVarname}
|
||||||
|
bcc +
|
||||||
|
iny
|
||||||
|
+ jsr c64flt.pop_float""")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird dt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
asmgen.translateExpression(index)
|
||||||
|
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
||||||
|
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.REGISTER -> TODO()
|
TargetStorageKind.REGISTER -> TODO()
|
||||||
TargetStorageKind.STACK -> TODO()
|
TargetStorageKind.STACK -> TODO()
|
||||||
@ -242,14 +298,75 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
throw AssemblyError("no asm gen for assign wordvar $sourceName to memory ${target.memory}")
|
throw AssemblyError("no asm gen for assign wordvar $sourceName to memory ${target.memory}")
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
// if(target.constArrayIndexValue!=null) {
|
|
||||||
// TODO("const index ${target.constArrayIndexValue}")
|
|
||||||
// }
|
|
||||||
val index = target.array!!.arrayspec.index
|
val index = target.array!!.arrayspec.index
|
||||||
asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | lda $sourceName+1 | sta $ESTACK_HI_HEX,x | dex")
|
when {
|
||||||
asmgen.translateExpression(index)
|
target.constArrayIndexValue!=null -> {
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
val scaledIdx = target.constArrayIndexValue!! * target.datatype.memorySize()
|
||||||
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
when(target.datatype) {
|
||||||
|
in ByteDatatypes -> {
|
||||||
|
asmgen.out(" lda $sourceName | sta ${target.asmVarname}+$scaledIdx")
|
||||||
|
}
|
||||||
|
in WordDatatypes -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda $sourceName
|
||||||
|
sta ${target.asmVarname}+$scaledIdx
|
||||||
|
lda $sourceName+1
|
||||||
|
sta ${target.asmVarname}+$scaledIdx+1
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
DataType.FLOAT -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$sourceName
|
||||||
|
ldy #>$sourceName
|
||||||
|
sta ${C64Zeropage.SCRATCH_W1}
|
||||||
|
sty ${C64Zeropage.SCRATCH_W1+1}
|
||||||
|
lda #<${target.asmVarname}+$scaledIdx
|
||||||
|
ldy #>${target.asmVarname}+$scaledIdx
|
||||||
|
jsr c64flt.copy_float
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird target variable type ${target.datatype}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index is IdentifierReference -> {
|
||||||
|
when(target.datatype) {
|
||||||
|
DataType.UBYTE, DataType.BYTE -> {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
|
||||||
|
asmgen.out(" lda $sourceName | sta ${target.asmVarname},y")
|
||||||
|
}
|
||||||
|
DataType.UWORD, DataType.WORD -> {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
|
||||||
|
asmgen.out("""
|
||||||
|
lda $sourceName
|
||||||
|
sta ${target.asmVarname},y
|
||||||
|
lda $sourceName+1
|
||||||
|
sta ${target.asmVarname}+1,y
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
DataType.FLOAT -> {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.A)
|
||||||
|
asmgen.out("""
|
||||||
|
ldy #<$sourceName
|
||||||
|
sty ${C64Zeropage.SCRATCH_W1}
|
||||||
|
ldy #>$sourceName
|
||||||
|
sty ${C64Zeropage.SCRATCH_W1+1}
|
||||||
|
ldy #>${target.asmVarname}
|
||||||
|
clc
|
||||||
|
adc #<${target.asmVarname}
|
||||||
|
bcc +
|
||||||
|
iny
|
||||||
|
+ jsr c64flt.copy_float""")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird dt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | lda $sourceName+1 | sta $ESTACK_HI_HEX,x | dex")
|
||||||
|
asmgen.translateExpression(index)
|
||||||
|
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
||||||
|
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.REGISTER -> TODO()
|
TargetStorageKind.REGISTER -> TODO()
|
||||||
TargetStorageKind.STACK -> TODO()
|
TargetStorageKind.STACK -> TODO()
|
||||||
@ -274,8 +391,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
|
// TODO optimize this, but the situation doesn't occur very often
|
||||||
// if(target.constArrayIndexValue!=null) {
|
// if(target.constArrayIndexValue!=null) {
|
||||||
// TODO("const index ${target.constArrayIndexValue}")
|
// TODO("const index ${target.constArrayIndexValue}")
|
||||||
|
// } else if(target.array!!.arrayspec.index is IdentifierReference) {
|
||||||
|
// TODO("array[var] ${target.constArrayIndexValue}")
|
||||||
// }
|
// }
|
||||||
val index = target.array!!.arrayspec.index
|
val index = target.array!!.arrayspec.index
|
||||||
asmgen.out(" lda #<$sourceName | ldy #>$sourceName | jsr c64flt.push_float")
|
asmgen.out(" lda #<$sourceName | ldy #>$sourceName | jsr c64flt.push_float")
|
||||||
@ -299,14 +419,23 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
storeByteViaRegisterAInMemoryAddress(sourceName, target.memory!!)
|
storeByteViaRegisterAInMemoryAddress(sourceName, target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
// if(target.constArrayIndexValue!=null) {
|
|
||||||
// TODO("const index ${target.constArrayIndexValue}")
|
|
||||||
// }
|
|
||||||
val index = target.array!!.arrayspec.index
|
val index = target.array!!.arrayspec.index
|
||||||
asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | dex")
|
when {
|
||||||
asmgen.translateExpression(index)
|
target.constArrayIndexValue!=null -> {
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
val scaledIdx = target.constArrayIndexValue!! * target.datatype.memorySize()
|
||||||
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
asmgen.out(" lda $sourceName | sta ${target.asmVarname}+$scaledIdx")
|
||||||
|
}
|
||||||
|
index is IdentifierReference -> {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
|
||||||
|
asmgen.out(" lda $sourceName | sta ${target.asmVarname},y")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | dex")
|
||||||
|
asmgen.translateExpression(index)
|
||||||
|
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
||||||
|
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.REGISTER -> TODO()
|
TargetStorageKind.REGISTER -> TODO()
|
||||||
TargetStorageKind.STACK -> TODO()
|
TargetStorageKind.STACK -> TODO()
|
||||||
@ -323,9 +452,6 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
storeRegisterInMemoryAddress(register, target.memory!!)
|
storeRegisterInMemoryAddress(register, target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
// if(target.constArrayIndexValue!=null) {
|
|
||||||
// TODO("const index ${target.constArrayIndexValue}")
|
|
||||||
// }
|
|
||||||
val index = target.array!!.arrayspec.index
|
val index = target.array!!.arrayspec.index
|
||||||
when (index) {
|
when (index) {
|
||||||
is NumericLiteralValue -> {
|
is NumericLiteralValue -> {
|
||||||
@ -338,16 +464,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
when (register) {
|
when (register) {
|
||||||
CpuRegister.A -> asmgen.out(" sta ${C64Zeropage.SCRATCH_B1}")
|
CpuRegister.A -> {}
|
||||||
CpuRegister.X -> asmgen.out(" stx ${C64Zeropage.SCRATCH_B1}")
|
CpuRegister.X -> asmgen.out(" txa")
|
||||||
CpuRegister.Y -> asmgen.out(" sty ${C64Zeropage.SCRATCH_B1}")
|
CpuRegister.Y -> asmgen.out(" tya")
|
||||||
}
|
}
|
||||||
asmgen.out("""
|
asmgen.out(" ldy ${asmgen.asmIdentifierName(index)} | sta ${target.asmVarname},y")
|
||||||
lda ${asmgen.asmIdentifierName(index)}
|
|
||||||
tay
|
|
||||||
lda ${C64Zeropage.SCRATCH_B1}
|
|
||||||
sta ${target.asmVarname},y
|
|
||||||
""")
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.saveRegister(register)
|
asmgen.saveRegister(register)
|
||||||
@ -396,8 +517,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
throw AssemblyError("no asm gen for assign word $word to memory ${target.memory}")
|
throw AssemblyError("no asm gen for assign word $word to memory ${target.memory}")
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
|
// TODO optimize this, but the situation doesn't occur very often
|
||||||
// if(target.constArrayIndexValue!=null) {
|
// if(target.constArrayIndexValue!=null) {
|
||||||
// TODO("const index ${target.constArrayIndexValue}")
|
// TODO("const index ${target.constArrayIndexValue}")
|
||||||
|
// } else if(target.array!!.arrayspec.index is IdentifierReference) {
|
||||||
|
// TODO("array[var] ${target.constArrayIndexValue}")
|
||||||
// }
|
// }
|
||||||
val index = target.array!!.arrayspec.index
|
val index = target.array!!.arrayspec.index
|
||||||
asmgen.translateExpression(index)
|
asmgen.translateExpression(index)
|
||||||
@ -420,23 +544,32 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
private fun assignConstantByte(target: AsmAssignTarget, byte: Short) {
|
private fun assignConstantByte(target: AsmAssignTarget, byte: Short) {
|
||||||
when(target.kind) {
|
when(target.kind) {
|
||||||
TargetStorageKind.VARIABLE -> {
|
TargetStorageKind.VARIABLE -> {
|
||||||
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname} ")
|
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname} ")
|
||||||
}
|
}
|
||||||
TargetStorageKind.MEMORY -> {
|
TargetStorageKind.MEMORY -> {
|
||||||
storeByteViaRegisterAInMemoryAddress("#${byte.toHex()}", target.memory!!)
|
storeByteViaRegisterAInMemoryAddress("#${byte.toHex()}", target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
// if(target.constArrayIndexValue!=null) {
|
|
||||||
// TODO("const index ${target.constArrayIndexValue}")
|
|
||||||
// }
|
|
||||||
val index = target.array!!.arrayspec.index
|
val index = target.array!!.arrayspec.index
|
||||||
asmgen.translateExpression(index)
|
when {
|
||||||
asmgen.out("""
|
target.constArrayIndexValue!=null -> {
|
||||||
inx
|
val indexValue = target.constArrayIndexValue!!
|
||||||
ldy $ESTACK_LO_HEX,x
|
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname}+$indexValue")
|
||||||
lda #${byte.toHex()}
|
}
|
||||||
sta ${target.asmVarname},y
|
index is IdentifierReference -> {
|
||||||
""")
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UBYTE, CpuRegister.Y)
|
||||||
|
asmgen.out(" lda #<${byte.toHex()} | sta ${target.asmVarname},y | lda #>${byte.toHex()} | sta ${target.asmVarname}+1,y")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
asmgen.translateExpression(index)
|
||||||
|
asmgen.out("""
|
||||||
|
inx
|
||||||
|
ldy $ESTACK_LO_HEX,x
|
||||||
|
lda #${byte.toHex()}
|
||||||
|
sta ${target.asmVarname},y
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("no asm gen for assign byte $byte to $target")
|
else -> throw AssemblyError("no asm gen for assign byte $byte to $target")
|
||||||
}
|
}
|
||||||
@ -457,8 +590,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
|
// TODO optimize this, but the situation doesn't occur very often
|
||||||
// if(target.constArrayIndexValue!=null) {
|
// if(target.constArrayIndexValue!=null) {
|
||||||
// TODO("const index ${target.constArrayIndexValue}")
|
// TODO("const index ${target.constArrayIndexValue}")
|
||||||
|
// } else if(target.array!!.arrayspec.index is IdentifierReference) {
|
||||||
|
// TODO("array[var] ${target.constArrayIndexValue}")
|
||||||
// }
|
// }
|
||||||
val index = target.array!!.arrayspec.index
|
val index = target.array!!.arrayspec.index
|
||||||
if (index is NumericLiteralValue) {
|
if (index is NumericLiteralValue) {
|
||||||
@ -503,8 +639,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
|
// TODO optimize this, but the situation doesn't occur very often
|
||||||
// if(target.constArrayIndexValue!=null) {
|
// if(target.constArrayIndexValue!=null) {
|
||||||
// TODO("const index ${target.constArrayIndexValue}")
|
// TODO("const index ${target.constArrayIndexValue}")
|
||||||
|
// } else if(target.array!!.arrayspec.index is IdentifierReference) {
|
||||||
|
// TODO("array[var] ${target.constArrayIndexValue}")
|
||||||
// }
|
// }
|
||||||
val index = target.array!!.arrayspec.index
|
val index = target.array!!.arrayspec.index
|
||||||
val arrayVarName = target.asmVarname
|
val arrayVarName = target.asmVarname
|
||||||
|
@ -11,11 +11,17 @@ main {
|
|||||||
uword[] array=[1111 ,2222,3333]
|
uword[] array=[1111 ,2222,3333]
|
||||||
float[] farr = [1.111, 2.222, 3.333]
|
float[] farr = [1.111, 2.222, 3.333]
|
||||||
|
|
||||||
|
ubyte ub
|
||||||
|
uword uw
|
||||||
float ff
|
float ff
|
||||||
ubyte i = 1
|
ubyte i = 1
|
||||||
|
|
||||||
farr[2] = farr[i]
|
arr1[i] = ub
|
||||||
c64flt.print_f(farr[2])
|
array[i] = uw
|
||||||
|
farr[2] = 3.15
|
||||||
|
farr[2] = ff
|
||||||
|
farr[i] = ff
|
||||||
|
c64flt.print_f(farr[1])
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
; c64scr.print_ub(arr1[1])
|
; c64scr.print_ub(arr1[1])
|
||||||
|
Loading…
Reference in New Issue
Block a user