mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
optimized in-place memory/pointervar operations some more
This commit is contained in:
parent
344a1b9eb8
commit
2cadb546d5
@ -163,6 +163,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
if(memory.address is PtBinaryExpression && tryOptimizedMemoryInplace(memory.address as PtBinaryExpression, operator, value))
|
||||
return
|
||||
asmgen.assignExpressionToRegister(memory.address, RegisterOrPair.AY, false)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, true)
|
||||
asmgen.saveRegisterStack(CpuRegister.Y, true)
|
||||
@ -474,6 +476,48 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun tryOptimizedMemoryInplace(address: PtBinaryExpression, operator: String, value: AsmAssignSource): Boolean {
|
||||
if(value.datatype !in ByteDatatypes || operator !in "|&^+-")
|
||||
return false
|
||||
val rightTc = address.right as? PtTypeCast
|
||||
val constOffset = (address.right as? PtNumber)?.number?.toInt()
|
||||
if(address.operator=="+" && (address.right.type in ByteDatatypes || (rightTc!=null && rightTc.value.type in ByteDatatypes) || (constOffset!=null && constOffset<256)) ) {
|
||||
if(rightTc!=null)
|
||||
asmgen.assignExpressionToRegister(rightTc.value, RegisterOrPair.A, false)
|
||||
else if(constOffset!=null)
|
||||
asmgen.out(" lda #${constOffset}")
|
||||
else
|
||||
asmgen.assignExpressionToRegister(address.right, RegisterOrPair.A, false)
|
||||
asmgen.out(" pha") // offset on stack
|
||||
val zpPointerVarName: String
|
||||
if(address.left is PtIdentifier && asmgen.isZpVar(address.left as PtIdentifier)) {
|
||||
zpPointerVarName = (address.left as PtIdentifier).name
|
||||
} else {
|
||||
zpPointerVarName = "P8ZP_SCRATCH_W2"
|
||||
asmgen.assignExpressionToRegister(address.left, RegisterOrPair.AY, false)
|
||||
asmgen.out(" sta $zpPointerVarName | sty $zpPointerVarName+1")
|
||||
}
|
||||
// calculate value into A
|
||||
val assignValue = AsmAssignment(value,
|
||||
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UBYTE,
|
||||
address.definingISub(), Position.DUMMY, register = RegisterOrPair.A),
|
||||
program.memsizer, Position.DUMMY)
|
||||
assignmentAsmGen.translateNormalAssignment(assignValue, address.definingISub())
|
||||
asmgen.restoreRegisterStack(CpuRegister.Y, false) // offset into Y
|
||||
when(operator) {
|
||||
"|" -> asmgen.out(" ora ($zpPointerVarName),y")
|
||||
"&" -> asmgen.out(" and ($zpPointerVarName),y")
|
||||
"^" -> asmgen.out(" eor ($zpPointerVarName),y")
|
||||
"+" -> asmgen.out(" clc | adc ($zpPointerVarName),y")
|
||||
"-" -> asmgen.out(" sta P8ZP_SCRATCH_REG | lda ($zpPointerVarName),y | sec | sbc P8ZP_SCRATCH_REG")
|
||||
else -> throw AssemblyError("invalid op")
|
||||
}
|
||||
asmgen.out(" sta ($zpPointerVarName),y")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun inplacemodificationSplitWordWithR0(arrayVar: String, index: Int, operator: String) {
|
||||
when (operator) {
|
||||
"+" -> {
|
||||
|
@ -43,7 +43,6 @@ Compiler:
|
||||
Once new codegen is written that is based on the IR, this point is mostly moot anyway as that will have its own dead code removal on the IR level.
|
||||
- Zig-like try-based error handling where the V flag could indicate error condition? and/or BRK to jump into monitor on failure? (has to set BRK vector for that) But the V flag is also set on certain normal instructions
|
||||
- generate WASM to eventually run prog8 on a browser canvas? Use binaryen toolkit and/or my binaryen kotlin library?
|
||||
- add Vic20 target?
|
||||
- split words arrays all()
|
||||
- split words arrays sort()
|
||||
|
||||
|
@ -11,10 +11,15 @@ main {
|
||||
uword @shared az = $4000
|
||||
ubyte @shared value = 22
|
||||
|
||||
az[20] = 99
|
||||
az[2000] = 99
|
||||
az[value] = 99
|
||||
az[cx16.r0] = 99
|
||||
az[20] |= 99
|
||||
az[21] &= 99
|
||||
az[22] ^= 99
|
||||
az[23] += 99
|
||||
az[24] -= 99
|
||||
; az[2000] |= 99
|
||||
; az[value] |= 99
|
||||
; az[cx16.r0] |= 99
|
||||
|
||||
; cx16.r0L = az[200]
|
||||
; cx16.r1L = az[2000]
|
||||
; cx16.r0L = az[value]
|
||||
|
Loading…
x
Reference in New Issue
Block a user