mirror of
https://github.com/irmen/prog8.git
synced 2024-09-10 09:54:32 +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
|
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
|
%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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
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)
|
it.branchTarget = labeledChunks.getValue(it.labelSymbol)
|
||||||
// note: branches with an address value cannot be linked to something...
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is IRInlineAsmChunk -> {
|
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"}
|
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) {
|
||||||
|
if(!it.labelSymbol.startsWith('$') && !it.labelSymbol.first().isDigit())
|
||||||
require(it.branchTarget != null) { "branching instruction to label should have branchTarget set" }
|
require(it.branchTarget != null) { "branching instruction to label should have branchTarget set" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,6 +213,7 @@ class IRProgram(val name: String,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun registersUsed(): RegistersUsed {
|
fun registersUsed(): RegistersUsed {
|
||||||
val readRegsCounts = mutableMapOf<Int, Int>().withDefault { 0 }
|
val readRegsCounts = mutableMapOf<Int, Int>().withDefault { 0 }
|
||||||
|
@ -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)
|
||||||
)
|
)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user