mirror of
				https://github.com/irmen/prog8.git
				synced 2025-10-31 00:16:08 +00:00 
			
		
		
		
	cleaned up some stuff, improved checking of asmsub statement body
This commit is contained in:
		| @@ -144,8 +144,7 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi | ||||
|             // NOTE: | ||||
|             // - numeric types BYTE and WORD and FLOAT are passed by value; | ||||
|             // - strings, arrays, matrices are passed by reference (their 16-bit address is passed as an uword parameter) | ||||
|             // - do NOT do this is the statement can be transformed into an asm subroutine later! | ||||
|             if(subroutine.asmAddress==null && !subroutine.canBeAsmSubroutine) { | ||||
|             if(subroutine.asmAddress==null) { | ||||
|                 if(subroutine.asmParameterRegisters.isEmpty()) { | ||||
|                     subroutine.parameters | ||||
|                             .filter { it.name !in namesInSub } | ||||
| @@ -157,6 +156,10 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi | ||||
|                             } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if(subroutine.isAsmSubroutine && subroutine.statements.any{it !is InlineAssembly}) { | ||||
|                 checkResult.add(SyntaxError("asmsub can only contain inline assembly (%asm)", subroutine.position)) | ||||
|             } | ||||
|         } | ||||
|         return super.visit(subroutine) | ||||
|     } | ||||
|   | ||||
| @@ -1,10 +1,12 @@ | ||||
| package prog8.ast.processing | ||||
|  | ||||
| import prog8.ast.* | ||||
| import prog8.ast.Module | ||||
| import prog8.ast.Program | ||||
| import prog8.ast.base.DataType | ||||
| import prog8.ast.base.FatalAstException | ||||
| import prog8.ast.base.initvarsSubName | ||||
| import prog8.ast.expressions.* | ||||
| import prog8.ast.mangledStructMemberName | ||||
| import prog8.ast.statements.* | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| package prog8.ast.processing | ||||
|  | ||||
| import prog8.ast.* | ||||
| import prog8.ast.IFunctionCall | ||||
| import prog8.ast.INameScope | ||||
| import prog8.ast.Program | ||||
| import prog8.ast.base.DataType | ||||
| import prog8.ast.base.FatalAstException | ||||
| import prog8.ast.base.printWarning | ||||
|   | ||||
| @@ -599,40 +599,6 @@ class Subroutine(override val name: String, | ||||
|             .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 } | ||||
|  | ||||
|     val canBeAsmSubroutine =false // TODO disabled for now, see below about problem with converting to asm subroutine | ||||
| //            !isAsmSubroutine | ||||
| //                    && ((parameters.size == 1 && parameters[0].type in setOf(DataType.BYTE, DataType.UBYTE, DataType.WORD, DataType.UWORD)) | ||||
| //                    || (parameters.size == 2 && parameters.map { it.type }.all { it == DataType.BYTE || it == DataType.UBYTE })) | ||||
|  | ||||
|     fun intoAsmSubroutine(): Subroutine { | ||||
|         // TODO turn subroutine into asm calling convention.   Requires rethinking of how parameters are handled (conflicts with local vardefs now, see AstIdentifierChecker...) | ||||
|         return this // TODO | ||||
|  | ||||
| //        println("TO ASM   $this")  // TODO | ||||
| //        val paramregs = if (parameters.size == 1 && parameters[0].type in setOf(DataType.BYTE, DataType.UBYTE)) | ||||
| //            listOf(RegisterOrStatusflag(RegisterOrPair.Y, null, null)) | ||||
| //        else if (parameters.size == 1 && parameters[0].type in setOf(DataType.WORD, DataType.UWORD)) | ||||
| //            listOf(RegisterOrStatusflag(RegisterOrPair.AY, null, null)) | ||||
| //        else if (parameters.size == 2 && parameters.map { it.type }.all { it == DataType.BYTE || it == DataType.UBYTE }) | ||||
| //            listOf(RegisterOrStatusflag(RegisterOrPair.A, null, null), RegisterOrStatusflag(RegisterOrPair.Y, null, null)) | ||||
| //        else throw FatalAstException("cannot convert subroutine to asm parameters") | ||||
| // | ||||
| //        val asmsub=Subroutine( | ||||
| //                name, | ||||
| //                parameters, | ||||
| //                returntypes, | ||||
| //                paramregs, | ||||
| //                emptyList(), | ||||
| //                emptySet(), | ||||
| //                null, | ||||
| //                true, | ||||
| //                statements, | ||||
| //                position | ||||
| //        ) | ||||
| //        asmsub.linkParents(parent) | ||||
| //        return asmsub | ||||
|     } | ||||
| } | ||||
|  | ||||
| open class SubroutineParameter(val name: String, | ||||
|   | ||||
| @@ -96,7 +96,7 @@ fun compileProgram(filepath: Path, | ||||
|             programAst.checkValid(compilerOptions)          // check if final tree is valid | ||||
|             programAst.checkRecursion()         // check if there are recursive subroutine calls | ||||
|  | ||||
|             printAst(programAst) | ||||
|             // printAst(programAst) | ||||
|  | ||||
|             if(writeAssembly) { | ||||
|                 // asm generation directly from the Ast, no need for intermediate code | ||||
|   | ||||
| @@ -16,9 +16,7 @@ import kotlin.math.floor | ||||
|  | ||||
|  | ||||
| /* | ||||
|     todo: subroutines with 1 or 2 byte args or 1 word arg can be converted to asm sub calling convention (args in registers) | ||||
|     todo analyse for unreachable code and remove that (f.i. code after goto or return that has no label so can never be jumped to) + print warning about this | ||||
|  | ||||
|     TODO: analyse for unreachable code and remove that (f.i. code after goto or return that has no label so can never be jumped to) + print warning about this | ||||
|     TODO: proper inlining of small subroutines (correctly renaming/relocating all variables in them and refs to those as well, or restrict to subs without variables?) | ||||
| */ | ||||
|  | ||||
| @@ -108,11 +106,6 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV | ||||
|             linesToRemove.reversed().forEach{subroutine.statements.removeAt(it)} | ||||
|         } | ||||
|  | ||||
|         if(subroutine.canBeAsmSubroutine) { | ||||
|             optimizationsDone++ | ||||
|             return subroutine.intoAsmSubroutine()   // TODO this doesn't work yet due to parameter vardecl issue | ||||
|         } | ||||
|  | ||||
|         if(subroutine !in callgraph.usedSymbols && !forceOutput) { | ||||
|             printWarning("removing unused subroutine '${subroutine.name}'", subroutine.position) | ||||
|             optimizationsDone++ | ||||
|   | ||||
| @@ -19,17 +19,6 @@ these should call optimized pieces of assembly code, so they run as fast as poss | ||||
|  | ||||
| For now, we have the ``memcopy``, ``memset`` and ``strlen`` builtin functions. | ||||
|  | ||||
| Fixes | ||||
| ^^^^^ | ||||
|  | ||||
| fix asmsub parameters so this works:: | ||||
|  | ||||
|       asmsub aa(byte arg @ Y) -> clobbers() -> () { | ||||
|           byte local = arg      ; @todo fix 'undefined symbol arg' that occurs here | ||||
|           A=44 | ||||
|       } | ||||
|  | ||||
|  | ||||
| More optimizations | ||||
| ^^^^^^^^^^^^^^^^^^ | ||||
|  | ||||
| @@ -38,11 +27,6 @@ Add more compiler optimizations to the existing ones. | ||||
| - on the language AST level | ||||
| - on the final assembly source level | ||||
| - can the parameter passing to subroutines be optimized to avoid copying? | ||||
|  | ||||
| - subroutines with 1 or 2 byte args (or 1 word arg) should be converted to asm calling convention with the args in A/Y register | ||||
|   this requires rethinking the way parameters are represented, simply injecting vardecls to | ||||
|   declare local variables for them is not always correct anymore | ||||
|  | ||||
| - working subroutine inlining (taking care of vars and identifier refs to them) | ||||
|  | ||||
| Also some library routines and code patterns could perhaps be optimized further | ||||
|   | ||||
| @@ -27,4 +27,12 @@ main { | ||||
| ;        uw *= 2 | ||||
| ;        ub *= 2 | ||||
|     } | ||||
|  | ||||
|  | ||||
|           asmsub aa(byte arg @ Y) clobbers() { | ||||
|             %asm {{ | ||||
|             rts | ||||
|             }} | ||||
|           } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user