mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
optimizing assigning an array value to a var
This commit is contained in:
parent
8136f3df5c
commit
125f6205f2
@ -68,12 +68,18 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
// constant array index value
|
// constant array index value
|
||||||
val indexValue = value.indexer.constIndex()!! * elementDt.memorySize()
|
val indexValue = value.indexer.constIndex()!! * elementDt.memorySize()
|
||||||
when (elementDt) {
|
when (elementDt) {
|
||||||
in ByteDatatypes ->
|
in ByteDatatypes -> {
|
||||||
asmgen.out(" lda $arrayVarName+$indexValue | sta P8ESTACK_LO,x | dex")
|
asmgen.out(" lda $arrayVarName+$indexValue")
|
||||||
in WordDatatypes ->
|
assignRegisterByte(assign.target, CpuRegister.A)
|
||||||
asmgen.out(" lda $arrayVarName+$indexValue | sta P8ESTACK_LO,x | lda $arrayVarName+$indexValue+1 | sta P8ESTACK_HI,x | dex")
|
}
|
||||||
DataType.FLOAT ->
|
in WordDatatypes -> {
|
||||||
asmgen.out(" lda #<$arrayVarName+$indexValue | ldy #>$arrayVarName+$indexValue | jsr floats.push_float")
|
asmgen.out(" lda $arrayVarName+$indexValue | ldy $arrayVarName+$indexValue+1")
|
||||||
|
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||||
|
}
|
||||||
|
DataType.FLOAT -> {
|
||||||
|
asmgen.out(" lda #<$arrayVarName+$indexValue | ldy #>$arrayVarName+$indexValue")
|
||||||
|
assignFloatFromAY(assign.target)
|
||||||
|
}
|
||||||
else ->
|
else ->
|
||||||
throw AssemblyError("weird array type")
|
throw AssemblyError("weird array type")
|
||||||
}
|
}
|
||||||
@ -81,11 +87,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
when (elementDt) {
|
when (elementDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||||
asmgen.out(" lda $arrayVarName,y | sta P8ESTACK_LO,x | dex")
|
asmgen.out(" lda $arrayVarName,y")
|
||||||
|
assignRegisterByte(assign.target, CpuRegister.A)
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||||
asmgen.out(" lda $arrayVarName,y | sta P8ESTACK_LO,x | lda $arrayVarName+1,y | sta P8ESTACK_HI,x | dex")
|
asmgen.out(" lda $arrayVarName,y | pha | lda $arrayVarName+1,y | tay | pla")
|
||||||
|
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.A)
|
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.A)
|
||||||
@ -95,13 +103,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
adc #<$arrayVarName
|
adc #<$arrayVarName
|
||||||
bcc +
|
bcc +
|
||||||
iny
|
iny
|
||||||
+ jsr floats.push_float""")
|
+""")
|
||||||
|
assignFloatFromAY(assign.target)
|
||||||
}
|
}
|
||||||
else ->
|
else ->
|
||||||
throw AssemblyError("weird array elt type")
|
throw AssemblyError("weird array elt type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assignStackValue(assign.target)
|
|
||||||
}
|
}
|
||||||
SourceStorageKind.MEMORY -> {
|
SourceStorageKind.MEMORY -> {
|
||||||
val value = assign.source.memory!!
|
val value = assign.source.memory!!
|
||||||
@ -726,6 +734,39 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun assignFloatFromAY(target: AsmAssignTarget) {
|
||||||
|
when(target.kind) {
|
||||||
|
TargetStorageKind.VARIABLE -> {
|
||||||
|
asmgen.out("""
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
lda #<${target.asmVarname}
|
||||||
|
ldy #>${target.asmVarname}
|
||||||
|
jsr floats.copy_float""")
|
||||||
|
}
|
||||||
|
TargetStorageKind.ARRAY -> {
|
||||||
|
asmgen.out("""
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
lda #<${target.asmVarname}
|
||||||
|
ldy #>${target.asmVarname}
|
||||||
|
sta P8ZP_SCRATCH_W2
|
||||||
|
sty P8ZP_SCRATCH_W2+1""")
|
||||||
|
if(target.array!!.indexer.indexNum!=null) {
|
||||||
|
val index = target.array.indexer.constIndex()!!
|
||||||
|
asmgen.out(" lda #$index")
|
||||||
|
} else {
|
||||||
|
val asmvarname = asmgen.asmVariableName(target.array.indexer.indexVar!!)
|
||||||
|
asmgen.out(" lda $asmvarname")
|
||||||
|
}
|
||||||
|
asmgen.out(" jsr floats.set_array_float")
|
||||||
|
}
|
||||||
|
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to mem byte")
|
||||||
|
TargetStorageKind.REGISTER -> throw AssemblyError("can't assign float to register")
|
||||||
|
TargetStorageKind.STACK -> asmgen.out(" jsr floats.push_float")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun assignVariableFloat(target: AsmAssignTarget, sourceName: String) {
|
private fun assignVariableFloat(target: AsmAssignTarget, sourceName: String) {
|
||||||
when(target.kind) {
|
when(target.kind) {
|
||||||
TargetStorageKind.VARIABLE -> {
|
TargetStorageKind.VARIABLE -> {
|
||||||
|
@ -184,7 +184,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
else -> {
|
else -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
if(asmgen.options.slowCodegenWarnings)
|
||||||
println("warning: slow stack evaluation used (1): ${memory.addressExpression::class.simpleName} at ${memory.addressExpression.position}") // TODO optimize...
|
println("warning: slow stack evaluation used (1): ${memory.addressExpression::class.simpleName} at ${memory.addressExpression.position}") // TODO optimize...
|
||||||
asmgen.translateExpression(memory.addressExpression) // TODO directly into P8ZP_SCRATCH_W2
|
asmgen.translateExpression(memory.addressExpression) // TODO directly into P8ZP_SCRATCH_W2?
|
||||||
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | sta P8ZP_SCRATCH_B1")
|
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | sta P8ZP_SCRATCH_B1")
|
||||||
val zp = CompilationTarget.instance.machine.zeropage
|
val zp = CompilationTarget.instance.machine.zeropage
|
||||||
when {
|
when {
|
||||||
|
@ -3,8 +3,6 @@ TODO
|
|||||||
====
|
====
|
||||||
|
|
||||||
- check cpu stack consistency in all examples
|
- check cpu stack consistency in all examples
|
||||||
- reduce the amount of translateExpression() calls when the result can be directly assigned to register or variable
|
|
||||||
- cc = xbuf[i] + ybuf[ii] generates unnecessary stack push/pulls (and no slow warning is given for it)
|
|
||||||
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
|
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'
|
||||||
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
- option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging)
|
||||||
- see if we can group some errors together for instance the (now single) errors about unidentified symbols
|
- see if we can group some errors together for instance the (now single) errors about unidentified symbols
|
||||||
|
@ -7,65 +7,40 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
float uw1
|
ubyte[] ubarray = [1,2,3,4]
|
||||||
const float uw2 = 2.2
|
byte[] barray = [1,2,3,4]
|
||||||
|
uword[] uwarray = [1,2,3,4]
|
||||||
|
word[] warray = [1,2,3,4]
|
||||||
|
float[] farray = [1.1,2.2,3.3,4.4]
|
||||||
|
|
||||||
uw1 = 1.1
|
ubyte ub
|
||||||
if uw1<uw2
|
byte bb
|
||||||
txt.chrout('.')
|
uword uw
|
||||||
else
|
word ww
|
||||||
txt.chrout('!')
|
float fl
|
||||||
if uw1<=uw2
|
|
||||||
txt.chrout('.')
|
|
||||||
else
|
|
||||||
txt.chrout('!')
|
|
||||||
if uw1>uw2
|
|
||||||
txt.chrout('!')
|
|
||||||
else
|
|
||||||
txt.chrout('.')
|
|
||||||
|
|
||||||
if uw1>=uw2
|
const ubyte i = 2
|
||||||
txt.chrout('!')
|
const ubyte j = 3
|
||||||
else
|
|
||||||
txt.chrout('.')
|
|
||||||
if uw1==uw2
|
|
||||||
txt.chrout('!')
|
|
||||||
else
|
|
||||||
txt.chrout('.')
|
|
||||||
if uw1!=uw2
|
|
||||||
txt.chrout('.')
|
|
||||||
else
|
|
||||||
txt.chrout('!')
|
|
||||||
|
|
||||||
|
ub = ubarray[i]
|
||||||
|
txt.print_ub(ub)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
txt.chrout(' ')
|
bb = barray[i]
|
||||||
uw1 = 2.2
|
txt.print_b(bb)
|
||||||
|
txt.chrout('\n')
|
||||||
|
|
||||||
if uw1<uw2
|
uw = uwarray[i]
|
||||||
txt.chrout('!')
|
txt.print_uw(uw)
|
||||||
else
|
txt.chrout('\n')
|
||||||
txt.chrout('.')
|
|
||||||
if uw1<=uw2
|
|
||||||
txt.chrout('.')
|
|
||||||
else
|
|
||||||
txt.chrout('!')
|
|
||||||
if uw1>uw2
|
|
||||||
txt.chrout('!')
|
|
||||||
else
|
|
||||||
txt.chrout('.')
|
|
||||||
|
|
||||||
if uw1>=uw2
|
ww = warray[i]
|
||||||
txt.chrout('.')
|
txt.print_w(ww)
|
||||||
else
|
txt.chrout('\n')
|
||||||
txt.chrout('!')
|
|
||||||
if uw1==uw2
|
fl = farray[i]
|
||||||
txt.chrout('.')
|
floats.print_f(fl)
|
||||||
else
|
txt.chrout('\n')
|
||||||
txt.chrout('!')
|
|
||||||
if uw1!=uw2
|
|
||||||
txt.chrout('!')
|
|
||||||
else
|
|
||||||
txt.chrout('.')
|
|
||||||
|
|
||||||
test_stack.test()
|
test_stack.test()
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
Loading…
Reference in New Issue
Block a user