mirror of
https://github.com/irmen/prog8.git
synced 2024-12-22 18:30:01 +00:00
ir: JUMPI instruction added to support indirect jumps
This commit is contained in:
parent
90c4b00f74
commit
334d382bfa
@ -1,9 +1,6 @@
|
||||
package prog8.codegen.intermediate
|
||||
|
||||
import prog8.code.StMemVar
|
||||
import prog8.code.StNode
|
||||
import prog8.code.StStaticVariable
|
||||
import prog8.code.SymbolTable
|
||||
import prog8.code.*
|
||||
import prog8.code.ast.*
|
||||
import prog8.code.core.*
|
||||
import prog8.intermediate.*
|
||||
@ -1520,17 +1517,26 @@ class IRCodeGen(
|
||||
|
||||
private fun translate(jump: PtJump): IRCodeChunks {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val instr = if(jump.address!=null) {
|
||||
IRInstruction(Opcode.JUMPA, address = jump.address!!.toInt())
|
||||
val chunk = IRCodeChunk(null, null)
|
||||
if(jump.address!=null) {
|
||||
chunk += IRInstruction(Opcode.JUMP, address = jump.address!!.toInt())
|
||||
} else {
|
||||
if (jump.generatedLabel != null)
|
||||
IRInstruction(Opcode.JUMP, labelSymbol = jump.generatedLabel!!)
|
||||
else if (jump.identifier != null)
|
||||
IRInstruction(Opcode.JUMP, labelSymbol = jump.identifier!!.name)
|
||||
chunk += IRInstruction(Opcode.JUMP, labelSymbol = jump.generatedLabel!!)
|
||||
else if (jump.identifier != null) {
|
||||
val symbol = symbolTable.lookup(jump.identifier!!.name)
|
||||
if(symbol?.type==StNodeType.MEMVAR || symbol?.type==StNodeType.STATICVAR) {
|
||||
val jumpReg = registers.nextFree()
|
||||
chunk += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1 = jumpReg, labelSymbol = jump.identifier!!.name)
|
||||
chunk += IRInstruction(Opcode.JUMPI, reg1 = jumpReg)
|
||||
} else {
|
||||
chunk += IRInstruction(Opcode.JUMP, labelSymbol = jump.identifier!!.name)
|
||||
}
|
||||
}
|
||||
else
|
||||
throw AssemblyError("weird jump")
|
||||
}
|
||||
addInstr(result, instr, null)
|
||||
result += chunk
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,10 @@ main {
|
||||
txt.print_ub('a' in name)
|
||||
txt.print_ub('e' in name)
|
||||
txt.nl()
|
||||
txt.print_ub(all(othercells)) ;; TODO fix vm ALL() !
|
||||
txt.print_ub(all(othercells))
|
||||
txt.print_ub(any(othercells))
|
||||
othercells[3] = 0
|
||||
txt.print_ub(all(othercells)) ;; TODO fix vm ALL() !
|
||||
txt.print_ub(all(othercells))
|
||||
txt.print_ub(any(othercells))
|
||||
reverse(othercells)
|
||||
sort(othercells)
|
||||
|
@ -51,8 +51,8 @@ storezx reg1, address - store zero at memory address, indexed by
|
||||
|
||||
CONTROL FLOW
|
||||
------------
|
||||
jump location - continue running at instruction number given by location
|
||||
jumpa address - continue running at memory address (note: only used to encode a physical cpu jump to fixed address instruction)
|
||||
jump location - continue running at instruction at 'location' (label/memory address)
|
||||
jumpi reg1 - continue running at memory address in reg1 (indirect jump)
|
||||
call label(argument register list) [: resultreg.type]
|
||||
- calls a subroutine with the given arguments and return value (optional).
|
||||
save current instruction location+1, continue execution at instruction nr of the label.
|
||||
@ -240,7 +240,7 @@ enum class Opcode {
|
||||
STOREZX,
|
||||
|
||||
JUMP,
|
||||
JUMPA,
|
||||
JUMPI,
|
||||
CALL,
|
||||
SYSCALL,
|
||||
RETURN,
|
||||
@ -378,14 +378,14 @@ enum class Opcode {
|
||||
|
||||
val OpcodesThatJump = setOf(
|
||||
Opcode.JUMP,
|
||||
Opcode.JUMPA,
|
||||
Opcode.JUMPI,
|
||||
Opcode.RETURN,
|
||||
Opcode.RETURNR
|
||||
)
|
||||
|
||||
val OpcodesThatBranch = setOf(
|
||||
Opcode.JUMP,
|
||||
Opcode.JUMPA,
|
||||
Opcode.JUMPI,
|
||||
Opcode.RETURN,
|
||||
Opcode.RETURNR,
|
||||
Opcode.CALL,
|
||||
@ -514,7 +514,7 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.STOREZI to InstructionFormat.from("BW,<r1 | F,<r1"),
|
||||
Opcode.STOREZX to InstructionFormat.from("BW,<r1,>a | F,<r1,>a"),
|
||||
Opcode.JUMP to InstructionFormat.from("N,<a"),
|
||||
Opcode.JUMPA to InstructionFormat.from("N,<a"),
|
||||
Opcode.JUMPI to InstructionFormat.from("N,<r1"),
|
||||
Opcode.CALL to InstructionFormat.from("N,call"),
|
||||
Opcode.SYSCALL to InstructionFormat.from("N,syscall"),
|
||||
Opcode.RETURN to InstructionFormat.from("N"),
|
||||
|
@ -95,6 +95,7 @@ class IRProgram(val name: String,
|
||||
}
|
||||
}
|
||||
}
|
||||
result.remove(null)
|
||||
return result
|
||||
}
|
||||
|
||||
@ -407,6 +408,7 @@ class IRAsmSubroutine(
|
||||
init {
|
||||
require('.' in label) { "subroutine name is not scoped: $label" }
|
||||
require(!label.startsWith("main.main.")) { "subroutine name invalid main prefix: $label" }
|
||||
require(label==asmChunk.label)
|
||||
}
|
||||
|
||||
private val registersUsed by lazy { registersUsedInAssembly(asmChunk.isIR, asmChunk.assembly) }
|
||||
|
@ -147,6 +147,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
null -> {
|
||||
if(i.address!=null)
|
||||
throw IllegalArgumentException("vm program can't jump to system memory address (${i.opcode} ${i.address!!.toHex()})")
|
||||
else if(i.labelSymbol!=null)
|
||||
throw IllegalArgumentException("vm program can't jump to system memory address (${i.opcode} ${i.labelSymbol})")
|
||||
else if(i.reg1!=null)
|
||||
throw IllegalArgumentException("vm program can't jump to system memory address (${i})")
|
||||
else
|
||||
throw IllegalArgumentException("no branchtarget in $i")
|
||||
}
|
||||
@ -174,8 +178,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
Opcode.STOREZM -> InsSTOREZM(ins)
|
||||
Opcode.STOREZX -> InsSTOREZX(ins)
|
||||
Opcode.STOREZI -> InsSTOREZI(ins)
|
||||
Opcode.JUMP -> InsJUMP(ins)
|
||||
Opcode.JUMPA -> throw IllegalArgumentException("vm program can't jump to system memory address (JUMPA)")
|
||||
Opcode.JUMP, Opcode.JUMPI -> InsJUMP(ins)
|
||||
Opcode.CALL -> InsCALL(ins)
|
||||
Opcode.SYSCALL -> InsSYSCALL(ins)
|
||||
Opcode.RETURN -> InsRETURN()
|
||||
|
@ -191,8 +191,6 @@ class VmProgramLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private val functionCallOpcodes = setOf(Opcode.CALL, Opcode.SYSCALL, Opcode.JUMP, Opcode.JUMPA)
|
||||
|
||||
private fun varsToMemory(
|
||||
program: IRProgram,
|
||||
allocations: VmVariableAllocator,
|
||||
|
Loading…
Reference in New Issue
Block a user