refactor: extract stack into seperate class
This commit is contained in:
parent
8ed94e4df3
commit
3f76a2c5bf
@ -10,7 +10,6 @@ object asmGenerator {
|
|||||||
|
|
||||||
val RAX = Register(RegSize.R64, RegName.AX)
|
val RAX = Register(RegSize.R64, RegName.AX)
|
||||||
val EAX = Register(RegSize.E32, RegName.AX)
|
val EAX = Register(RegSize.E32, RegName.AX)
|
||||||
val RSP = Register(RegSize.R64, RegName.SP)
|
|
||||||
val ESP = Register(RegSize.E32, RegName.SP)
|
val ESP = Register(RegSize.E32, RegName.SP)
|
||||||
val EDX = Register(RegSize.E32, RegName.DX)
|
val EDX = Register(RegSize.E32, RegName.DX)
|
||||||
val RDI = Register(RegSize.R64, RegName.DI)
|
val RDI = Register(RegSize.R64, RegName.DI)
|
||||||
@ -37,14 +36,14 @@ object asmGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def generateAsm(microProg: Program): List[AsmLine] = {
|
def generateAsm(microProg: Program): List[AsmLine] = {
|
||||||
given stack: LinkedHashMap[Ident, Int] = LinkedHashMap[Ident, Int]()
|
given stack: Stack = Stack()
|
||||||
given strings: ListBuffer[String] = ListBuffer[String]()
|
given strings: ListBuffer[String] = ListBuffer[String]()
|
||||||
val Program(funcs, main) = microProg
|
val Program(funcs, main) = microProg
|
||||||
|
|
||||||
val progAsm =
|
val progAsm =
|
||||||
LabelDef("main") ::
|
LabelDef("main") ::
|
||||||
funcPrologue() ++
|
funcPrologue() ++
|
||||||
alignStack() ++
|
List(stack.align()) ++
|
||||||
main.flatMap(generateStmt) ++
|
main.flatMap(generateStmt) ++
|
||||||
List(Move(RAX, ImmediateVal(0))) ++
|
List(Move(RAX, ImmediateVal(0))) ++
|
||||||
funcEpilogue() ++
|
funcEpilogue() ++
|
||||||
@ -61,7 +60,7 @@ object asmGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def wrapFunc(labelName: String, funcBody: List[AsmLine])(using
|
def wrapFunc(labelName: String, funcBody: List[AsmLine])(using
|
||||||
stack: LinkedHashMap[Ident, Int],
|
stack: Stack,
|
||||||
strings: ListBuffer[String]
|
strings: ListBuffer[String]
|
||||||
): List[AsmLine] = {
|
): List[AsmLine] = {
|
||||||
LabelDef(labelName) ::
|
LabelDef(labelName) ::
|
||||||
@ -71,18 +70,17 @@ object asmGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def generateBuiltInFuncs()(using
|
def generateBuiltInFuncs()(using
|
||||||
stack: LinkedHashMap[Ident, Int],
|
stack: Stack,
|
||||||
strings: ListBuffer[String]
|
strings: ListBuffer[String]
|
||||||
): List[AsmLine] = {
|
): List[AsmLine] = {
|
||||||
wrapFunc(
|
wrapFunc(
|
||||||
labelGenerator.getLabel(Builtin.Exit),
|
labelGenerator.getLabel(Builtin.Exit),
|
||||||
alignStack() ++
|
List(stack.align(), assemblyIR.Call(CLibFunc.Exit))
|
||||||
List(assemblyIR.Call(CLibFunc.Exit))
|
|
||||||
) ++
|
) ++
|
||||||
wrapFunc(
|
wrapFunc(
|
||||||
labelGenerator.getLabel(Builtin.Printf),
|
labelGenerator.getLabel(Builtin.Printf),
|
||||||
alignStack() ++
|
|
||||||
List(
|
List(
|
||||||
|
stack.align(),
|
||||||
assemblyIR.Call(CLibFunc.PrintF),
|
assemblyIR.Call(CLibFunc.PrintF),
|
||||||
Move(RDI, ImmediateVal(0)),
|
Move(RDI, ImmediateVal(0)),
|
||||||
assemblyIR.Call(CLibFunc.Fflush)
|
assemblyIR.Call(CLibFunc.Fflush)
|
||||||
@ -90,46 +88,44 @@ object asmGenerator {
|
|||||||
) ++
|
) ++
|
||||||
wrapFunc(
|
wrapFunc(
|
||||||
labelGenerator.getLabel(Builtin.Malloc),
|
labelGenerator.getLabel(Builtin.Malloc),
|
||||||
alignStack() ++
|
List(
|
||||||
List()
|
stack.align(),
|
||||||
|
)
|
||||||
) ++
|
) ++
|
||||||
wrapFunc(labelGenerator.getLabel(Builtin.Free), List()) ++
|
wrapFunc(labelGenerator.getLabel(Builtin.Free), List()) ++
|
||||||
wrapFunc(
|
wrapFunc(
|
||||||
labelGenerator.getLabel(Builtin.Read),
|
labelGenerator.getLabel(Builtin.Read),
|
||||||
alignStack() ++
|
|
||||||
List(
|
List(
|
||||||
Push(RSI),
|
stack.align(),
|
||||||
Load(RSI, MemLocation(RSP)),
|
stack.push(RSI),
|
||||||
|
Load(RSI, stack.head),
|
||||||
assemblyIR.Call(CLibFunc.Scanf),
|
assemblyIR.Call(CLibFunc.Scanf),
|
||||||
Pop(RAX)
|
stack.pop(RAX)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def generateStmt(
|
def generateStmt(
|
||||||
stmt: Stmt
|
stmt: Stmt
|
||||||
)(using stack: LinkedHashMap[Ident, Int], strings: ListBuffer[String]): List[AsmLine] =
|
)(using stack: Stack, strings: ListBuffer[String]): List[AsmLine] =
|
||||||
stmt match {
|
stmt match {
|
||||||
case Assign(lhs, rhs) =>
|
case Assign(lhs, rhs) =>
|
||||||
var dest: () => IndexAddress =
|
var dest: () => IndexAddress =
|
||||||
() => IndexAddress(RSP, 0) // gets overrwitten
|
() => IndexAddress(RAX, 0) // gets overrwitten
|
||||||
(lhs match {
|
(lhs match {
|
||||||
case ident: Ident =>
|
case ident: Ident =>
|
||||||
|
dest = stack.accessVar(ident)
|
||||||
if (!stack.contains(ident)) {
|
if (!stack.contains(ident)) {
|
||||||
stack += (ident -> (stack.size + 1))
|
List(stack.reserve(ident))
|
||||||
dest = accessVar(ident)
|
} else Nil
|
||||||
List(Subtract(RSP, ImmediateVal(8)))
|
|
||||||
} else {
|
|
||||||
dest = accessVar(ident)
|
|
||||||
List()
|
|
||||||
}
|
|
||||||
// TODO lhs = arrayElem
|
// TODO lhs = arrayElem
|
||||||
case _ =>
|
case _ =>
|
||||||
// dest = ???
|
// dest = ???
|
||||||
List()
|
List()
|
||||||
}) ++
|
}) ++
|
||||||
evalExprOntoStack(rhs) ++
|
evalExprOntoStack(rhs) ++
|
||||||
List(Pop(RAX),
|
List(
|
||||||
|
stack.pop(RAX),
|
||||||
Move(dest(), RAX),
|
Move(dest(), RAX),
|
||||||
)
|
)
|
||||||
case If(cond, thenBranch, elseBranch) => {
|
case If(cond, thenBranch, elseBranch) => {
|
||||||
@ -137,8 +133,8 @@ object asmGenerator {
|
|||||||
val endLabel = labelGenerator.getLabel()
|
val endLabel = labelGenerator.getLabel()
|
||||||
evalExprOntoStack(cond) ++
|
evalExprOntoStack(cond) ++
|
||||||
List(
|
List(
|
||||||
Compare(MemLocation(RSP, SizeDir.Word), ImmediateVal(0)),
|
Compare(stack.head(SizeDir.Word), ImmediateVal(0)),
|
||||||
Add(RSP, ImmediateVal(8)),
|
stack.drop(),
|
||||||
Jump(LabelArg(elseLabel), Cond.Equal)
|
Jump(LabelArg(elseLabel), Cond.Equal)
|
||||||
) ++
|
) ++
|
||||||
thenBranch.flatMap(generateStmt) ++
|
thenBranch.flatMap(generateStmt) ++
|
||||||
@ -152,8 +148,8 @@ object asmGenerator {
|
|||||||
List(LabelDef(startLabel)) ++
|
List(LabelDef(startLabel)) ++
|
||||||
evalExprOntoStack(cond) ++
|
evalExprOntoStack(cond) ++
|
||||||
List(
|
List(
|
||||||
Compare(MemLocation(RSP, SizeDir.Word), ImmediateVal(0)),
|
Compare(stack.head(SizeDir.Word), ImmediateVal(0)),
|
||||||
Add(RSP, ImmediateVal(8)),
|
stack.drop(),
|
||||||
Jump(LabelArg(endLabel), Cond.Equal)
|
Jump(LabelArg(endLabel), Cond.Equal)
|
||||||
) ++
|
) ++
|
||||||
body.flatMap(generateStmt) ++
|
body.flatMap(generateStmt) ++
|
||||||
@ -161,21 +157,21 @@ object asmGenerator {
|
|||||||
}
|
}
|
||||||
case microWacc.Return(expr) =>
|
case microWacc.Return(expr) =>
|
||||||
evalExprOntoStack(expr) ++
|
evalExprOntoStack(expr) ++
|
||||||
List(Pop(RAX), assemblyIR.Return())
|
List(stack.pop(RAX), assemblyIR.Return())
|
||||||
case call: microWacc.Call => generateCall(call)
|
case call: microWacc.Call => generateCall(call)
|
||||||
}
|
}
|
||||||
|
|
||||||
def evalExprOntoStack(expr: Expr)(using
|
def evalExprOntoStack(expr: Expr)(using
|
||||||
stack: LinkedHashMap[Ident, Int],
|
stack: Stack,
|
||||||
strings: ListBuffer[String]
|
strings: ListBuffer[String]
|
||||||
): List[AsmLine] = {
|
): List[AsmLine] = {
|
||||||
expr match {
|
expr match {
|
||||||
case IntLiter(v) =>
|
case IntLiter(v) =>
|
||||||
List(Push(ImmediateVal(v)))
|
List(stack.push(ImmediateVal(v)))
|
||||||
case CharLiter(v) =>
|
case CharLiter(v) =>
|
||||||
List(Push(ImmediateVal(v.toInt)))
|
List(stack.push(ImmediateVal(v.toInt)))
|
||||||
case ident: Ident =>
|
case ident: Ident =>
|
||||||
List(Push(accessVar(ident)()))
|
List(stack.push(stack.accessVar(ident)()))
|
||||||
case ArrayLiter(elems) =>
|
case ArrayLiter(elems) =>
|
||||||
expr.ty match {
|
expr.ty match {
|
||||||
case KnownType.String =>
|
case KnownType.String =>
|
||||||
@ -191,13 +187,13 @@ object asmGenerator {
|
|||||||
LabelArg(s".L.str${strings.size - 1}")
|
LabelArg(s".L.str${strings.size - 1}")
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Push(RAX)
|
stack.push(RAX)
|
||||||
)
|
)
|
||||||
// TODO other array types
|
// TODO other array types
|
||||||
case _ => List()
|
case _ => List()
|
||||||
}
|
}
|
||||||
case BoolLiter(v) => List(Push(ImmediateVal(if (v) 1 else 0)))
|
case BoolLiter(v) => List(stack.push(ImmediateVal(if (v) 1 else 0)))
|
||||||
case NullLiter() => List(Push(ImmediateVal(0)))
|
case NullLiter() => List(stack.push(ImmediateVal(0)))
|
||||||
case ArrayElem(value, indices) => List()
|
case ArrayElem(value, indices) => List()
|
||||||
case UnaryOp(x, op) =>
|
case UnaryOp(x, op) =>
|
||||||
op match {
|
op match {
|
||||||
@ -208,12 +204,12 @@ object asmGenerator {
|
|||||||
case UnaryOperator.Len => List()
|
case UnaryOperator.Len => List()
|
||||||
case UnaryOperator.Negate =>
|
case UnaryOperator.Negate =>
|
||||||
List(
|
List(
|
||||||
Negate(MemLocation(RSP, SizeDir.Word))
|
Negate(stack.head(SizeDir.Word))
|
||||||
)
|
)
|
||||||
case UnaryOperator.Not =>
|
case UnaryOperator.Not =>
|
||||||
evalExprOntoStack(x) ++
|
evalExprOntoStack(x) ++
|
||||||
List(
|
List(
|
||||||
Xor(MemLocation(RSP, SizeDir.Word), ImmediateVal(1))
|
Xor(stack.head(SizeDir.Word), ImmediateVal(1))
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -223,46 +219,46 @@ object asmGenerator {
|
|||||||
evalExprOntoStack(x) ++
|
evalExprOntoStack(x) ++
|
||||||
evalExprOntoStack(y) ++
|
evalExprOntoStack(y) ++
|
||||||
List(
|
List(
|
||||||
Pop(RAX),
|
stack.pop(RAX),
|
||||||
Add(MemLocation(RSP, SizeDir.Word), EAX)
|
Add(stack.head(SizeDir.Word), EAX)
|
||||||
// TODO OVERFLOWING
|
// TODO OVERFLOWING
|
||||||
)
|
)
|
||||||
case BinaryOperator.Sub =>
|
case BinaryOperator.Sub =>
|
||||||
evalExprOntoStack(x) ++
|
evalExprOntoStack(x) ++
|
||||||
evalExprOntoStack(y) ++
|
evalExprOntoStack(y) ++
|
||||||
List(
|
List(
|
||||||
Pop(RAX),
|
stack.pop(RAX),
|
||||||
Subtract(MemLocation(RSP, SizeDir.Word), EAX)
|
Subtract(stack.head(SizeDir.Word), EAX)
|
||||||
// TODO OVERFLOWING
|
// TODO OVERFLOWING
|
||||||
)
|
)
|
||||||
case BinaryOperator.Mul =>
|
case BinaryOperator.Mul =>
|
||||||
evalExprOntoStack(x) ++
|
evalExprOntoStack(x) ++
|
||||||
evalExprOntoStack(y) ++
|
evalExprOntoStack(y) ++
|
||||||
List(
|
List(
|
||||||
Pop(RAX),
|
stack.pop(RAX),
|
||||||
Multiply(EAX, MemLocation(RSP, SizeDir.Word)),
|
Multiply(EAX, stack.head(SizeDir.Word)),
|
||||||
Add(RSP, ImmediateVal(8)),
|
stack.drop(),
|
||||||
Push(RAX)
|
stack.push(RAX)
|
||||||
// TODO OVERFLOWING
|
// TODO OVERFLOWING
|
||||||
)
|
)
|
||||||
case BinaryOperator.Div =>
|
case BinaryOperator.Div =>
|
||||||
evalExprOntoStack(y) ++
|
evalExprOntoStack(y) ++
|
||||||
evalExprOntoStack(x) ++
|
evalExprOntoStack(x) ++
|
||||||
List(
|
List(
|
||||||
Pop(RAX),
|
stack.pop(RAX),
|
||||||
Divide(MemLocation(RSP, SizeDir.Word)),
|
Divide(stack.head(SizeDir.Word)),
|
||||||
Add(RSP, ImmediateVal(8)),
|
stack.drop(),
|
||||||
Push(RAX)
|
stack.push(RAX)
|
||||||
// TODO CHECK DIVISOR IS NOT 0
|
// TODO CHECK DIVISOR IS NOT 0
|
||||||
)
|
)
|
||||||
case BinaryOperator.Mod =>
|
case BinaryOperator.Mod =>
|
||||||
evalExprOntoStack(y) ++
|
evalExprOntoStack(y) ++
|
||||||
evalExprOntoStack(x) ++
|
evalExprOntoStack(x) ++
|
||||||
List(
|
List(
|
||||||
Pop(RAX),
|
stack.pop(RAX),
|
||||||
Divide(MemLocation(RSP, SizeDir.Word)),
|
Divide(stack.head(SizeDir.Word)),
|
||||||
Add(RSP, ImmediateVal(8)),
|
stack.drop(),
|
||||||
Push(RDX)
|
stack.push(RDX)
|
||||||
// TODO CHECK DIVISOR IS NOT 0
|
// TODO CHECK DIVISOR IS NOT 0
|
||||||
)
|
)
|
||||||
case BinaryOperator.Eq =>
|
case BinaryOperator.Eq =>
|
||||||
@ -281,15 +277,15 @@ object asmGenerator {
|
|||||||
evalExprOntoStack(x) ++
|
evalExprOntoStack(x) ++
|
||||||
evalExprOntoStack(y) ++
|
evalExprOntoStack(y) ++
|
||||||
List(
|
List(
|
||||||
Pop(RAX),
|
stack.pop(RAX),
|
||||||
And(MemLocation(RSP, SizeDir.Word), EAX)
|
And(stack.head(SizeDir.Word), EAX)
|
||||||
)
|
)
|
||||||
case BinaryOperator.Or =>
|
case BinaryOperator.Or =>
|
||||||
evalExprOntoStack(x) ++
|
evalExprOntoStack(x) ++
|
||||||
evalExprOntoStack(y) ++
|
evalExprOntoStack(y) ++
|
||||||
List(
|
List(
|
||||||
Pop(RAX),
|
stack.pop(RAX),
|
||||||
Or(MemLocation(RSP, SizeDir.Word), EAX)
|
Or(stack.head(SizeDir.Word), EAX)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case call: microWacc.Call => generateCall(call)
|
case call: microWacc.Call => generateCall(call)
|
||||||
@ -297,24 +293,24 @@ object asmGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def generateCall(call: microWacc.Call)(using
|
def generateCall(call: microWacc.Call)(using
|
||||||
stack: LinkedHashMap[Ident, Int],
|
stack: Stack,
|
||||||
strings: ListBuffer[String]
|
strings: ListBuffer[String]
|
||||||
): List[AsmLine] = {
|
): List[AsmLine] = {
|
||||||
val argRegs = List(RDI, RSI, RDX, RCX, R8, R9)
|
val argRegs = List(RDI, RSI, RDX, RCX, R8, R9)
|
||||||
val microWacc.Call(target, args) = call
|
val microWacc.Call(target, args) = call
|
||||||
argRegs.zip(args).flatMap { (reg, expr) =>
|
argRegs.zip(args).flatMap { (reg, expr) =>
|
||||||
evalExprOntoStack(expr) ++
|
evalExprOntoStack(expr) ++
|
||||||
List(Pop(reg))
|
List(stack.pop(reg))
|
||||||
} ++
|
} ++
|
||||||
args.drop(argRegs.size).flatMap(evalExprOntoStack) ++
|
args.drop(argRegs.size).flatMap(evalExprOntoStack) ++
|
||||||
List(assemblyIR.Call(LabelArg(labelGenerator.getLabel(target)))) ++
|
List(assemblyIR.Call(LabelArg(labelGenerator.getLabel(target)))) ++
|
||||||
(if (args.size > argRegs.size) {
|
(if (args.size > argRegs.size) {
|
||||||
List(Load(RSP, IndexAddress(RSP, (args.size - argRegs.size) * 8)))
|
List(stack.reserve(args.size - argRegs.size))
|
||||||
} else Nil)
|
} else Nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// def readIntoVar(dest: IndexAddress, readType: Builtin.ReadInt.type | Builtin.ReadChar.type)(using
|
// def readIntoVar(dest: IndexAddress, readType: Builtin.ReadInt.type | Builtin.ReadChar.type)(using
|
||||||
// stack: LinkedHashMap[Ident, Int],
|
// stack: Stack,
|
||||||
// strings: ListBuffer[String]
|
// strings: ListBuffer[String]
|
||||||
// ): List[AsmLine] = {
|
// ): List[AsmLine] = {
|
||||||
// readType match {
|
// readType match {
|
||||||
@ -339,41 +335,33 @@ object asmGenerator {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
def generateComparison(x: Expr, y: Expr, cond: Cond)(using
|
def generateComparison(x: Expr, y: Expr, cond: Cond)(using
|
||||||
stack: LinkedHashMap[Ident, Int],
|
stack: Stack,
|
||||||
strings: ListBuffer[String]
|
strings: ListBuffer[String]
|
||||||
): List[AsmLine] = {
|
): List[AsmLine] = {
|
||||||
evalExprOntoStack(x) ++
|
evalExprOntoStack(x) ++
|
||||||
evalExprOntoStack(y) ++
|
evalExprOntoStack(y) ++
|
||||||
List(
|
List(
|
||||||
Pop(RAX),
|
stack.pop(RAX),
|
||||||
Compare(MemLocation(RSP, SizeDir.Word), EAX),
|
Compare(stack.head(SizeDir.Word), EAX),
|
||||||
Set(Register(RegSize.Byte, RegName.AL), cond),
|
Set(Register(RegSize.Byte, RegName.AL), cond),
|
||||||
And(EAX, ImmediateVal(_8_BIT_MASK)),
|
And(RAX, ImmediateVal(_8_BIT_MASK)),
|
||||||
Load(RSP, IndexAddress(RSP, 8)),
|
stack.drop(),
|
||||||
Push(RAX)
|
stack.push(RAX)
|
||||||
)
|
|
||||||
}
|
|
||||||
def accessVar(ident: Ident)(using stack: LinkedHashMap[Ident, Int]): () => IndexAddress =
|
|
||||||
() => IndexAddress(RSP, (stack.size - stack(ident)) * 8)
|
|
||||||
|
|
||||||
def alignStack()(using stack: LinkedHashMap[Ident, Int]): List[AsmLine] = {
|
|
||||||
List(
|
|
||||||
And(RSP, ImmediateVal(-16))
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Missing a sub instruction but dont think we need it
|
// Missing a sub instruction but dont think we need it
|
||||||
def funcPrologue(): List[AsmLine] = {
|
def funcPrologue()(using stack: Stack): List[AsmLine] = {
|
||||||
List(
|
List(
|
||||||
Push(RBP),
|
stack.push(RBP),
|
||||||
Move(RBP, RSP)
|
Move(RBP, Register(RegSize.R64, RegName.SP))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def funcEpilogue(): List[AsmLine] = {
|
def funcEpilogue()(using stack: Stack): List[AsmLine] = {
|
||||||
List(
|
List(
|
||||||
Move(RSP, RBP),
|
Move(Register(RegSize.R64, RegName.SP), RBP),
|
||||||
Pop(RBP),
|
stack.pop(RBP),
|
||||||
assemblyIR.Return()
|
assemblyIR.Return()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -383,7 +371,7 @@ object asmGenerator {
|
|||||||
|
|
||||||
// TODO: refactor, really ugly function
|
// TODO: refactor, really ugly function
|
||||||
// def printF(expr: Expr)(using
|
// def printF(expr: Expr)(using
|
||||||
// stack: LinkedHashMap[Ident, Int],
|
// stack: Stack,
|
||||||
// strings: ListBuffer[String]
|
// strings: ListBuffer[String]
|
||||||
// ): List[AsmLine] = {
|
// ): List[AsmLine] = {
|
||||||
// // determine the format string
|
// // determine the format string
|
||||||
@ -442,7 +430,7 @@ object asmGenerator {
|
|||||||
|
|
||||||
// prints a new line
|
// prints a new line
|
||||||
// def printLn()(using
|
// def printLn()(using
|
||||||
// stack: LinkedHashMap[Ident, Int],
|
// stack: Stack,
|
||||||
// strings: ListBuffer[String]
|
// strings: ListBuffer[String]
|
||||||
// ): List[AsmLine] = {
|
// ): List[AsmLine] = {
|
||||||
// strings += ""
|
// strings += ""
|
||||||
@ -461,4 +449,44 @@ object asmGenerator {
|
|||||||
// )
|
// )
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
class Stack {
|
||||||
|
private val stack = LinkedHashMap[Expr | Int, Int]()
|
||||||
|
private val RSP = Register(RegSize.R64, RegName.SP)
|
||||||
|
|
||||||
|
def next: Int = stack.size + 1
|
||||||
|
def push(expr: Expr, src: Src): AsmLine = {
|
||||||
|
stack += expr -> next
|
||||||
|
Push(src)
|
||||||
|
}
|
||||||
|
def push(src: Src): AsmLine = {
|
||||||
|
stack += stack.size -> next
|
||||||
|
Push(src)
|
||||||
|
}
|
||||||
|
def pop(dest: Src): AsmLine = {
|
||||||
|
stack.remove(stack.last._1)
|
||||||
|
Pop(dest)
|
||||||
|
}
|
||||||
|
def reserve(ident: Ident): AsmLine = {
|
||||||
|
stack += ident -> next
|
||||||
|
Subtract(RSP, ImmediateVal(8))
|
||||||
|
}
|
||||||
|
def reserve(n: Int = 1): AsmLine = {
|
||||||
|
(1 to n).foreach(_ => stack += stack.size -> next)
|
||||||
|
Subtract(RSP, ImmediateVal(n*8))
|
||||||
|
}
|
||||||
|
def drop(n : Int = 1): AsmLine = {
|
||||||
|
(1 to n).foreach(_ => stack.remove(stack.last._1))
|
||||||
|
Add(RSP, ImmediateVal(n*8))
|
||||||
|
}
|
||||||
|
def accessVar(ident: Ident): () => IndexAddress = () => {
|
||||||
|
IndexAddress(RSP, (stack.size - stack(ident)) * 8)
|
||||||
|
}
|
||||||
|
def head: MemLocation = MemLocation(RSP)
|
||||||
|
def head(size: SizeDir): MemLocation = MemLocation(RSP, size)
|
||||||
|
def contains(ident: Ident): Boolean = stack.contains(ident)
|
||||||
|
// TODO: Might want to actually properly handle this with the LinkedHashMap too
|
||||||
|
def align(): AsmLine = And(RSP, ImmediateVal(-16))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user