mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
fix IR loader for romsub calls (calls to an address)
This commit is contained in:
parent
f570b70827
commit
f9200a2b75
@ -1,13 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- fix IR loading of romsubs
|
||||
romsub $FFD2 = chrout(ubyte ch @ A)
|
||||
sub start() {
|
||||
ubyte ch = '\n'
|
||||
chrout(ch)
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
|
||||
|
@ -2,10 +2,9 @@
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
|
||||
romsub $FFD2 = chrout(ubyte ch @ A)
|
||||
sub start() {
|
||||
ubyte ch = '\n'
|
||||
ubyte ch = '2'
|
||||
chrout(ch)
|
||||
}
|
||||
}
|
||||
|
@ -138,9 +138,14 @@ class IRProgram(val name: String,
|
||||
|
||||
// link all jump and branching instructions to their target
|
||||
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) {
|
||||
if(it.labelSymbol.startsWith('$') || it.labelSymbol.first().isDigit()) {
|
||||
// it's a call to an address (romsub most likely)
|
||||
require(it.address!=null)
|
||||
} else {
|
||||
it.branchTarget = labeledChunks.getValue(it.labelSymbol)
|
||||
// note: branches with an address value cannot be linked to something...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is IRInlineAsmChunk -> {
|
||||
@ -199,7 +204,8 @@ class IRProgram(val name: String,
|
||||
require(!chunk.isIR) { "inline IR-asm should have been converted into regular code chunk"}
|
||||
}
|
||||
chunk.instructions.forEach {
|
||||
if(it.labelSymbol!=null && it.opcode in OpcodesThatBranch)
|
||||
if(it.labelSymbol!=null && it.opcode in OpcodesThatBranch) {
|
||||
if(!it.labelSymbol.startsWith('$') && !it.labelSymbol.first().isDigit())
|
||||
require(it.branchTarget != null) { "branching instruction to label should have branchTarget set" }
|
||||
}
|
||||
}
|
||||
@ -207,6 +213,7 @@ class IRProgram(val name: String,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun registersUsed(): RegistersUsed {
|
||||
val readRegsCounts = mutableMapOf<Int, Int>().withDefault { 0 }
|
||||
|
@ -131,11 +131,11 @@ fun parseIRCodeLine(line: String): Either<IRInstruction, String> {
|
||||
}
|
||||
if(format.sysCall) {
|
||||
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)))
|
||||
} else if (format.funcCall) {
|
||||
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 {
|
||||
operands.forEach { oper ->
|
||||
if (oper[0] == '&')
|
||||
@ -222,7 +222,8 @@ fun parseIRCodeLine(line: String): Either<IRInstruction, String> {
|
||||
}
|
||||
|
||||
private class ParsedCall(
|
||||
val target: String,
|
||||
val target: String?,
|
||||
val address: Int?,
|
||||
val args: List<FunctionCallArgs.ArgumentSpec>,
|
||||
val returns: FunctionCallArgs.RegSpec?
|
||||
)
|
||||
@ -266,8 +267,17 @@ private fun parseCall(rest: String): ParsedCall {
|
||||
val args = match.groups["arglist"]!!.value
|
||||
val arguments = parseArgs(args)
|
||||
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(
|
||||
target,
|
||||
actualTarget,
|
||||
address,
|
||||
arguments,
|
||||
if(returns==null) null else parseRegspec(returns)
|
||||
)
|
||||
|
@ -179,7 +179,7 @@ class VmProgramLoader {
|
||||
if(arg.address!=null)
|
||||
arg
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user