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 NumericLiteralValue -> 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 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")
}
private fun translateExpression(expression: FunctionCall) {
private fun translateFunctionCallResultOntoStack(expression: FunctionCall) {
val functionName = expression.target.nameInSource.last()
val builtinFunc = BuiltinFunctions[functionName]
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 FunctionCall -> {
if(value.target.targetSubroutine(program.namespace)?.isAsmSubroutine==true) {
// TODO handle asmsub functioncalls specifically, without shoving stuff on the estack
asmgen.translateExpression(value)
assignStackValue(assign.target)
val sub = value.target.targetSubroutine(program.namespace)
if(sub!=null && sub.asmReturnvaluesRegisters.any { it.statusflag != null }) {
// the expression translation will have generated a 'php' instruction earlier.
asmgen.out(" plp\t; restore status flags from call")
// handle asmsub functioncalls specifically, without shoving stuff on the estack
val sub = value.target.targetSubroutine(program.namespace)!!
val preserveStatusRegisterAfterCall = sub.asmReturnvaluesRegisters.any { it.statusflag != null }
asmgen.translateFunctionCall(value, preserveStatusRegisterAfterCall)
when((sub.asmReturnvaluesRegisters.single { it.registerOrPair!=null }).registerOrPair) {
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A)
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 {
// regular subroutine, return values are (for now) always done via the stack... TODO optimize this
asmgen.translateExpression(value)

View File

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