mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
ir: fix non-code chunk linkage
This commit is contained in:
parent
224f490455
commit
7cc3cc3990
@ -67,8 +67,12 @@ main {
|
||||
}
|
||||
}"""
|
||||
val target = VMTarget()
|
||||
val result = compileText(target, true, src, writeAssembly = true)!!
|
||||
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
|
||||
var result = compileText(target, false, src, writeAssembly = true)!!
|
||||
var virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
|
||||
VmRunner().runProgram(virtfile.readText())
|
||||
|
||||
result = compileText(target, true, src, writeAssembly = true)!!
|
||||
virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
|
||||
VmRunner().runProgram(virtfile.readText())
|
||||
}
|
||||
|
||||
@ -107,7 +111,7 @@ mylabel_inside:
|
||||
}"""
|
||||
|
||||
val target = VMTarget()
|
||||
val result = compileText(target, true, src, writeAssembly = true)!!
|
||||
val result = compileText(target, false, src, writeAssembly = true)!!
|
||||
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
|
||||
VmRunner().runProgram(virtfile.readText())
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ TODO
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- ir: fix unit tests
|
||||
- ir: join more codechunks
|
||||
- ir: fix removeWeirdBranches in IR optimizer
|
||||
- update diagram in technical.rst?
|
||||
|
||||
|
@ -1,17 +1,20 @@
|
||||
%import textio
|
||||
%import floats
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
float[10] flt
|
||||
|
||||
sub start() {
|
||||
float ff = 9.0
|
||||
flt[1] = 42.42
|
||||
flt[1] = -9.0
|
||||
flt[1] = -ff
|
||||
flt[1] = -flt[1] ; TODO also fix crash when selecting vm target: fpReg1 out of bounds
|
||||
floats.print_f(flt[1])
|
||||
txt.nl()
|
||||
cx16.r0 = 42
|
||||
goto foobar
|
||||
my_label:
|
||||
txt.print_uwhex(cx16.r0, true)
|
||||
txt.spc()
|
||||
cx16.r0--
|
||||
if cx16.r0
|
||||
goto my_label
|
||||
sys.exit(0)
|
||||
|
||||
foobar:
|
||||
txt.print("yeooo\n")
|
||||
goto my_label
|
||||
}
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ class IRFileReader {
|
||||
chunk += it
|
||||
},
|
||||
ifRight = {
|
||||
TODO("PROCESS LABEL $it")
|
||||
throw IRParseException("code chunk should not contain a separate label line anymore, this should be the proper label of a new separate chunk")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -620,7 +620,7 @@ data class IRInstruction(
|
||||
val fpValue: Float?=null,
|
||||
val labelSymbol: String?=null, // symbolic label name as alternative to value (so only for Branch/jump/call Instructions!)
|
||||
val binaryData: Collection<UByte>?=null,
|
||||
var branchTarget: IRCodeChunk? = null // will be linked after loading
|
||||
var branchTarget: IRCodeChunkBase? = null // will be linked after loading
|
||||
) {
|
||||
// reg1 and fpreg1 can be IN/OUT/INOUT (all others are readonly INPUT)
|
||||
// This knowledge is useful in IL assembly optimizers to see how registers are used.
|
||||
@ -635,7 +635,7 @@ data class IRInstruction(
|
||||
require(reg2==null || reg2 in 0..65536) {"reg2 out of bounds"}
|
||||
require(fpReg1==null || fpReg1 in 0..65536) {"fpReg1 out of bounds"}
|
||||
require(fpReg2==null || fpReg2 in 0..65536) {"fpReg2 out of bounds"}
|
||||
if(value!=null) {
|
||||
if(value!=null && labelSymbol==null) {
|
||||
when (type) {
|
||||
IRDataType.BYTE -> require(value in -128..255) {"value out of range for byte: $value"}
|
||||
IRDataType.WORD -> require(value in -32768..65535) {"value out of range for word: $value"}
|
||||
|
@ -76,17 +76,11 @@ class IRProgram(val name: String,
|
||||
val firstBlock = blocks.firstOrNull()
|
||||
if(firstBlock!=null) {
|
||||
if(firstBlock.inlineAssembly.isNotEmpty()) {
|
||||
TODO("link to inline assembly block")
|
||||
// irprog.globalInits.next = firstBlock.inlineAssembly.first()
|
||||
globalInits.next = firstBlock.inlineAssembly.first()
|
||||
} else if(firstBlock.subroutines.isNotEmpty()) {
|
||||
val firstSub = firstBlock.subroutines.first()
|
||||
if(firstSub.chunks.isNotEmpty()) {
|
||||
val firstChunk = firstSub.chunks.first()
|
||||
when(firstChunk) {
|
||||
is IRCodeChunk -> globalInits.next = firstChunk
|
||||
else -> TODO("link to other type of chunk")
|
||||
}
|
||||
}
|
||||
if(firstSub.chunks.isNotEmpty())
|
||||
globalInits.next = firstSub.chunks.first()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,7 +88,6 @@ class IRProgram(val name: String,
|
||||
|
||||
blocks.asSequence().flatMap { it.subroutines }.forEach { sub ->
|
||||
|
||||
|
||||
sub.chunks.withIndex().forEach { (index, chunk) ->
|
||||
|
||||
fun nextChunk(): IRCodeChunkBase? = if(index<sub.chunks.size-1) sub.chunks[index + 1] else null
|
||||
@ -118,10 +111,7 @@ class IRProgram(val name: String,
|
||||
chunk.instructions.forEach {
|
||||
if(it.opcode in OpcodesThatBranch && it.opcode!=Opcode.RETURN && it.labelSymbol!=null) {
|
||||
val targetChunk = labeledChunks.getValue(it.labelSymbol)
|
||||
if(targetChunk is IRCodeChunk)
|
||||
it.branchTarget = targetChunk
|
||||
else
|
||||
println("TODO: branchTarget to non-codechunk $targetChunk with label ${targetChunk.label}") // TODO
|
||||
}
|
||||
// note: branches with an address value cannot be linked to something...
|
||||
}
|
||||
@ -159,10 +149,8 @@ class IRProgram(val name: String,
|
||||
else
|
||||
require(chunk.instructions.isEmpty())
|
||||
chunk.instructions.forEach {
|
||||
if(it.labelSymbol!=null && it.opcode in OpcodesThatBranch) {
|
||||
if(it.branchTarget==null) println("TODO: fix branching instruction to label ${it.labelSymbol} should have branchTarget set") // TODO
|
||||
// TODO require(it.branchTarget != null) { "branching instruction to label should have branchTarget set" }
|
||||
}
|
||||
if(it.labelSymbol!=null && it.opcode in OpcodesThatBranch)
|
||||
require(it.branchTarget != null) { "branching instruction to label should have branchTarget set" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ fun parseIRCodeLine(line: String, location: Pair<IRCodeChunk, Int>?, placeholder
|
||||
operands.clear()
|
||||
}
|
||||
if(operands.isNotEmpty()) {
|
||||
TODO("placeholder symbol? $operands rest=$rest'")
|
||||
TODO("huh even more operands? $operands rest=$rest'")
|
||||
// operands.clear()
|
||||
}
|
||||
}
|
||||
|
@ -132,11 +132,16 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
}
|
||||
|
||||
private fun branchTo(i: IRInstruction) {
|
||||
if(i.branchTarget==null)
|
||||
TODO("no branchtarget in $i (remove this check)")
|
||||
pcChunk = i.branchTarget!!
|
||||
val target = i.branchTarget
|
||||
when (target) {
|
||||
is IRCodeChunk -> {
|
||||
pcChunk = target
|
||||
pcIndex = 0
|
||||
}
|
||||
null -> TODO("no branchtarget in $i (remove this check)")
|
||||
else -> throw IllegalArgumentException("VM can't execute code in a non-codechunk: $target")
|
||||
}
|
||||
}
|
||||
|
||||
private fun dispatch(ins: IRInstruction) {
|
||||
when(ins.opcode) {
|
||||
|
Loading…
Reference in New Issue
Block a user