asmsub return value in registers is now put on evalstack, and loopvar sequence numbering

This commit is contained in:
Irmen de Jong 2019-08-07 23:53:47 +02:00
parent 2136db0e61
commit 4862fb7db1
3 changed files with 35 additions and 13 deletions

View File

@ -527,7 +527,10 @@ class AnonymousScope(override var statements: MutableList<Statement>,
override lateinit var parent: Node override lateinit var parent: Node
override val expensiveToInline override val expensiveToInline
get() = statements.any { it.expensiveToInline } get() = statements.any { it.expensiveToInline }
companion object {
private var sequenceNumber = 1 private var sequenceNumber = 1
}
init { init {
name = "<anon-$sequenceNumber>" // make sure it's an invalid soruce code identifier so user source code can never produce it name = "<anon-$sequenceNumber>" // make sure it's an invalid soruce code identifier so user source code can never produce it

View File

@ -227,7 +227,8 @@ internal class AsmGen2(val program: Program,
// This var is not on the ZP yet. Attempt to move it there (if it's not a float, those take up too much space) // This var is not on the ZP yet. Attempt to move it there (if it's not a float, those take up too much space)
if(variable.zeropage != ZeropageWish.NOT_IN_ZEROPAGE && if(variable.zeropage != ZeropageWish.NOT_IN_ZEROPAGE &&
variable.datatype in zeropage.allowedDatatypes variable.datatype in zeropage.allowedDatatypes
&& variable.datatype != DataType.FLOAT) { && variable.datatype != DataType.FLOAT
&& options.zeropage != ZeropageType.DONTUSE) {
try { try {
val address = zeropage.allocate(fullName, variable.datatype, null) val address = zeropage.allocate(fullName, variable.datatype, null)
out("${variable.name} = $address\t; auto zp ${variable.datatype}") out("${variable.name} = $address\t; auto zp ${variable.datatype}")
@ -626,6 +627,8 @@ internal class AsmGen2(val program: Program,
} }
private fun translateSubroutineCall(stmt: IFunctionCall) { private fun translateSubroutineCall(stmt: IFunctionCall) {
// output the code to setup the parameters and perform the actual call
// does NOT output the code to deal with the result values!
val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}") val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}")
if(Register.X in sub.asmClobbers) if(Register.X in sub.asmClobbers)
out(" stx c64.SCRATCH_ZPREGX") // we only save X for now (required! is the eval stack pointer), screw A and Y... out(" stx c64.SCRATCH_ZPREGX") // we only save X for now (required! is the eval stack pointer), screw A and Y...
@ -1754,6 +1757,23 @@ $endLabel""")
builtinFunctionsAsmGen.translateFunctioncallExpression(expression, builtinFunc) builtinFunctionsAsmGen.translateFunctioncallExpression(expression, builtinFunc)
} else { } else {
translateSubroutineCall(expression) translateSubroutineCall(expression)
val sub = expression.target.targetSubroutine(program.namespace)!!
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
for((t, reg) in returns) {
if(!reg.stack) {
// result value in cpu or status registers, put it on the stack
if(reg.registerOrPair!=null) {
when(reg.registerOrPair) {
RegisterOrPair.A -> out(" sta $ESTACK_LO_HEX,x | dex")
RegisterOrPair.Y -> out(" tya | sta $ESTACK_LO_HEX,x | dex")
RegisterOrPair.AY -> out(" sta $ESTACK_LO_HEX,x | tya | sta $ESTACK_HI_HEX,x | dex")
RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY -> throw AssemblyError("can't push X register - use a variable")
}
} else {
TODO("put return value from statusregister on stack $reg")
}
}
}
} }
} }
is ReferenceLiteralValue -> TODO("string/array/struct assignment?") is ReferenceLiteralValue -> TODO("string/array/struct assignment?")

View File

@ -1,20 +1,19 @@
%import c64utils %import c64utils
%import c64lib %import c64lib
%zeropage dontuse
main { main {
sub start() { sub start() {
ending()
} uword uw
sub ending() {
if A uw = c64utils.str2uword("12345")
c64scr.print("bla") c64scr.print_uw(uw)
else { c64.CHROUT('\n')
c64scr.print("bla")
c64scr.print("bla") uw = c64utils.str2uword("11")
} c64scr.print_uw(uw)
c64scr.print("bla") c64.CHROUT('\n')
} }
} }