mirror of
https://github.com/irmen/prog8.git
synced 2025-01-27 10:31:40 +00:00
optimize assignment to memory pointer with fixed byte offset
This commit is contained in:
parent
9f72779cdc
commit
76d54fbe5c
@ -1960,6 +1960,16 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
private fun storeByteViaRegisterAInMemoryAddress(ldaInstructionArg: String, memoryAddress: DirectMemoryWrite) {
|
private fun storeByteViaRegisterAInMemoryAddress(ldaInstructionArg: String, memoryAddress: DirectMemoryWrite) {
|
||||||
val addressExpr = memoryAddress.addressExpression
|
val addressExpr = memoryAddress.addressExpression
|
||||||
val addressLv = addressExpr as? NumericLiteralValue
|
val addressLv = addressExpr as? NumericLiteralValue
|
||||||
|
|
||||||
|
fun storeViaExprEval()
|
||||||
|
{
|
||||||
|
assignExpressionToVariable(addressExpr, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
|
||||||
|
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02)
|
||||||
|
asmgen.out(" lda $ldaInstructionArg | sta (P8ZP_SCRATCH_W2)")
|
||||||
|
else
|
||||||
|
asmgen.out(" lda $ldaInstructionArg | ldy #0 | sta (P8ZP_SCRATCH_W2),y")
|
||||||
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
addressLv != null -> {
|
addressLv != null -> {
|
||||||
asmgen.out(" lda $ldaInstructionArg | sta ${addressLv.number.toHex()}")
|
asmgen.out(" lda $ldaInstructionArg | sta ${addressLv.number.toHex()}")
|
||||||
@ -1967,13 +1977,26 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
addressExpr is IdentifierReference -> {
|
addressExpr is IdentifierReference -> {
|
||||||
asmgen.storeByteIntoPointer(addressExpr, ldaInstructionArg)
|
asmgen.storeByteIntoPointer(addressExpr, ldaInstructionArg)
|
||||||
}
|
}
|
||||||
else -> {
|
addressExpr is BinaryExpression -> {
|
||||||
assignExpressionToVariable(addressExpr, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
|
// try to optimize simple cases like storing value to ptr+1, ptr+2...
|
||||||
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02)
|
var optimized = false
|
||||||
asmgen.out(" lda $ldaInstructionArg | sta (P8ZP_SCRATCH_W2)")
|
if(addressExpr.operator=="+") {
|
||||||
else
|
// we can assume const operand has been moved to the right.
|
||||||
asmgen.out(" lda $ldaInstructionArg | ldy #0 | sta (P8ZP_SCRATCH_W2),y")
|
val constOperand = addressExpr.right.constValue(program)
|
||||||
|
if(constOperand!=null) {
|
||||||
|
val intIndex = constOperand.number.toInt()
|
||||||
|
if(intIndex in 1..255) {
|
||||||
|
assignExpressionToVariable(addressExpr.left, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
|
||||||
|
asmgen.out(" lda $ldaInstructionArg | ldy #${intIndex} | sta (P8ZP_SCRATCH_W2),y")
|
||||||
|
optimized = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!optimized)
|
||||||
|
storeViaExprEval()
|
||||||
}
|
}
|
||||||
|
else -> storeViaExprEval()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1982,6 +2005,18 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
val addressExpr = memoryAddress.addressExpression
|
val addressExpr = memoryAddress.addressExpression
|
||||||
val addressLv = addressExpr as? NumericLiteralValue
|
val addressLv = addressExpr as? NumericLiteralValue
|
||||||
val registerName = register.name.toLowerCase()
|
val registerName = register.name.toLowerCase()
|
||||||
|
|
||||||
|
fun storeViaExprEval()
|
||||||
|
{
|
||||||
|
asmgen.saveRegisterStack(register, false)
|
||||||
|
assignExpressionToVariable(addressExpr, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
|
||||||
|
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
||||||
|
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02)
|
||||||
|
asmgen.out(" sta (P8ZP_SCRATCH_W2)")
|
||||||
|
else
|
||||||
|
asmgen.out(" ldy #0 | sta (P8ZP_SCRATCH_W2),y")
|
||||||
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
addressLv != null -> {
|
addressLv != null -> {
|
||||||
asmgen.out(" st$registerName ${addressLv.number.toHex()}")
|
asmgen.out(" st$registerName ${addressLv.number.toHex()}")
|
||||||
@ -1994,15 +2029,28 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
asmgen.storeByteIntoPointer(addressExpr, null)
|
asmgen.storeByteIntoPointer(addressExpr, null)
|
||||||
}
|
}
|
||||||
else -> {
|
addressExpr is BinaryExpression -> {
|
||||||
asmgen.saveRegisterStack(register, false)
|
// try to optimize simple cases like storing value to ptr+1, ptr+2...
|
||||||
assignExpressionToVariable(addressExpr, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
|
var optimized = false
|
||||||
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
if(addressExpr.operator=="+") {
|
||||||
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02)
|
// we can assume const operand has been moved to the right.
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W2)")
|
val constOperand = addressExpr.right.constValue(program)
|
||||||
else
|
if(constOperand!=null) {
|
||||||
asmgen.out(" ldy #0 | sta (P8ZP_SCRATCH_W2),y")
|
val intIndex = constOperand.number.toInt()
|
||||||
|
if(intIndex in 1..255) {
|
||||||
|
asmgen.saveRegisterStack(register, false)
|
||||||
|
assignExpressionToVariable(addressExpr.left, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
|
||||||
|
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
||||||
|
asmgen.out(" ldy #${intIndex} | sta (P8ZP_SCRATCH_W2),y")
|
||||||
|
optimized = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!optimized)
|
||||||
|
storeViaExprEval()
|
||||||
}
|
}
|
||||||
|
else -> storeViaExprEval()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user