11package deep.decaf.low.amd64
22
33import deep.decaf.ir.*
4+ import deep.decaf.low.*
45import java.lang.IllegalStateException
56import 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
229230data 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