11package deep.decaf.low.amd64
22
33import deep.decaf.ir.*
4- import deep.decaf.low.*
54import java.lang.IllegalStateException
6- import java.util.*
7-
8- fun getUUID (): String = UUID .randomUUID().toString().replace(" -" , " " )
9-
10- sealed class Offset
11- data class NumberOffset (val offset : Int ) : Offset() {
12- override fun toString (): String {
13- return " $offset "
14- }
15- }
16-
17- data class StringOffset (val name : String ) : Offset() {
18- override fun toString (): String {
19- return name
20- }
21- }
22-
23-
24- sealed class Location
25- data class ImmediateVal (val num : Int ) : Location() {
26- override fun toString (): String {
27- return " \$ $num "
28- }
29- }
30-
31- data class Register (val name : String ) : Location() {
32- companion object {
33- fun basePointer () = Register (" rbp" )
34- fun stackPointer () = Register (" rsp" )
35- fun instructionPointer () = Register (" rip" )
36- fun returnRegister () = Register (" rax" )
37- fun r10 () = Register (" r10" )
38- fun r10b () = Register (" r10b" )
39- fun r11 () = Register (" r11" )
40- fun rax () = Register (" rax" )
41- fun rdx () = Register (" rdx" )
42- }
43-
44- override fun toString (): String {
45- return " %$name "
46- }
47- }
48-
49- data class Label (val label : String ) : Location() {
50- override fun toString (): String {
51- return label
52- }
53- }
54-
55- data class MemLoc (val reg : Register , val offset : NumberOffset ) : Location() {
56- override fun toString (): String {
57- return " $offset ($reg )"
58- }
59- }
60-
61- data class ArrayAsm (val name : String , val offsetRegister : Register ) : Location() {
62- override fun toString (): String {
63- return " $name (, $offsetRegister , 8)"
64- }
65- }
66-
67- enum class AsmCMoveOp {
68- CMOVE ,
69- CMOVNE ,
70- CMOVG ,
71- CMOVL ,
72- CMOVGE ,
73- CMOVLE ;
74-
75- override fun toString (): String {
76- return when (this ) {
77- CMOVE -> " cmove"
78- CMOVNE -> " cmovne"
79- CMOVG -> " cmovg"
80- CMOVL -> " cmovl"
81- CMOVGE -> " cmovge"
82- CMOVLE -> " cmovle"
83- }
84- }
85- }
86-
87- enum class AsmJumpOp {
88- JMP ,
89- JE ,
90- JNE ;
91-
92- override fun toString (): String {
93- return when (this ) {
94- JMP -> " jmp"
95- JE -> " je"
96- JNE -> " jne"
97- }
98- }
99- }
100-
101- enum class SetType {
102- SETE ,
103- SETNE ,
104- SETG ,
105- SETL ,
106- SETGE ,
107- SETLE ;
108-
109- override fun toString (): String {
110- return when (this ) {
111- SETE -> " sete"
112- SETNE -> " setne"
113- SETG -> " setg"
114- SETL -> " setl"
115- SETGE -> " setge"
116- SETLE -> " setle"
117- }
118- }
119- }
120-
121- sealed class Instruction
122- data class AddInstruction (val src : Location , val dest : Location ) : Instruction() {
123- override fun toString (): String {
124- return " add $src , $dest "
125- }
126- }
127-
128- data class SubInstruction (val src : Location , val dest : Location ) : Instruction() {
129- override fun toString (): String {
130- return " sub $src , $dest "
131- }
132- }
133-
134- data class IMulInstruction (val src : Location , val dest : Location ) : Instruction() {
135- override fun toString (): String {
136- return " imul $src , $dest "
137- }
138- }
139-
140- data class IDivInstruction (val src : Location ) : Instruction() {
141- override fun toString (): String {
142- return " idivq $src "
143- }
144- }
145-
146- data class CmpInstruction (val src : Location , val dest : Location ) : Instruction() {
147- override fun toString (): String {
148- return " cmp $src , $dest "
149- }
150- }
151-
152- data class AndInstruction (val src : Location , val dest : Location ) : Instruction() {
153- override fun toString (): String {
154- return " and $src , $dest "
155- }
156- }
157-
158- data class OrInstruction (val src : Location , val dest : Location ) : Instruction() {
159- override fun toString (): String {
160- return " or $src , $dest "
161- }
162- }
163-
164- data class NotInstruction (val src : Location ) : Instruction() {
165- override fun toString (): String {
166- return " not $src "
167- }
168- }
169-
170- data class NegInstruction (val src : Location ) : Instruction() {
171- override fun toString (): String {
172- return " nge $src "
173- }
174- }
175-
176- data class JumpInstruction (val type : AsmJumpOp , val target : String ) : Instruction() {
177- override fun toString (): String {
178- return " $type $target "
179- }
180- }
181-
182- data class MoveInstruction (val src : Location , val dest : Location ) : Instruction() {
183- override fun toString (): String {
184- return " mov $src , $dest "
185- }
186- }
187-
188- data class CMoveInstruction (val type : AsmCMoveOp , val src : Register , val dest : Register ) : Instruction() {
189- override fun toString (): String {
190- return " $type $src $dest "
191- }
192- }
193-
194- data class SetInstruction (val type : SetType , val reg : Register ) : Instruction() {
195- override fun toString (): String {
196- return " $type $reg "
197- }
198- }
199-
200- object SignedExtendInstruction : Instruction() {
201- override fun toString () = " cqto"
202- }
203-
204- object ReturnInstruction : Instruction() {
205- override fun toString () = " ret"
206- }
207-
208- data class CallInstruction (val label : String ) : Instruction() {
209- override fun toString () = " call $label "
210- }
211-
212- data class PushInstruction (val src : Location ) : Instruction() {
213- override fun toString () = " push $src "
214- }
215-
216- data class PopInstruction (val src : Location ) : Instruction() {
217- override fun toString () = " pop ${src ? : " " } "
218- }
219-
220- object LeaveInstruction : Instruction() {
221- override fun toString () = " leave"
222- }
223-
224- data class EnterInstruction (val size : ImmediateVal ) : Instruction() {
225- override fun toString () = " enter \$ ($size *8), $0"
226- }
227-
228- data class Block (val label : String? , val instructions : MutableList <Instruction >)
229-
230- data class Method (
231- var stackSize : Int ,
232- var formalParams : Map <String , Location >,
233- var localVars : Map <String , Location >,
234- var blocks : List <Block >,
235- var program : Program
236- )
237-
238- data class Program (
239- var globalVars : List <String >,
240- var globalArrays : List <String >,
241- var methods : List <Method >
242- )
2435
2446fun irExprToLow (expr : IRExpr ): List <Instruction > {
2457 val instructions = mutableListOf<Instruction >()
@@ -455,56 +217,4 @@ fun irStatementToLow(statement: IRStatement): List<Instruction> {
455217 }
456218
457219 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- }
510220}
0 commit comments