From 109e118aba525efd8acb8f261d17d1346e9ddf99 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 3 Feb 2023 00:27:50 +0100 Subject: [PATCH] fix sub return register --- .../src/prog8/codegen/cpu6502/AsmGen.kt | 2 +- .../codegen/cpu6502/ExpressionsAsmGen.kt | 2 +- .../src/prog8/codegen/cpu6502/Extensions.kt | 15 ++++++-- .../codegen/cpu6502/FunctionCallAsmGen.kt | 6 ++-- .../cpu6502/assignment/AsmAssignment.kt | 2 +- .../cpu6502/assignment/AssignmentAsmGen.kt | 2 +- examples/test.p8 | 35 ++++++++++--------- 7 files changed, 38 insertions(+), 26 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 6000abb74..9f6048848 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -835,7 +835,7 @@ $repeatLabel lda $counterVar private fun translate(ret: PtReturn, withRts: Boolean=true) { ret.value?.let { returnvalue -> val sub = ret.definingSub()!! - val returnReg = RegisterOrStatusflag(RegisterOrPair.A, null) // TODO("what is returnReg of the sub?") + val returnReg = sub.returnRegister()!! when (sub.returntype) { in NumericDatatypes -> { assignExpressionToRegister(returnvalue, returnReg.registerOrPair!!) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt index fc903f326..774a4b5c6 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt @@ -44,7 +44,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram, private fun translateFunctionCallResultOntoStack(call: PtFunctionCall) { // only for use in nested expression evaluation - val sub = call.targetSubroutine(program)!! + val sub = call.targetSubroutine(program) asmgen.saveXbeforeCall(call) asmgen.translateFunctionCall(call, true) if(sub.regXasResult()) { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/Extensions.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/Extensions.kt index 8279bd7e9..0bc10496c 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/Extensions.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/Extensions.kt @@ -66,6 +66,7 @@ internal fun PtIdentifier.targetStatement(program: PtProgram): PtNode { } internal fun PtProgram.lookup(name: String): PtNode { + // TODO should be cached? fun searchLocalSymbol(node: PtNode, namePart: String): PtNode? { when(node) { is PtProgram -> { @@ -131,8 +132,8 @@ internal fun PtAsmSub.shouldKeepA(): KeepAresult { return KeepAresult(false, saveAonReturn) } -internal fun PtFunctionCall.targetSubroutine(program: PtProgram): IPtSubroutine? = - this.targetStatement(program) as? IPtSubroutine +internal fun PtFunctionCall.targetSubroutine(program: PtProgram): IPtSubroutine = + this.targetStatement(program) as IPtSubroutine internal fun PtFunctionCall.targetStatement(program: PtProgram): PtNode { return if(name in BuiltinFunctions) @@ -185,4 +186,14 @@ internal fun PtExpression.clone(): PtExpression { is PtString -> return withClonedChildrenFrom(this, PtString(value, encoding, position)) is PtTypeCast -> return withClonedChildrenFrom(this, PtTypeCast(type, position)) } +} + +internal fun PtSub.returnRegister(): RegisterOrStatusflag? { + return when(returntype) { + in ByteDatatypes -> RegisterOrStatusflag(RegisterOrPair.A, null) + in WordDatatypes -> RegisterOrStatusflag(RegisterOrPair.AY, null) + DataType.FLOAT -> RegisterOrStatusflag(RegisterOrPair.FAC1, null) + null -> null + else -> RegisterOrStatusflag(RegisterOrPair.AY, null) + } } \ No newline at end of file diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt index 4e76513fa..2a2427010 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/FunctionCallAsmGen.kt @@ -18,7 +18,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as } internal fun saveXbeforeCall(stmt: PtFunctionCall) { - val sub = stmt.targetSubroutine(program) ?: throw AssemblyError("undefined subroutine ${stmt.name}") + val sub = stmt.targetSubroutine(program) if(sub.shouldSaveX()) { if(sub is PtAsmSub) { val regSaveOnStack = sub.address == null // rom-routines don't require registers to be saved on stack, normal subroutines do because they can contain nested calls @@ -32,7 +32,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as } internal fun restoreXafterCall(stmt: PtFunctionCall) { - val sub = stmt.targetSubroutine(program) ?: throw AssemblyError("undefined subroutine ${stmt.name}") + val sub = stmt.targetSubroutine(program) if(sub.shouldSaveX()) { if(sub is PtAsmSub) { val regSaveOnStack = sub.address == null // rom-routines don't require registers to be saved on stack, normal subroutines do because they can contain nested calls @@ -55,7 +55,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as // NOTE: does NOT output code to save/restore the X register for this call! Every caller should deal with this in their own way!! // (you can use subroutine.shouldSaveX() and saveX()/restoreX() routines as a help for this) - val sub: IPtSubroutine = call.targetSubroutine(program) ?: throw AssemblyError("undefined subroutine ${call.name}") + val sub: IPtSubroutine = call.targetSubroutine(program) val subAsmName = asmgen.asmSymbolName(call.name) if(sub is PtAsmSub) { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt index 9bccc89d0..26a309f24 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AsmAssignment.kt @@ -158,7 +158,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind, AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, value.type, expression = value) } is PtFunctionCall -> { - val sub = value.targetSubroutine(program)!! + val sub = value.targetSubroutine(program) val returnType = sub.returnsWhatWhere().firstOrNull { rr -> rr.second.registerOrPair != null || rr.second.statusflag!=null }?.first ?: throw AssemblyError("can't translate zero return values in assignment") diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index b02ce997b..73314612d 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -178,7 +178,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, is PtMemoryByte -> throw AssemblyError("source kind should have been memory") is PtTypeCast -> assignTypeCastedValue(assign.target, value.type, value.value, value) is PtFunctionCall -> { - val sub = value.targetSubroutine(program)!! + val sub = value.targetSubroutine(program) asmgen.saveXbeforeCall(value) asmgen.translateFunctionCall(value, true) val returnValue = sub.returnsWhatWhere().singleOrNull() { it.second.registerOrPair!=null } ?: sub.returnsWhatWhere().single() { it.second.statusflag!=null } diff --git a/examples/test.p8 b/examples/test.p8 index c7c329b1e..4f0ad75cc 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,22 +1,23 @@ -%import textio -%option no_sysinit -%zeropage basicsafe - main { sub start() { - rsavex() - - ubyte @shared ub - main.normalfoo.arg=99 - void normalfoo(42) -somelabel: - ub++ - txt.print_ub(ub) - } - - sub normalfoo(ubyte arg) -> ubyte { - arg++ - return 42 + testscope.duplicate() + cx16.r0L = testscope.duplicate2() + } +} + +testscope { + + sub sub1() { + ubyte @shared duplicate + ubyte @shared duplicate2 + } + + sub duplicate() { + ; do nothing + } + + sub duplicate2() -> ubyte { + return cx16.r0L } }