optimized code for processing return values from asmsubs without intermediate estack.

This commit is contained in:
Irmen de Jong 2020-10-07 00:51:57 +02:00
parent 71fd98e39e
commit 3e181362dd
3 changed files with 17 additions and 12 deletions

View File

@ -22,7 +22,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
is DirectMemoryRead -> translateDirectMemReadExpression(expression, true) is DirectMemoryRead -> translateDirectMemReadExpression(expression, true)
is NumericLiteralValue -> translateExpression(expression) is NumericLiteralValue -> translateExpression(expression)
is IdentifierReference -> translateExpression(expression) is IdentifierReference -> translateExpression(expression)
is FunctionCall -> translateExpression(expression) is FunctionCall -> translateFunctionCallResultOntoStack(expression)
is ArrayLiteralValue, is StringLiteralValue -> throw AssemblyError("no asm gen for string/array literal value assignment - should have been replaced by a variable") is ArrayLiteralValue, is StringLiteralValue -> throw AssemblyError("no asm gen for string/array literal value assignment - should have been replaced by a variable")
is RangeExpr -> throw AssemblyError("range expression should have been changed into array values") is RangeExpr -> throw AssemblyError("range expression should have been changed into array values")
} }
@ -942,7 +942,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
asmgen.out(" jsr floats.notequal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel") asmgen.out(" jsr floats.notequal_f | inx | lda P8ESTACK_LO,x | beq $jumpIfFalseLabel")
} }
private fun translateExpression(expression: FunctionCall) { private fun translateFunctionCallResultOntoStack(expression: FunctionCall) {
val functionName = expression.target.nameInSource.last() val functionName = expression.target.nameInSource.last()
val builtinFunc = BuiltinFunctions[functionName] val builtinFunc = BuiltinFunctions[functionName]
if (builtinFunc != null) { if (builtinFunc != null) {

View File

@ -125,14 +125,18 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
is TypecastExpression -> assignTypeCastedValue(assign.target, value.type, value.expression, assign) is TypecastExpression -> assignTypeCastedValue(assign.target, value.type, value.expression, assign)
is FunctionCall -> { is FunctionCall -> {
if(value.target.targetSubroutine(program.namespace)?.isAsmSubroutine==true) { if(value.target.targetSubroutine(program.namespace)?.isAsmSubroutine==true) {
// TODO handle asmsub functioncalls specifically, without shoving stuff on the estack // handle asmsub functioncalls specifically, without shoving stuff on the estack
asmgen.translateExpression(value) val sub = value.target.targetSubroutine(program.namespace)!!
assignStackValue(assign.target) val preserveStatusRegisterAfterCall = sub.asmReturnvaluesRegisters.any { it.statusflag != null }
val sub = value.target.targetSubroutine(program.namespace) asmgen.translateFunctionCall(value, preserveStatusRegisterAfterCall)
if(sub!=null && sub.asmReturnvaluesRegisters.any { it.statusflag != null }) { when((sub.asmReturnvaluesRegisters.single { it.registerOrPair!=null }).registerOrPair) {
// the expression translation will have generated a 'php' instruction earlier. RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A)
asmgen.out(" plp\t; restore status flags from call") RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X)
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y)
else -> throw AssemblyError("should be just one register byte result value")
} }
if(preserveStatusRegisterAfterCall)
asmgen.out(" plp\t; restore status flags from call")
} else { } else {
// regular subroutine, return values are (for now) always done via the stack... TODO optimize this // regular subroutine, return values are (for now) always done via the stack... TODO optimize this
asmgen.translateExpression(value) asmgen.translateExpression(value)

View File

@ -18,12 +18,13 @@ main {
return return
; ; TODO make this work as well, with the same warning: ; TODO make this work as well, with the same warning:
; ubyte status2 = c64.OPEN() ; open 1,8,0,"$" ubyte status2 = c64.OPEN() ; open 1,8,0,"$"
if_cs if_cs
return return
txt.print_ub(status)
txt.print_ub(status2)
txt.print(planet_name) txt.print(planet_name)
txt.chrout('\n') txt.chrout('\n')