mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
fix a few small compiler errors (removing functioncall, removing block, assigning virtual register return value)
This commit is contained in:
parent
f778f08f76
commit
68abda1219
@ -220,9 +220,25 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A)
|
RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A)
|
||||||
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X)
|
RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X)
|
||||||
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y)
|
RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y)
|
||||||
RegisterOrPair.AX -> assignRegisterpairWord(assign.target, RegisterOrPair.AX)
|
RegisterOrPair.AX -> assignVirtualRegister(assign.target, RegisterOrPair.AX)
|
||||||
RegisterOrPair.AY -> assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
RegisterOrPair.AY -> assignVirtualRegister(assign.target, RegisterOrPair.AY)
|
||||||
RegisterOrPair.XY -> assignRegisterpairWord(assign.target, RegisterOrPair.XY)
|
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 -> {
|
else -> {
|
||||||
val sflag = returnValue.second.statusflag
|
val sflag = returnValue.second.statusflag
|
||||||
if(sflag!=null)
|
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 {
|
private fun attemptAssignOptimizedBinexpr(expr: BinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
if(expr.operator in ComparisonOperators) {
|
if(expr.operator in ComparisonOperators) {
|
||||||
if(expr.right.constValue(program)?.number == 0.0) {
|
if(expr.right.constValue(program)?.number == 0.0) {
|
||||||
|
@ -6,10 +6,7 @@ import prog8.ast.Program
|
|||||||
import prog8.ast.base.FatalAstException
|
import prog8.ast.base.FatalAstException
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.maySwapOperandOrder
|
import prog8.ast.maySwapOperandOrder
|
||||||
import prog8.ast.statements.AnonymousScope
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.statements.Assignment
|
|
||||||
import prog8.ast.statements.IfElse
|
|
||||||
import prog8.ast.statements.Jump
|
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package prog8.optimizer
|
package prog8.optimizer
|
||||||
|
|
||||||
import prog8.ast.*
|
import prog8.ast.*
|
||||||
import prog8.ast.base.FatalAstException
|
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.AstWalker
|
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
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,7 +387,8 @@ class StatementOptimizer(private val program: Program,
|
|||||||
|
|
||||||
val returnvalue = returnStmt.value
|
val returnvalue = returnStmt.value
|
||||||
if (returnvalue!=null) {
|
if (returnvalue!=null) {
|
||||||
val dt = returnvalue.inferType(program).getOrElse { throw FatalAstException("invalid dt") }
|
val dt = returnvalue.inferType(program).getOr(DataType.UNDEFINED)
|
||||||
|
if(dt!=DataType.UNDEFINED) {
|
||||||
if (returnvalue is BinaryExpression || (returnvalue is TypecastExpression && !returnvalue.expression.isSimple)) {
|
if (returnvalue is BinaryExpression || (returnvalue is TypecastExpression && !returnvalue.expression.isSimple)) {
|
||||||
// first assign to intermediary variable, then return that
|
// first assign to intermediary variable, then return that
|
||||||
val (returnVarName, _) = program.getTempVar(dt)
|
val (returnVarName, _) = program.getTempVar(dt)
|
||||||
@ -410,6 +402,7 @@ class StatementOptimizer(private val program: Program,
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
@ -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 $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()
|
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)
|
; 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 $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 $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)
|
romsub $ff7a = cmpare(ubyte data @A, ubyte bank @X, ubyte index @Y) clobbers(X)
|
||||||
|
@ -333,16 +333,16 @@ internal class AstChecker(private val program: Program,
|
|||||||
subroutine.returntypes.zip(subroutine.asmReturnvaluesRegisters).forEachIndexed { index, pair ->
|
subroutine.returntypes.zip(subroutine.asmReturnvaluesRegisters).forEachIndexed { index, pair ->
|
||||||
if(pair.second.registerOrPair in arrayOf(RegisterOrPair.A, RegisterOrPair.X, RegisterOrPair.Y)) {
|
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)
|
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
|
if (pair.first != DataType.UWORD && pair.first != DataType.WORD
|
||||||
&& pair.first != DataType.STR && pair.first !in ArrayDatatypes && pair.first != DataType.FLOAT)
|
&& 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) {
|
else if(pair.second.statusflag!=null) {
|
||||||
if (pair.first != DataType.UBYTE)
|
if (pair.first != DataType.UBYTE)
|
||||||
err("return value #${index + 1} should be ubyte")
|
err("return type #${index + 1} should be ubyte")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,16 +33,13 @@ class CallGraph(private val program: Program, private val allowMissingIdentifier
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val usedBlocks: Set<Block> by lazy {
|
private val usedBlocks: Set<Block> by lazy {
|
||||||
val blocksFromSubroutines = usedSubroutines.map { it.definingBlock }
|
|
||||||
val blocksFromLibraries = program.allBlocks.filter { it.isInLibrary }
|
val blocksFromLibraries = program.allBlocks.filter { it.isInLibrary }
|
||||||
val used = mutableSetOf<Block>()
|
val used = mutableSetOf<Block>()
|
||||||
|
|
||||||
allIdentifiersAndTargets.forEach {
|
allIdentifiersAndTargets.forEach {
|
||||||
if(it.key.definingBlock in blocksFromSubroutines) {
|
|
||||||
val target = it.value.definingBlock
|
val target = it.value.definingBlock
|
||||||
used.add(target)
|
used.add(target)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
used + blocksFromLibraries + program.entrypoint.definingBlock
|
used + blocksFromLibraries + program.entrypoint.definingBlock
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
- in a block marked option force_output, make all subroutines in asm using .block rather than .proc
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,26 +1,23 @@
|
|||||||
%import textio
|
%import textio
|
||||||
|
%import diskio
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
str @zp zpstr = "irmen"
|
romsub $5000 = external_command() -> ubyte @R15
|
||||||
ubyte[3] @zp zparr = [1,2,3]
|
ubyte @shared result = external_command()
|
||||||
|
|
||||||
txt.print(zpstr)
|
|
||||||
txt.print_ub(zparr[2])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; sub start2() {
|
||||||
sub start2() {
|
; ubyte[] arr = [1,2,3,4]
|
||||||
ubyte[] arr = [1,2,3,4]
|
; uword pointer
|
||||||
uword pointer
|
; ubyte ix
|
||||||
ubyte ix
|
;
|
||||||
|
; arr[ix] = arr[ix]+1
|
||||||
arr[ix] = arr[ix]+1
|
;
|
||||||
|
;; arr[3] = arr[3]+1
|
||||||
; arr[3] = arr[3]+1
|
;; pointer[3] = pointer[3]+1
|
||||||
; pointer[3] = pointer[3]+1
|
;
|
||||||
|
; txt.print_ub(arr[3])
|
||||||
txt.print_ub(arr[3])
|
; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user