Skip to content

Commit 1a89280

Browse files
committed
Partial implementation of cfg to low conversion
1 parent a7b5460 commit 1a89280

1 file changed

Lines changed: 56 additions & 3 deletions

File tree

src/main/kotlin/deep/decaf/low/amd64/LowIRClasses.kt

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package deep.decaf.low.amd64
22

33
import deep.decaf.ir.*
4+
import deep.decaf.low.*
45
import java.lang.IllegalStateException
56
import java.util.*
67

@@ -212,7 +213,7 @@ data class PushInstruction(val src: Location) : Instruction() {
212213
override fun toString() = "push $src"
213214
}
214215

215-
data class PopInstruction(val src: Location?) : Instruction() {
216+
data class PopInstruction(val src: Location) : Instruction() {
216217
override fun toString() = "pop ${src ?: ""}"
217218
}
218219

@@ -224,7 +225,7 @@ data class EnterInstruction(val size: ImmediateVal) : Instruction() {
224225
override fun toString() = "enter \$($size*8), $0"
225226
}
226227

227-
data class Block(val label: String?, val instructions: List<Instruction>)
228+
data class Block(val label: String?, val instructions: MutableList<Instruction>)
228229

229230
data class Method(
230231
var stackSize: Int,
@@ -252,7 +253,7 @@ fun irExprToLow(expr: IRExpr): List<Instruction> {
252253
argLocations.forEach { instructions.add(PushInstruction(it)) }
253254
instructions.add(CallInstruction(expr.name))
254255
for (i in 1..expr.argList.size) {
255-
instructions.add(PopInstruction(null))
256+
instructions.add(PopInstruction(Register.r10()))
256257
}
257258
Register.returnRegister()
258259
}
@@ -454,4 +455,56 @@ fun irStatementToLow(statement: IRStatement): List<Instruction> {
454455
}
455456

456457
return instructions
458+
}
459+
460+
fun methodCFGToLow(name: String, cfg: CFG, blockCountStart: Int = 0) {
461+
val blocks = mutableListOf<Block>()
462+
var stackSize = 0
463+
var blockCounts = blockCountStart
464+
465+
val visited = mutableMapOf<String, Boolean>()
466+
fun convert(node: CFGNode, block: Block) {
467+
val done = visited[node.uuid] ?: false
468+
if (!done) {
469+
visited[node.uuid] = true
470+
when (node) {
471+
is RegularNode -> {
472+
for (statement in node.statements) {
473+
block.instructions.addAll(irStatementToLow(statement))
474+
}
475+
if (node.next != null) {
476+
convert(node.next!!, block)
477+
}
478+
}
479+
is BlockEntryNode -> {
480+
if (node.next != null) {
481+
convert(node.next!!, block)
482+
}
483+
}
484+
is BlockExitNode -> {
485+
if (node.next != null) {
486+
convert(node.next!!, block)
487+
}
488+
}
489+
is ConditionalNode -> {
490+
val instructions = irExprToLow(node.condition)
491+
val res = (instructions.last() as MoveInstruction).dest
492+
blockCounts++
493+
val newLabel = "BLOCK$blockCounts"
494+
block.instructions.add(MoveInstruction(res, Register.r10()))
495+
block.instructions.add(CmpInstruction(Register.r10(), ImmediateVal(1)))
496+
block.instructions.add(JumpInstruction(AsmJumpOp.JNE, newLabel))
497+
if (node.truePath != null) {
498+
convert(node.truePath!!, block)
499+
}
500+
val newBlock = Block(newLabel, mutableListOf())
501+
if (node.falsePath != null) {
502+
convert(node.falsePath!!, newBlock)
503+
}
504+
blocks.add(newBlock)
505+
}
506+
else -> throw IllegalStateException("wrong CFG")
507+
}
508+
}
509+
}
457510
}

0 commit comments

Comments
 (0)