fix IR loader for romsub calls (calls to an address)

This commit is contained in:
Irmen de Jong 2023-07-02 23:41:15 +02:00
parent f570b70827
commit f9200a2b75
5 changed files with 28 additions and 19 deletions

View File

@ -1,13 +1,6 @@
TODO TODO
==== ====
- fix IR loading of romsubs
romsub $FFD2 = chrout(ubyte ch @ A)
sub start() {
ubyte ch = '\n'
chrout(ch)
}
... ...

View File

@ -2,10 +2,9 @@
%zeropage basicsafe %zeropage basicsafe
main { main {
romsub $FFD2 = chrout(ubyte ch @ A) romsub $FFD2 = chrout(ubyte ch @ A)
sub start() { sub start() {
ubyte ch = '\n' ubyte ch = '2'
chrout(ch) chrout(ch)
} }
} }

View File

@ -138,9 +138,14 @@ class IRProgram(val name: String,
// link all jump and branching instructions to their target // link all jump and branching instructions to their target
chunk.instructions.forEach { chunk.instructions.forEach {
if(it.opcode in OpcodesThatBranch && it.opcode!=Opcode.RETURN && it.opcode!=Opcode.RETURNR && it.labelSymbol!=null) if(it.opcode in OpcodesThatBranch && it.opcode!=Opcode.RETURN && it.opcode!=Opcode.RETURNR && it.labelSymbol!=null) {
it.branchTarget = labeledChunks.getValue(it.labelSymbol) if(it.labelSymbol.startsWith('$') || it.labelSymbol.first().isDigit()) {
// note: branches with an address value cannot be linked to something... // it's a call to an address (romsub most likely)
require(it.address!=null)
} else {
it.branchTarget = labeledChunks.getValue(it.labelSymbol)
}
}
} }
} }
is IRInlineAsmChunk -> { is IRInlineAsmChunk -> {
@ -199,8 +204,10 @@ class IRProgram(val name: String,
require(!chunk.isIR) { "inline IR-asm should have been converted into regular code chunk"} require(!chunk.isIR) { "inline IR-asm should have been converted into regular code chunk"}
} }
chunk.instructions.forEach { chunk.instructions.forEach {
if(it.labelSymbol!=null && it.opcode in OpcodesThatBranch) if(it.labelSymbol!=null && it.opcode in OpcodesThatBranch) {
require(it.branchTarget != null) { "branching instruction to label should have branchTarget set" } if(!it.labelSymbol.startsWith('$') && !it.labelSymbol.first().isDigit())
require(it.branchTarget != null) { "branching instruction to label should have branchTarget set" }
}
} }
} }
} }

View File

@ -131,11 +131,11 @@ fun parseIRCodeLine(line: String): Either<IRInstruction, String> {
} }
if(format.sysCall) { if(format.sysCall) {
val call = parseCall(rest) val call = parseCall(rest)
val syscallNum = parseIRValue(call.target).toInt() val syscallNum = call.address ?: parseIRValue(call.target ?: "").toInt()
return left(IRInstruction(Opcode.SYSCALL, immediate = syscallNum, fcallArgs = FunctionCallArgs(call.args, call.returns))) return left(IRInstruction(Opcode.SYSCALL, immediate = syscallNum, fcallArgs = FunctionCallArgs(call.args, call.returns)))
} else if (format.funcCall) { } else if (format.funcCall) {
val call = parseCall(rest) val call = parseCall(rest)
return left(IRInstruction(Opcode.CALL, labelSymbol = call.target, fcallArgs = FunctionCallArgs(call.args, call.returns))) return left(IRInstruction(Opcode.CALL, address = call.address, labelSymbol = call.target, fcallArgs = FunctionCallArgs(call.args, call.returns)))
} else { } else {
operands.forEach { oper -> operands.forEach { oper ->
if (oper[0] == '&') if (oper[0] == '&')
@ -222,7 +222,8 @@ fun parseIRCodeLine(line: String): Either<IRInstruction, String> {
} }
private class ParsedCall( private class ParsedCall(
val target: String, val target: String?,
val address: Int?,
val args: List<FunctionCallArgs.ArgumentSpec>, val args: List<FunctionCallArgs.ArgumentSpec>,
val returns: FunctionCallArgs.RegSpec? val returns: FunctionCallArgs.RegSpec?
) )
@ -266,8 +267,17 @@ private fun parseCall(rest: String): ParsedCall {
val args = match.groups["arglist"]!!.value val args = match.groups["arglist"]!!.value
val arguments = parseArgs(args) val arguments = parseArgs(args)
val returns = match.groups["returns"]?.value val returns = match.groups["returns"]?.value
var address: Int? = null
var actualTarget: String? = target
if(target.startsWith('$') || target[0].isDigit()) {
address = parseIRValue(target).toInt()
actualTarget = null
}
return ParsedCall( return ParsedCall(
target, actualTarget,
address,
arguments, arguments,
if(returns==null) null else parseRegspec(returns) if(returns==null) null else parseRegspec(returns)
) )

View File

@ -179,7 +179,7 @@ class VmProgramLoader {
if(arg.address!=null) if(arg.address!=null)
arg arg
else { else {
val address = variableAddresses.getValue(ins.labelSymbol + "." + arg.name) val address = ins.address ?: variableAddresses.getValue(ins.labelSymbol + "." + arg.name)
FunctionCallArgs.ArgumentSpec(arg.name, address, arg.reg) FunctionCallArgs.ArgumentSpec(arg.name, address, arg.reg)
} }
} }