mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
fix RTS-issue with inlined return statement
This commit is contained in:
parent
02e12d8575
commit
8e26e38ecc
@ -1272,7 +1272,7 @@ $label nop""")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(ret: Return) {
|
internal fun translate(ret: Return, withRts: Boolean=true) {
|
||||||
ret.value?.let { returnvalue ->
|
ret.value?.let { returnvalue ->
|
||||||
val sub = ret.definingSubroutine()!!
|
val sub = ret.definingSubroutine()!!
|
||||||
val returnType = sub.returntypes.single()
|
val returnType = sub.returntypes.single()
|
||||||
@ -1291,7 +1291,9 @@ $label nop""")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out(" rts")
|
|
||||||
|
if(withRts)
|
||||||
|
out(" rts")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(asm: InlineAssembly) {
|
private fun translate(asm: InlineAssembly) {
|
||||||
|
@ -114,14 +114,23 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
if(!sub.inline || !asmgen.options.optimize) {
|
if(!sub.inline || !asmgen.options.optimize) {
|
||||||
asmgen.out(" jsr $subName")
|
asmgen.out(" jsr $subName")
|
||||||
} else {
|
} else {
|
||||||
// inline the subroutine
|
// inline the subroutine.
|
||||||
|
// we do this by copying the subroutine's statements at the call site.
|
||||||
|
// NOTE: *if* there is a return statement, it will be the only one, and the very last statement of the subroutine
|
||||||
|
// (this condition has been enforced by an ast check earlier)
|
||||||
if(sub.containsDefinedVariables())
|
if(sub.containsDefinedVariables())
|
||||||
throw AssemblyError("can't inline sub with vars")
|
throw AssemblyError("can't inline sub with vars")
|
||||||
if(!sub.isAsmSubroutine && sub.parameters.isNotEmpty())
|
if(!sub.isAsmSubroutine && sub.parameters.isNotEmpty())
|
||||||
throw AssemblyError("can't inline a non-asm subroutine with parameters")
|
throw AssemblyError("can't inline a non-asm subroutine with parameters")
|
||||||
asmgen.out(" \t; inlined routine follows: ${sub.name} from ${sub.position}")
|
asmgen.out(" \t; inlined routine follows: ${sub.name} from ${sub.position}")
|
||||||
val statements = sub.statements.filter { it !is ParameterVarDecl && it !is Directive }
|
val statements = sub.statements.filter { it !is ParameterVarDecl && it !is Directive }
|
||||||
statements.forEach { asmgen.translate(it) }
|
statements.forEach {
|
||||||
|
if(it is Return) {
|
||||||
|
asmgen.translate(it, false) // don't use RTS for the inlined return statement
|
||||||
|
} else {
|
||||||
|
asmgen.translate(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remember: dealing with the X register and/or dealing with return values is the responsibility of the caller
|
// remember: dealing with the X register and/or dealing with return values is the responsibility of the caller
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- fix inlining issue with return statement inlined literally at call site
|
|
||||||
|
|
||||||
- allow inlining of subroutines with vardecls
|
- allow inlining of subroutines with vardecls
|
||||||
- optimize several inner loops in gfx2
|
- optimize several inner loops in gfx2
|
||||||
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
|
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
|
||||||
|
Loading…
Reference in New Issue
Block a user