astchecker is smarter in detecting rts in inline assembly

This commit is contained in:
Irmen de Jong 2021-12-05 21:28:31 +01:00
parent b6fe40ada4
commit edffe92a24
4 changed files with 22 additions and 11 deletions

View File

@ -217,7 +217,7 @@ internal class AstChecker(private val program: Program,
super.visit(label)
}
private fun hasReturnOrJump(scope: IStatementContainer): Boolean {
private fun hasReturnOrJumpOrRts(scope: IStatementContainer): Boolean {
class Searcher: IAstVisitor
{
var count=0
@ -229,6 +229,13 @@ internal class AstChecker(private val program: Program,
if(!jump.isGosub)
count++
}
override fun visit(inlineAssembly: InlineAssembly) {
val assembly = inlineAssembly.assembly
if(" rti" in assembly || "\trti" in assembly || " rts" in assembly || "\trts" in assembly ||
" jmp" in assembly || "\tjmp" in assembly || " bra" in assembly || "\tbra" in assembly )
count++
}
}
val s=Searcher()
@ -262,13 +269,11 @@ internal class AstChecker(private val program: Program,
// subroutine must contain at least one 'return' or 'goto'
// (or if it has an asm block, that must contain a 'rts' or 'jmp' or 'bra')
if(!hasReturnOrJump(subroutine)) {
if (subroutine.amountOfRtsInAsm() == 0) {
if (subroutine.returntypes.isNotEmpty()) {
// for asm subroutines with an address, no statement check is possible.
if (subroutine.asmAddress == null && !subroutine.inline)
err("non-inline subroutine has result value(s) and thus must have at least one 'return' or 'goto' in it (or rts/jmp/bra in case of %asm)")
}
if(!hasReturnOrJumpOrRts(subroutine)) {
if (subroutine.returntypes.isNotEmpty()) {
// for asm subroutines with an address, no statement check is possible.
if (subroutine.asmAddress == null && !subroutine.inline)
err("non-inline subroutine has result value(s) and thus must have at least one 'return' or 'goto' in it (or rts/jmp/bra in case of %asm)")
}
}

View File

@ -706,12 +706,11 @@ class Subroutine(override val name: String,
return KeepAresult(false, saveAonReturn)
}
// TODO fix this to also look in asm nodes in subscopes
fun amountOfRtsInAsm(): Int = statements
.asSequence()
.filter { it is InlineAssembly }
.map { (it as InlineAssembly).assembly }
.count { " rti" in it || "\trti" in it || " rts" in it || "\trts" in it || " jmp" in it || "\tjmp" in it || " bra" in it || "\tbra" in it}
.count { " rti" in it || "\trti" in it || " rts" in it || "\trts" in it || " jmp" in it || "\tjmp" in it || " bra" in it || "\tbra" in it }
// code to provide the ability to reference asmsub parameters via qualified name:

View File

@ -3,7 +3,6 @@ TODO
For next compiler release (7.5)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- fix: amountOfRtsInAsm() look in subscopes too
- fix: when statements generate unneeded branches to choice_end?

View File

@ -6,4 +6,12 @@ main {
sub start() {
ubyte @shared bb = @(cx16.r0)
}
sub count() -> ubyte {
repeat {
%asm {{
rts
}}
}
}
}