mirror of
https://github.com/irmen/prog8.git
synced 2024-12-01 15:52:54 +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 target = VMTarget()
|
||||||
val result = compileText(target, true, src, writeAssembly = true)!!
|
var result = compileText(target, false, src, writeAssembly = true)!!
|
||||||
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
|
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())
|
VmRunner().runProgram(virtfile.readText())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +111,7 @@ mylabel_inside:
|
|||||||
}"""
|
}"""
|
||||||
|
|
||||||
val target = VMTarget()
|
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")
|
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
|
||||||
VmRunner().runProgram(virtfile.readText())
|
VmRunner().runProgram(virtfile.readText())
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ TODO
|
|||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- ir: fix unit tests
|
- ir: fix unit tests
|
||||||
|
- ir: join more codechunks
|
||||||
- ir: fix removeWeirdBranches in IR optimizer
|
- ir: fix removeWeirdBranches in IR optimizer
|
||||||
- update diagram in technical.rst?
|
- update diagram in technical.rst?
|
||||||
|
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import floats
|
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
float[10] flt
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
float ff = 9.0
|
cx16.r0 = 42
|
||||||
flt[1] = 42.42
|
goto foobar
|
||||||
flt[1] = -9.0
|
my_label:
|
||||||
flt[1] = -ff
|
txt.print_uwhex(cx16.r0, true)
|
||||||
flt[1] = -flt[1] ; TODO also fix crash when selecting vm target: fpReg1 out of bounds
|
txt.spc()
|
||||||
floats.print_f(flt[1])
|
cx16.r0--
|
||||||
txt.nl()
|
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
|
chunk += it
|
||||||
},
|
},
|
||||||
ifRight = {
|
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 fpValue: Float?=null,
|
||||||
val labelSymbol: String?=null, // symbolic label name as alternative to value (so only for Branch/jump/call Instructions!)
|
val labelSymbol: String?=null, // symbolic label name as alternative to value (so only for Branch/jump/call Instructions!)
|
||||||
val binaryData: Collection<UByte>?=null,
|
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)
|
// 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.
|
// 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(reg2==null || reg2 in 0..65536) {"reg2 out of bounds"}
|
||||||
require(fpReg1==null || fpReg1 in 0..65536) {"fpReg1 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"}
|
require(fpReg2==null || fpReg2 in 0..65536) {"fpReg2 out of bounds"}
|
||||||
if(value!=null) {
|
if(value!=null && labelSymbol==null) {
|
||||||
when (type) {
|
when (type) {
|
||||||
IRDataType.BYTE -> require(value in -128..255) {"value out of range for byte: $value"}
|
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"}
|
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()
|
val firstBlock = blocks.firstOrNull()
|
||||||
if(firstBlock!=null) {
|
if(firstBlock!=null) {
|
||||||
if(firstBlock.inlineAssembly.isNotEmpty()) {
|
if(firstBlock.inlineAssembly.isNotEmpty()) {
|
||||||
TODO("link to inline assembly block")
|
globalInits.next = firstBlock.inlineAssembly.first()
|
||||||
// irprog.globalInits.next = firstBlock.inlineAssembly.first()
|
|
||||||
} else if(firstBlock.subroutines.isNotEmpty()) {
|
} else if(firstBlock.subroutines.isNotEmpty()) {
|
||||||
val firstSub = firstBlock.subroutines.first()
|
val firstSub = firstBlock.subroutines.first()
|
||||||
if(firstSub.chunks.isNotEmpty()) {
|
if(firstSub.chunks.isNotEmpty())
|
||||||
val firstChunk = firstSub.chunks.first()
|
globalInits.next = firstSub.chunks.first()
|
||||||
when(firstChunk) {
|
|
||||||
is IRCodeChunk -> globalInits.next = firstChunk
|
|
||||||
else -> TODO("link to other type of chunk")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +88,6 @@ class IRProgram(val name: String,
|
|||||||
|
|
||||||
blocks.asSequence().flatMap { it.subroutines }.forEach { sub ->
|
blocks.asSequence().flatMap { it.subroutines }.forEach { sub ->
|
||||||
|
|
||||||
|
|
||||||
sub.chunks.withIndex().forEach { (index, chunk) ->
|
sub.chunks.withIndex().forEach { (index, chunk) ->
|
||||||
|
|
||||||
fun nextChunk(): IRCodeChunkBase? = if(index<sub.chunks.size-1) sub.chunks[index + 1] else null
|
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 {
|
chunk.instructions.forEach {
|
||||||
if(it.opcode in OpcodesThatBranch && it.opcode!=Opcode.RETURN && it.labelSymbol!=null) {
|
if(it.opcode in OpcodesThatBranch && it.opcode!=Opcode.RETURN && it.labelSymbol!=null) {
|
||||||
val targetChunk = labeledChunks.getValue(it.labelSymbol)
|
val targetChunk = labeledChunks.getValue(it.labelSymbol)
|
||||||
if(targetChunk is IRCodeChunk)
|
|
||||||
it.branchTarget = targetChunk
|
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...
|
// note: branches with an address value cannot be linked to something...
|
||||||
}
|
}
|
||||||
@ -159,10 +149,8 @@ class IRProgram(val name: String,
|
|||||||
else
|
else
|
||||||
require(chunk.instructions.isEmpty())
|
require(chunk.instructions.isEmpty())
|
||||||
chunk.instructions.forEach {
|
chunk.instructions.forEach {
|
||||||
if(it.labelSymbol!=null && it.opcode in OpcodesThatBranch) {
|
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
|
require(it.branchTarget != null) { "branching instruction to label should have branchTarget set" }
|
||||||
// TODO 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()
|
operands.clear()
|
||||||
}
|
}
|
||||||
if(operands.isNotEmpty()) {
|
if(operands.isNotEmpty()) {
|
||||||
TODO("placeholder symbol? $operands rest=$rest'")
|
TODO("huh even more operands? $operands rest=$rest'")
|
||||||
// operands.clear()
|
// operands.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,11 +132,16 @@ class VirtualMachine(irProgram: IRProgram) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun branchTo(i: IRInstruction) {
|
private fun branchTo(i: IRInstruction) {
|
||||||
if(i.branchTarget==null)
|
val target = i.branchTarget
|
||||||
TODO("no branchtarget in $i (remove this check)")
|
when (target) {
|
||||||
pcChunk = i.branchTarget!!
|
is IRCodeChunk -> {
|
||||||
|
pcChunk = target
|
||||||
pcIndex = 0
|
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) {
|
private fun dispatch(ins: IRInstruction) {
|
||||||
when(ins.opcode) {
|
when(ins.opcode) {
|
||||||
|
Loading…
Reference in New Issue
Block a user