fix a few small compiler errors (removing functioncall, removing block, assigning virtual register return value)

This commit is contained in:
Irmen de Jong 2022-08-09 23:38:29 +02:00
parent f778f08f76
commit 68abda1219
8 changed files with 69 additions and 56 deletions

View File

@ -220,9 +220,25 @@ internal class AssignmentAsmGen(private val program: Program,
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A)
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X)
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y)
RegisterOrPair.AX -> assignRegisterpairWord(assign.target, RegisterOrPair.AX)
RegisterOrPair.AY -> assignRegisterpairWord(assign.target, RegisterOrPair.AY)
RegisterOrPair.XY -> assignRegisterpairWord(assign.target, RegisterOrPair.XY)
RegisterOrPair.AX -> assignVirtualRegister(assign.target, RegisterOrPair.AX)
RegisterOrPair.AY -> assignVirtualRegister(assign.target, RegisterOrPair.AY)
RegisterOrPair.XY -> assignVirtualRegister(assign.target, RegisterOrPair.XY)
RegisterOrPair.R0 -> assignVirtualRegister(assign.target, RegisterOrPair.R0)
RegisterOrPair.R1 -> assignVirtualRegister(assign.target, RegisterOrPair.R1)
RegisterOrPair.R2 -> assignVirtualRegister(assign.target, RegisterOrPair.R2)
RegisterOrPair.R3 -> assignVirtualRegister(assign.target, RegisterOrPair.R3)
RegisterOrPair.R4 -> assignVirtualRegister(assign.target, RegisterOrPair.R4)
RegisterOrPair.R5 -> assignVirtualRegister(assign.target, RegisterOrPair.R5)
RegisterOrPair.R6 -> assignVirtualRegister(assign.target, RegisterOrPair.R6)
RegisterOrPair.R7 -> assignVirtualRegister(assign.target, RegisterOrPair.R7)
RegisterOrPair.R8 -> assignVirtualRegister(assign.target, RegisterOrPair.R8)
RegisterOrPair.R9 -> assignVirtualRegister(assign.target, RegisterOrPair.R9)
RegisterOrPair.R10 -> assignVirtualRegister(assign.target, RegisterOrPair.R10)
RegisterOrPair.R11 -> assignVirtualRegister(assign.target, RegisterOrPair.R11)
RegisterOrPair.R12 -> assignVirtualRegister(assign.target, RegisterOrPair.R12)
RegisterOrPair.R13 -> assignVirtualRegister(assign.target, RegisterOrPair.R13)
RegisterOrPair.R14 -> assignVirtualRegister(assign.target, RegisterOrPair.R14)
RegisterOrPair.R15 -> assignVirtualRegister(assign.target, RegisterOrPair.R15)
else -> {
val sflag = returnValue.second.statusflag
if(sflag!=null)
@ -301,6 +317,17 @@ internal class AssignmentAsmGen(private val program: Program,
}
}
private fun assignVirtualRegister(target: AsmAssignTarget, register: RegisterOrPair) {
when(target.datatype) {
in ByteDatatypes -> {
asmgen.out(" lda cx16.${register.toString().lowercase()}L")
assignRegisterByte(target, CpuRegister.A)
}
in WordDatatypes -> assignRegisterpairWord(target, register)
else -> throw AssemblyError("expected byte or word")
}
}
private fun attemptAssignOptimizedBinexpr(expr: BinaryExpression, assign: AsmAssignment): Boolean {
if(expr.operator in ComparisonOperators) {
if(expr.right.constValue(program)?.number == 0.0) {

View File

@ -6,10 +6,7 @@ import prog8.ast.Program
import prog8.ast.base.FatalAstException
import prog8.ast.expressions.*
import prog8.ast.maySwapOperandOrder
import prog8.ast.statements.AnonymousScope
import prog8.ast.statements.Assignment
import prog8.ast.statements.IfElse
import prog8.ast.statements.Jump
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.code.core.*

View File

@ -1,7 +1,6 @@
package prog8.optimizer
import prog8.ast.*
import prog8.ast.base.FatalAstException
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
@ -74,14 +73,6 @@ class StatementOptimizer(private val program: Program,
}
}
// if the first instruction in the called subroutine is a return statement, remove the jump altogeter
val subroutine = functionCallStatement.target.targetSubroutine(program)
if(subroutine!=null) {
val first = subroutine.statements.asSequence().filterNot { it is VarDecl || it is Directive }.firstOrNull()
if(first is Return)
return listOf(IAstModification.Remove(functionCallStatement, parent as IStatementContainer))
}
return noModifications
}
@ -396,18 +387,20 @@ class StatementOptimizer(private val program: Program,
val returnvalue = returnStmt.value
if (returnvalue!=null) {
val dt = returnvalue.inferType(program).getOrElse { throw FatalAstException("invalid dt") }
if (returnvalue is BinaryExpression || (returnvalue is TypecastExpression && !returnvalue.expression.isSimple)) {
// first assign to intermediary variable, then return that
val (returnVarName, _) = program.getTempVar(dt)
val returnValueIntermediary = IdentifierReference(returnVarName, returnStmt.position)
val tgt = AssignTarget(returnValueIntermediary, null, null, returnStmt.position)
val assign = Assignment(tgt, returnvalue, AssignmentOrigin.OPTIMIZER, returnStmt.position)
val returnReplacement = Return(returnValueIntermediary.copy(), returnStmt.position)
return listOf(
IAstModification.InsertBefore(returnStmt, assign, parent as IStatementContainer),
IAstModification.ReplaceNode(returnStmt, returnReplacement, parent)
)
val dt = returnvalue.inferType(program).getOr(DataType.UNDEFINED)
if(dt!=DataType.UNDEFINED) {
if (returnvalue is BinaryExpression || (returnvalue is TypecastExpression && !returnvalue.expression.isSimple)) {
// first assign to intermediary variable, then return that
val (returnVarName, _) = program.getTempVar(dt)
val returnValueIntermediary = IdentifierReference(returnVarName, returnStmt.position)
val tgt = AssignTarget(returnValueIntermediary, null, null, returnStmt.position)
val assign = Assignment(tgt, returnvalue, AssignmentOrigin.OPTIMIZER, returnStmt.position)
val returnReplacement = Return(returnValueIntermediary.copy(), returnStmt.position)
return listOf(
IAstModification.InsertBefore(returnStmt, assign, parent as IStatementContainer),
IAstModification.ReplaceNode(returnStmt, returnReplacement, parent)
)
}
}
}

View File

@ -306,7 +306,7 @@ romsub $ff5c = lkupsa(ubyte sa @Y) clobbers(A,X,Y)
romsub $ff5f = screen_mode(ubyte mode @A, ubyte getCurrent @Pc) clobbers(A, X, Y) -> ubyte @Pc
romsub $ff62 = screen_set_charset(ubyte charset @A, uword charsetptr @XY) clobbers(A,X,Y) ; incompatible with C128 dlchr()
; not yet supported: romsub $ff65 = pfkey() clobbers(A,X,Y)
romsub $ff6e = jsrfar()
romsub $ff6e = jsrfar() ; following word = address to call, byte after that=rom/ram bank it is in
romsub $ff74 = fetch(ubyte bank @X, ubyte index @Y) clobbers(X) -> ubyte @A
romsub $ff77 = stash(ubyte data @A, ubyte bank @X, ubyte index @Y) clobbers(X)
romsub $ff7a = cmpare(ubyte data @A, ubyte bank @X, ubyte index @Y) clobbers(X)

View File

@ -333,16 +333,16 @@ internal class AstChecker(private val program: Program,
subroutine.returntypes.zip(subroutine.asmReturnvaluesRegisters).forEachIndexed { index, pair ->
if(pair.second.registerOrPair in arrayOf(RegisterOrPair.A, RegisterOrPair.X, RegisterOrPair.Y)) {
if (pair.first != DataType.UBYTE && pair.first != DataType.BYTE && pair.first != DataType.BOOL)
err("return value #${index + 1} should be (u)byte")
err("return type #${index + 1} should be (u)byte")
}
else if(pair.second.registerOrPair in arrayOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY)) {
else if(pair.second.registerOrPair in setOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY)) {
if (pair.first != DataType.UWORD && pair.first != DataType.WORD
&& pair.first != DataType.STR && pair.first !in ArrayDatatypes && pair.first != DataType.FLOAT)
err("return value #${index + 1} should be (u)word/address")
err("return type #${index + 1} should be (u)word/address")
}
else if(pair.second.statusflag!=null) {
if (pair.first != DataType.UBYTE)
err("return value #${index + 1} should be ubyte")
err("return type #${index + 1} should be ubyte")
}
}

View File

@ -33,15 +33,12 @@ class CallGraph(private val program: Program, private val allowMissingIdentifier
}
private val usedBlocks: Set<Block> by lazy {
val blocksFromSubroutines = usedSubroutines.map { it.definingBlock }
val blocksFromLibraries = program.allBlocks.filter { it.isInLibrary }
val used = mutableSetOf<Block>()
allIdentifiersAndTargets.forEach {
if(it.key.definingBlock in blocksFromSubroutines) {
val target = it.value.definingBlock
used.add(target)
}
val target = it.value.definingBlock
used.add(target)
}
used + blocksFromLibraries + program.entrypoint.definingBlock

View File

@ -3,6 +3,8 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- in a block marked option force_output, make all subroutines in asm using .block rather than .proc
...

View File

@ -1,26 +1,23 @@
%import textio
%import diskio
%zeropage basicsafe
main {
sub start() {
str @zp zpstr = "irmen"
ubyte[3] @zp zparr = [1,2,3]
txt.print(zpstr)
txt.print_ub(zparr[2])
romsub $5000 = external_command() -> ubyte @R15
ubyte @shared result = external_command()
}
sub start2() {
ubyte[] arr = [1,2,3,4]
uword pointer
ubyte ix
arr[ix] = arr[ix]+1
; arr[3] = arr[3]+1
; pointer[3] = pointer[3]+1
txt.print_ub(arr[3])
}
; sub start2() {
; ubyte[] arr = [1,2,3,4]
; uword pointer
; ubyte ix
;
; arr[ix] = arr[ix]+1
;
;; arr[3] = arr[3]+1
;; pointer[3] = pointer[3]+1
;
; txt.print_ub(arr[3])
; }
}