mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
optimized in-place array element modification to use simpler assignment asm code
This commit is contained in:
parent
83fbf86b1c
commit
d40788adfa
@ -878,7 +878,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignFAC1float(target: AsmAssignTarget) {
|
internal fun assignFAC1float(target: AsmAssignTarget) {
|
||||||
when(target.kind) {
|
when(target.kind) {
|
||||||
TargetStorageKind.VARIABLE -> {
|
TargetStorageKind.VARIABLE -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -1143,7 +1143,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister) {
|
internal fun assignRegisterByte(target: AsmAssignTarget, register: CpuRegister) {
|
||||||
require(target.datatype in ByteDatatypes)
|
require(target.datatype in ByteDatatypes)
|
||||||
when(target.kind) {
|
when(target.kind) {
|
||||||
TargetStorageKind.VARIABLE -> {
|
TargetStorageKind.VARIABLE -> {
|
||||||
@ -1212,7 +1212,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignRegisterpairWord(target: AsmAssignTarget, regs: RegisterOrPair) {
|
internal fun assignRegisterpairWord(target: AsmAssignTarget, regs: RegisterOrPair) {
|
||||||
require(target.datatype in NumericDatatypes)
|
require(target.datatype in NumericDatatypes)
|
||||||
if(target.datatype==DataType.FLOAT)
|
if(target.datatype==DataType.FLOAT)
|
||||||
throw AssemblyError("float value should be from FAC1 not from registerpair memory pointer")
|
throw AssemblyError("float value should be from FAC1 not from registerpair memory pointer")
|
||||||
|
@ -160,7 +160,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
when {
|
when {
|
||||||
valueLv != null -> inplaceModification_byte_litval_to_variable(addr.toHex(), DataType.UBYTE, operator, valueLv.toInt())
|
valueLv != null -> inplaceModification_byte_litval_to_variable(addr.toHex(), DataType.UBYTE, operator, valueLv.toInt())
|
||||||
ident != null -> inplaceModification_byte_variable_to_variable(addr.toHex(), DataType.UBYTE, operator, ident)
|
ident != null -> inplaceModification_byte_variable_to_variable(addr.toHex(), DataType.UBYTE, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
// TODO more specialized code for types such as memory read etc. -> inplaceModification_byte_memread_to_variable()
|
||||||
value is TypecastExpression -> {
|
value is TypecastExpression -> {
|
||||||
if (tryRemoveRedundantCast(value, target, operator)) return
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
inplaceModification_byte_value_to_variable(addr.toHex(), DataType.UBYTE, operator, value)
|
inplaceModification_byte_value_to_variable(addr.toHex(), DataType.UBYTE, operator, value)
|
||||||
@ -173,7 +173,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
when {
|
when {
|
||||||
valueLv != null -> inplaceModification_byte_litval_to_pointer(pointer, operator, valueLv.toInt())
|
valueLv != null -> inplaceModification_byte_litval_to_pointer(pointer, operator, valueLv.toInt())
|
||||||
ident != null -> inplaceModification_byte_variable_to_pointer(pointer, operator, ident)
|
ident != null -> inplaceModification_byte_variable_to_pointer(pointer, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
|
||||||
value is TypecastExpression -> {
|
value is TypecastExpression -> {
|
||||||
if (tryRemoveRedundantCast(value, target, operator)) return
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
inplaceModification_byte_value_to_pointer(pointer, operator, value)
|
inplaceModification_byte_value_to_pointer(pointer, operator, value)
|
||||||
@ -199,9 +198,75 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
if(asmgen.options.slowCodegenWarnings)
|
with(target.array!!.indexer) {
|
||||||
println("*** TODO optimize simple inplace array assignment ${target.array} $operator= $value")
|
when {
|
||||||
assignmentAsmGen.translateNormalAssignment(target.origAssign) // TODO get rid of this fallback for the most common cases here
|
indexNum!=null -> {
|
||||||
|
val targetVarName = "${target.asmVarname} + ${indexNum!!.number.toInt()*target.datatype.memorySize()}"
|
||||||
|
when(target.datatype) {
|
||||||
|
in ByteDatatypes -> {
|
||||||
|
when {
|
||||||
|
valueLv != null -> inplaceModification_byte_litval_to_variable(targetVarName, target.datatype, operator, valueLv.toInt())
|
||||||
|
ident != null -> inplaceModification_byte_variable_to_variable(targetVarName, target.datatype, operator, ident)
|
||||||
|
memread != null -> inplaceModification_byte_memread_to_variable(targetVarName, target.datatype, operator, memread)
|
||||||
|
value is TypecastExpression -> {
|
||||||
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
|
inplaceModification_byte_value_to_variable(targetVarName, target.datatype, operator, value)
|
||||||
|
}
|
||||||
|
else -> inplaceModification_byte_value_to_variable(targetVarName, target.datatype, operator, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in WordDatatypes -> {
|
||||||
|
when {
|
||||||
|
valueLv != null -> inplaceModification_word_litval_to_variable(targetVarName, target.datatype, operator, valueLv.toInt())
|
||||||
|
ident != null -> inplaceModification_word_variable_to_variable(targetVarName, target.datatype, operator, ident)
|
||||||
|
memread != null -> inplaceModification_word_memread_to_variable(targetVarName, target.datatype, operator, memread)
|
||||||
|
value is TypecastExpression -> {
|
||||||
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
|
inplaceModification_word_value_to_variable(targetVarName, target.datatype, operator, value)
|
||||||
|
}
|
||||||
|
else -> inplaceModification_word_value_to_variable(targetVarName, target.datatype, operator, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DataType.FLOAT -> {
|
||||||
|
when {
|
||||||
|
valueLv != null -> inplaceModification_float_litval_to_variable(targetVarName, operator, valueLv.toDouble(), target.scope!!)
|
||||||
|
ident != null -> inplaceModification_float_variable_to_variable(targetVarName, operator, ident, target.scope!!)
|
||||||
|
value is TypecastExpression -> {
|
||||||
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
|
inplaceModification_float_value_to_variable(targetVarName, operator, value, target.scope!!)
|
||||||
|
}
|
||||||
|
else -> inplaceModification_float_value_to_variable(targetVarName, operator, value, target.scope!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird type to do in-place modification on ${target.datatype}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indexVar!=null -> {
|
||||||
|
when(target.datatype) {
|
||||||
|
in ByteDatatypes -> {
|
||||||
|
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.A, null, program, asmgen)
|
||||||
|
val assign = AsmAssignment(target.origAssign.source, tgt, false, value.position)
|
||||||
|
assignmentAsmGen.translateNormalAssignment(assign)
|
||||||
|
assignmentAsmGen.assignRegisterByte(target, CpuRegister.A)
|
||||||
|
}
|
||||||
|
in WordDatatypes -> {
|
||||||
|
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.AY, null, program, asmgen)
|
||||||
|
val assign = AsmAssignment(target.origAssign.source, tgt, false, value.position)
|
||||||
|
assignmentAsmGen.translateNormalAssignment(assign)
|
||||||
|
assignmentAsmGen.assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||||
|
}
|
||||||
|
DataType.FLOAT -> {
|
||||||
|
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.FAC1, null, program, asmgen)
|
||||||
|
val assign = AsmAssignment(target.origAssign.source, tgt, false, value.position)
|
||||||
|
assignmentAsmGen.translateNormalAssignment(assign)
|
||||||
|
assignmentAsmGen.assignFAC1float(target)
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird type to do in-place modification on ${target.datatype}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("indexer expression should have been replaced by auto indexer var")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.REGISTER -> TODO("reg in-place modification")
|
TargetStorageKind.REGISTER -> TODO("reg in-place modification")
|
||||||
TargetStorageKind.STACK -> TODO("stack in-place modification")
|
TargetStorageKind.STACK -> TODO("stack in-place modification")
|
||||||
|
@ -8,15 +8,24 @@ main {
|
|||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
ubyte[] ubarray = [100,200]
|
ubyte[] ubarray = [100,200]
|
||||||
|
uword[] uwarray = [1000, 2000]
|
||||||
|
|
||||||
ubyte index = 0
|
ubyte index = 0
|
||||||
ubarray[index+1] += 13
|
ubarray[index+1] += 13
|
||||||
ubarray[index+1] += 13
|
ubarray[index+1] += 13
|
||||||
ubarray[index+1] += 13
|
ubarray[index+1] += 13
|
||||||
ubarray[index+2] += 13
|
; ubarray[index+2] += 13
|
||||||
|
|
||||||
txt.print_ub(ubarray[1])
|
txt.print_ub(ubarray[1])
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
|
||||||
|
uwarray[index+1] += 13
|
||||||
|
uwarray[index+1] += 13
|
||||||
|
uwarray[index+1] += 13
|
||||||
|
; uwarray[index+2] += 13
|
||||||
|
|
||||||
|
txt.print_uw(uwarray[1])
|
||||||
|
txt.chrout('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
; sub start222() {
|
; sub start222() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user