From 97b9c8f320a60a35a3537658e9b00e146995421c Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 12 Sep 2020 18:53:44 +0200 Subject: [PATCH] don't clobber A when trying to save X at functioncall --- .../compiler/target/c64/codegen/AsmGen.kt | 51 ++++++++++--------- .../target/c64/codegen/FunctionCallAsmGen.kt | 4 +- examples/tehtriz.p8 | 1 - examples/test.p8 | 3 +- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index c126be98c..8d91cd64b 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -552,55 +552,60 @@ internal class AsmGen(private val program: Program, internal fun fixNameSymbols(name: String) = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names - internal fun saveRegister(register: CpuRegister, forFuncCall: Boolean = false, dontClobberA: Boolean = false) { + + private val saveRegisterLabels = Stack(); + + internal fun saveRegister(register: CpuRegister, forFuncCall: Boolean = false) { when(register) { CpuRegister.A -> out(" pha") CpuRegister.X -> { - // TODO get rid of REG_X altogheter! replace with sta _save | txa | pha | lda _save + // TODO get rid of REG_X altogether! when { CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" phx") forFuncCall -> { - if(dontClobberA) - out(" sta P8ZP_SCRATCH_REG | txa | pha | lda P8ZP_SCRATCH_REG") - else - out(" txa | pha") + val save = makeLabel("saveX") + saveRegisterLabels.push(save) + out(""" + stx $save + jmp + +$save .byte 0 ++""") } else -> out(" stx P8ZP_SCRATCH_REG_X") } } CpuRegister.Y -> { - when { - CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" phy") - dontClobberA -> out(" sta P8ZP_SCRATCH_REG | tya | pha | lda P8ZP_SCRATCH_REG") - else -> out(" tya | pha") + if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" phy") + else { + val save = makeLabel("saveY") + out(""" + sty $save + jmp + +$save .byte 0 ++""") } } } } - internal fun restoreRegister(register: CpuRegister, forFuncCall: Boolean = false, dontClobberA: Boolean=false) { + internal fun restoreRegister(register: CpuRegister, forFuncCall: Boolean = false) { when(register) { - CpuRegister.A -> { - require(!dontClobberA) - out(" pla") - } + CpuRegister.A -> out(" pla") CpuRegister.X -> { when { CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" plx") forFuncCall -> { - if(dontClobberA) - out(" sta P8ZP_SCRATCH_REG | pla | tax | lda P8ZP_SCRATCH_REG") - else - out(" pla | tax") + val save = saveRegisterLabels.pop() + out(" ldx $save") } else -> out(" ldx P8ZP_SCRATCH_REG_X") } } CpuRegister.Y -> { - when { - CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" ply") - dontClobberA -> out(" sta P8ZP_SCRATCH_REG | pla | tay | lda P8ZP_SCRATCH_REG") - else -> out(" pla | tay") + if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" ply") + else { + val save = saveRegisterLabels.pop() + out(" ldy $save") } } } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt index 2227c0fe5..84afb5af7 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/FunctionCallAsmGen.kt @@ -19,7 +19,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}") val saveX = CpuRegister.X in sub.asmClobbers || sub.regXasResult() || sub.regXasParam() if(saveX) - asmgen.saveRegister(CpuRegister.X, forFuncCall = true, dontClobberA = false) // we only save X for now (required! is the eval stack pointer), screw A and Y... + asmgen.saveRegister(CpuRegister.X, forFuncCall = true) val subName = asmgen.asmSymbolName(stmt.target) if(stmt.args.isNotEmpty()) { @@ -58,7 +58,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg asmgen.out(" jsr $subName") if(saveX) - asmgen.restoreRegister(CpuRegister.X, forFuncCall = true, dontClobberA = false) + asmgen.restoreRegister(CpuRegister.X, forFuncCall = true) } private fun registerArgsViaStackEvaluation(stmt: IFunctionCall, sub: Subroutine) { diff --git a/examples/tehtriz.p8 b/examples/tehtriz.p8 index b00edf84d..bb225a9ae 100644 --- a/examples/tehtriz.p8 +++ b/examples/tehtriz.p8 @@ -248,7 +248,6 @@ waitkey: c64.CHROUT('K') while c64.GETIN()!=133 { - ; TODO FIX THIS, DOESN'T TRIGGER ANYMORE ON F1 ; endless loop until user presses F1 to restart the game } } diff --git a/examples/test.p8 b/examples/test.p8 index db8039cfc..a25869b83 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,5 +1,4 @@ -%target cx16 -%import cx16textio +%import c64textio ;%import c64flt ;%option enable_floats ; %zeropage kernalsafe