fix register overwriting for certain subroutine call parameter combinations. Fixes #136

This commit is contained in:
Irmen de Jong 2024-07-02 23:16:57 +02:00
parent e7298f8162
commit 43c55b58d2
3 changed files with 13 additions and 9 deletions

View File

@ -583,8 +583,8 @@ private fun optimizeJsrRtsAndOtherCombinations(linesByFour: Sequence<List<Indexe
fun sameLabel(branchInstr: String, jumpInstr: String, labelInstr: String): Boolean { fun sameLabel(branchInstr: String, jumpInstr: String, labelInstr: String): Boolean {
if('(' in jumpInstr) return false // indirect jump cannot be replaced if('(' in jumpInstr) return false // indirect jump cannot be replaced
val label = labelInstr.trimEnd().substringBefore(':').substringBefore(' ').substringBefore('\t') val label = labelInstr.trimEnd().substringBefore(':').substringBefore(' ').substringBefore('\t')
println("label=$label") val branchLabel = branchInstr.trimStart().substring(3).trim()
return true return label==branchLabel
} }
// beq Label + jmp Addr + Label -> bne Addr // beq Label + jmp Addr + Label -> bne Addr

View File

@ -82,7 +82,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
is PtAddressOf -> false is PtAddressOf -> false
is PtIdentifier -> false is PtIdentifier -> false
is PtIrRegister -> false is PtIrRegister -> false
is PtMemoryByte -> return usesOtherRegistersWhileEvaluating(arg.address) is PtMemoryByte -> true // TODO might not actually need extra registers if the value has to end up in A
is PtNumber -> false is PtNumber -> false
is PtBool -> false is PtBool -> false
else -> true else -> true
@ -110,9 +110,9 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
throw AssemblyError("call argument evaluation problem: can't save cpu statusregister parameter ${call.position}") throw AssemblyError("call argument evaluation problem: can't save cpu statusregister parameter ${call.position}")
} }
else { else {
if(usedX()) asmgen.saveRegisterStack(CpuRegister.X, false) if(usedX()) asmgen.saveRegisterStack(CpuRegister.X, usedA())
if(usedY()) asmgen.saveRegisterStack(CpuRegister.Y, false) if(usedY()) asmgen.saveRegisterStack(CpuRegister.Y, usedA())
if(usedA()) asmgen.saveRegisterStack(CpuRegister.A, false) if(usedA()) asmgen.saveRegisterStack(CpuRegister.A, usedA())
val used = argumentViaRegister(sub, IndexedValue(it, param.second), arg) val used = argumentViaRegister(sub, IndexedValue(it, param.second), arg)
if(usedA()) asmgen.restoreRegisterStack(CpuRegister.A, false) if(usedA()) asmgen.restoreRegisterStack(CpuRegister.A, false)
if(usedY()) asmgen.restoreRegisterStack(CpuRegister.Y, true) if(usedY()) asmgen.restoreRegisterStack(CpuRegister.Y, true)

View File

@ -1,9 +1,7 @@
TODO TODO
==== ====
https://github.com/irmen/prog8/issues/136 (string.find register order issue) See open issues on github.
other issues on github.
optimize signed byte/word division by powers of 2 (and shift right?), it's now using divmod routine. (also % ?) optimize signed byte/word division by powers of 2 (and shift right?), it's now using divmod routine. (also % ?)
see inplacemodificationByteVariableWithLiteralval() and inplacemodificationSomeWordWithLiteralval() see inplacemodificationByteVariableWithLiteralval() and inplacemodificationSomeWordWithLiteralval()
@ -30,6 +28,12 @@ optimize signed byte/word division by powers of 2 (and shift right?), it's now u
lda $4 lda $4
Improve register load order in subroutine call args assignments:
in certain situations, the "wrong" order of evaluation of function call arguments is done which results
in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!)
Maybe this routine can be made more intelligent. See usesOtherRegistersWhileEvaluating() and argumentsViaRegisters().
Future Things and Ideas Future Things and Ideas
^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
Compiler: Compiler: