refactor: rename local builder chain to asm

This commit is contained in:
Jonny
2025-02-28 13:55:02 +00:00
parent 302099ab76
commit 621849dfa4

View File

@@ -82,11 +82,11 @@ object asmGenerator {
private def wrapBuiltinFunc(labelName: String, funcBody: Chain[AsmLine])(using private def wrapBuiltinFunc(labelName: String, funcBody: Chain[AsmLine])(using
stack: Stack stack: Stack
): Chain[AsmLine] = { ): Chain[AsmLine] = {
var chain = Chain.one[AsmLine](LabelDef(labelName)) var asm = Chain.one[AsmLine](LabelDef(labelName))
chain ++= funcPrologue() asm ++= funcPrologue()
chain ++= funcBody asm ++= funcBody
chain ++= funcEpilogue() asm ++= funcEpilogue()
chain asm
} }
private def generateUserFunc(func: FuncDecl)(using private def generateUserFunc(func: FuncDecl)(using
@@ -97,29 +97,29 @@ object asmGenerator {
// Setup the stack with param 7 and up // Setup the stack with param 7 and up
func.params.drop(argRegs.size).foreach(stack.reserve(_)) func.params.drop(argRegs.size).foreach(stack.reserve(_))
stack.reserve(Q64) // Reserve return pointer slot stack.reserve(Q64) // Reserve return pointer slot
var chain = Chain.one[AsmLine](LabelDef(labelGenerator.getLabel(func.name))) var asm = Chain.one[AsmLine](LabelDef(labelGenerator.getLabel(func.name)))
chain ++= funcPrologue() asm ++= funcPrologue()
// Push the rest of params onto the stack for simplicity // Push the rest of params onto the stack for simplicity
argRegs.zip(func.params).foreach { (reg, param) => argRegs.zip(func.params).foreach { (reg, param) =>
chain += stack.push(param, Register(Q64, reg)) asm += stack.push(param, Register(Q64, reg))
} }
chain ++= func.body.foldMap(generateStmt(_)) asm ++= func.body.foldMap(generateStmt(_))
// No need for epilogue here since all user functions must return explicitly // No need for epilogue here since all user functions must return explicitly
chain asm
} }
private def generateBuiltInFuncs()(using private def generateBuiltInFuncs()(using
stack: Stack, stack: Stack,
labelGenerator: LabelGenerator labelGenerator: LabelGenerator
): Chain[AsmLine] = { ): Chain[AsmLine] = {
var chain = Chain.empty[AsmLine] var asm = Chain.empty[AsmLine]
chain ++= wrapBuiltinFunc( asm ++= wrapBuiltinFunc(
labelGenerator.getLabel(Builtin.Exit), labelGenerator.getLabel(Builtin.Exit),
Chain(stackAlign, assemblyIR.Call(CLibFunc.Exit)) Chain(stackAlign, assemblyIR.Call(CLibFunc.Exit))
) )
chain ++= wrapBuiltinFunc( asm ++= wrapBuiltinFunc(
labelGenerator.getLabel(Builtin.Printf), labelGenerator.getLabel(Builtin.Printf),
Chain( Chain(
stackAlign, stackAlign,
@@ -129,7 +129,7 @@ object asmGenerator {
) )
) )
chain ++= wrapBuiltinFunc( asm ++= wrapBuiltinFunc(
labelGenerator.getLabel(Builtin.PrintCharArray), labelGenerator.getLabel(Builtin.PrintCharArray),
Chain( Chain(
stackAlign, stackAlign,
@@ -141,7 +141,7 @@ object asmGenerator {
) )
) )
chain ++= wrapBuiltinFunc( asm ++= wrapBuiltinFunc(
labelGenerator.getLabel(Builtin.Malloc), labelGenerator.getLabel(Builtin.Malloc),
Chain( Chain(
stackAlign, stackAlign,
@@ -152,7 +152,7 @@ object asmGenerator {
) )
) )
chain ++= wrapBuiltinFunc( asm ++= wrapBuiltinFunc(
labelGenerator.getLabel(Builtin.Free), labelGenerator.getLabel(Builtin.Free),
Chain( Chain(
stackAlign, stackAlign,
@@ -163,7 +163,7 @@ object asmGenerator {
) )
) )
chain ++= wrapBuiltinFunc( asm ++= wrapBuiltinFunc(
labelGenerator.getLabel(Builtin.Read), labelGenerator.getLabel(Builtin.Read),
Chain( Chain(
stackAlign, stackAlign,
@@ -175,9 +175,9 @@ object asmGenerator {
) )
) )
chain ++= RuntimeError.all.foldMap(_.generateHandler) asm ++= RuntimeError.all.foldMap(_.generateHandler)
chain asm
} }
private def generateStmt(stmt: Stmt)(using private def generateStmt(stmt: Stmt)(using
@@ -185,33 +185,33 @@ object asmGenerator {
strings: ListBuffer[String], strings: ListBuffer[String],
labelGenerator: LabelGenerator labelGenerator: LabelGenerator
): Chain[AsmLine] = { ): Chain[AsmLine] = {
var chain = Chain.empty[AsmLine] var asm = Chain.empty[AsmLine]
chain += Comment(stmt.toString) asm += Comment(stmt.toString)
stmt match { stmt match {
case Assign(lhs, rhs) => case Assign(lhs, rhs) =>
lhs match { lhs match {
case ident: Ident => case ident: Ident =>
if (!stack.contains(ident)) chain += stack.reserve(ident) if (!stack.contains(ident)) asm += stack.reserve(ident)
chain ++= evalExprOntoStack(rhs) asm ++= evalExprOntoStack(rhs)
chain += stack.pop(RAX) asm += stack.pop(RAX)
chain += Move(stack.accessVar(ident), RAX) asm += Move(stack.accessVar(ident), RAX)
case ArrayElem(x, i) => case ArrayElem(x, i) =>
chain ++= evalExprOntoStack(rhs) asm ++= evalExprOntoStack(rhs)
chain ++= evalExprOntoStack(i) asm ++= evalExprOntoStack(i)
chain += stack.pop(RCX) asm += stack.pop(RCX)
chain += Compare(ECX, ImmediateVal(0)) asm += Compare(ECX, ImmediateVal(0))
chain += Jump(LabelArg(OutOfBoundsError.errLabel), Cond.Less) asm += Jump(LabelArg(OutOfBoundsError.errLabel), Cond.Less)
chain += stack.push(Q64, RCX) asm += stack.push(Q64, RCX)
chain ++= evalExprOntoStack(x) asm ++= evalExprOntoStack(x)
chain += stack.pop(RAX) asm += stack.pop(RAX)
chain += stack.pop(RCX) asm += stack.pop(RCX)
chain += Compare(EAX, ImmediateVal(0)) asm += Compare(EAX, ImmediateVal(0))
chain += Jump(LabelArg(NullPtrError.errLabel), Cond.Equal) asm += Jump(LabelArg(NullPtrError.errLabel), Cond.Equal)
chain += Compare(MemLocation(RAX, D32), ECX) asm += Compare(MemLocation(RAX, D32), ECX)
chain += Jump(LabelArg(OutOfBoundsError.errLabel), Cond.LessEqual) asm += Jump(LabelArg(OutOfBoundsError.errLabel), Cond.LessEqual)
chain += stack.pop(RDX) asm += stack.pop(RDX)
chain += Move( asm += Move(
IndexAddress(RAX, KnownType.Int.size.toInt, RCX, x.ty.elemSize.toInt), IndexAddress(RAX, KnownType.Int.size.toInt, RCX, x.ty.elemSize.toInt),
Register(x.ty.elemSize, DX) Register(x.ty.elemSize, DX)
) )
@@ -221,47 +221,47 @@ object asmGenerator {
val elseLabel = labelGenerator.getLabel() val elseLabel = labelGenerator.getLabel()
val endLabel = labelGenerator.getLabel() val endLabel = labelGenerator.getLabel()
chain ++= evalExprOntoStack(cond) asm ++= evalExprOntoStack(cond)
chain += stack.pop(RAX) asm += stack.pop(RAX)
chain += Compare(RAX, ImmediateVal(0)) asm += Compare(RAX, ImmediateVal(0))
chain += Jump(LabelArg(elseLabel), Cond.Equal) asm += Jump(LabelArg(elseLabel), Cond.Equal)
chain ++= stack.withScope(() => thenBranch.foldMap(generateStmt)) asm ++= stack.withScope(() => thenBranch.foldMap(generateStmt))
chain += Jump(LabelArg(endLabel)) asm += Jump(LabelArg(endLabel))
chain += LabelDef(elseLabel) asm += LabelDef(elseLabel)
chain ++= stack.withScope(() => elseBranch.foldMap(generateStmt)) asm ++= stack.withScope(() => elseBranch.foldMap(generateStmt))
chain += LabelDef(endLabel) asm += LabelDef(endLabel)
case While(cond, body) => case While(cond, body) =>
val startLabel = labelGenerator.getLabel() val startLabel = labelGenerator.getLabel()
val endLabel = labelGenerator.getLabel() val endLabel = labelGenerator.getLabel()
chain += LabelDef(startLabel) asm += LabelDef(startLabel)
chain ++= evalExprOntoStack(cond) asm ++= evalExprOntoStack(cond)
chain += stack.pop(RAX) asm += stack.pop(RAX)
chain += Compare(RAX, ImmediateVal(0)) asm += Compare(RAX, ImmediateVal(0))
chain += Jump(LabelArg(endLabel), Cond.Equal) asm += Jump(LabelArg(endLabel), Cond.Equal)
chain ++= stack.withScope(() => body.foldMap(generateStmt)) asm ++= stack.withScope(() => body.foldMap(generateStmt))
chain += Jump(LabelArg(startLabel)) asm += Jump(LabelArg(startLabel))
chain += LabelDef(endLabel) asm += LabelDef(endLabel)
case call: microWacc.Call => case call: microWacc.Call =>
chain ++= generateCall(call, isTail = false) asm ++= generateCall(call, isTail = false)
case microWacc.Return(expr) => case microWacc.Return(expr) =>
expr match { expr match {
case call: microWacc.Call => case call: microWacc.Call =>
chain ++= generateCall(call, isTail = true) // tco asm ++= generateCall(call, isTail = true) // tco
case _ => case _ =>
chain ++= evalExprOntoStack(expr) asm ++= evalExprOntoStack(expr)
chain += stack.pop(RAX) asm += stack.pop(RAX)
chain ++= funcEpilogue() asm ++= funcEpilogue()
} }
} }
chain asm
} }
private def evalExprOntoStack(expr: Expr)(using private def evalExprOntoStack(expr: Expr)(using
@@ -269,138 +269,138 @@ object asmGenerator {
strings: ListBuffer[String], strings: ListBuffer[String],
labelGenerator: LabelGenerator labelGenerator: LabelGenerator
): Chain[AsmLine] = { ): Chain[AsmLine] = {
var chain = Chain.empty[AsmLine] var asm = Chain.empty[AsmLine]
val stackSizeStart = stack.size val stackSizeStart = stack.size
expr match { expr match {
case IntLiter(v) => chain += stack.push(KnownType.Int.size, ImmediateVal(v)) case IntLiter(v) => asm += stack.push(KnownType.Int.size, ImmediateVal(v))
case CharLiter(v) => chain += stack.push(KnownType.Char.size, ImmediateVal(v.toInt)) case CharLiter(v) => asm += stack.push(KnownType.Char.size, ImmediateVal(v.toInt))
case ident: Ident => chain += stack.push(ident.ty.size, stack.accessVar(ident)) case ident: Ident => asm += stack.push(ident.ty.size, stack.accessVar(ident))
case array @ ArrayLiter(elems) => case array @ ArrayLiter(elems) =>
expr.ty match { expr.ty match {
case KnownType.String => case KnownType.String =>
strings += elems.collect { case CharLiter(v) => v }.mkString strings += elems.collect { case CharLiter(v) => v }.mkString
chain += Load(RAX, IndexAddress(RIP, LabelArg(s".L.str${strings.size - 1}"))) asm += Load(RAX, IndexAddress(RIP, LabelArg(s".L.str${strings.size - 1}")))
chain += stack.push(Q64, RAX) asm += stack.push(Q64, RAX)
case ty => case ty =>
chain ++= generateCall( asm ++= generateCall(
microWacc.Call(Builtin.Malloc, List(IntLiter(array.heapSize))), microWacc.Call(Builtin.Malloc, List(IntLiter(array.heapSize))),
isTail = false isTail = false
) )
chain += stack.push(Q64, RAX) asm += stack.push(Q64, RAX)
// Store the length of the array at the start // Store the length of the array at the start
chain += Move(MemLocation(RAX, D32), ImmediateVal(elems.size)) asm += Move(MemLocation(RAX, D32), ImmediateVal(elems.size))
elems.zipWithIndex.foldMap { (elem, i) => elems.zipWithIndex.foldMap { (elem, i) =>
chain ++= evalExprOntoStack(elem) asm ++= evalExprOntoStack(elem)
chain += stack.pop(RCX) asm += stack.pop(RCX)
chain += stack.pop(RAX) asm += stack.pop(RAX)
chain += Move(IndexAddress(RAX, 4 + i * ty.elemSize.toInt), Register(ty.elemSize, CX)) asm += Move(IndexAddress(RAX, 4 + i * ty.elemSize.toInt), Register(ty.elemSize, CX))
chain += stack.push(Q64, RAX) asm += stack.push(Q64, RAX)
} }
} }
case BoolLiter(true) => case BoolLiter(true) =>
chain += stack.push(KnownType.Bool.size, ImmediateVal(1)) asm += stack.push(KnownType.Bool.size, ImmediateVal(1))
case BoolLiter(false) => case BoolLiter(false) =>
chain += Xor(RAX, RAX) asm += Xor(RAX, RAX)
chain += stack.push(KnownType.Bool.size, RAX) asm += stack.push(KnownType.Bool.size, RAX)
case NullLiter() => case NullLiter() =>
chain += stack.push(KnownType.Pair(?, ?).size, ImmediateVal(0)) asm += stack.push(KnownType.Pair(?, ?).size, ImmediateVal(0))
case ArrayElem(x, i) => case ArrayElem(x, i) =>
chain ++= evalExprOntoStack(x) asm ++= evalExprOntoStack(x)
chain ++= evalExprOntoStack(i) asm ++= evalExprOntoStack(i)
chain += stack.pop(RCX) asm += stack.pop(RCX)
chain += Compare(RCX, ImmediateVal(0)) asm += Compare(RCX, ImmediateVal(0))
chain += Jump(LabelArg(OutOfBoundsError.errLabel), Cond.Less) asm += Jump(LabelArg(OutOfBoundsError.errLabel), Cond.Less)
chain += stack.pop(RAX) asm += stack.pop(RAX)
chain += Compare(EAX, ImmediateVal(0)) asm += Compare(EAX, ImmediateVal(0))
chain += Jump(LabelArg(NullPtrError.errLabel), Cond.Equal) asm += Jump(LabelArg(NullPtrError.errLabel), Cond.Equal)
chain += Compare(MemLocation(RAX, D32), ECX) asm += Compare(MemLocation(RAX, D32), ECX)
chain += Jump(LabelArg(OutOfBoundsError.errLabel), Cond.LessEqual) asm += Jump(LabelArg(OutOfBoundsError.errLabel), Cond.LessEqual)
// + Int because we store the length of the array at the start // + Int because we store the length of the array at the start
chain += Move( asm += Move(
Register(x.ty.elemSize, AX), Register(x.ty.elemSize, AX),
IndexAddress(RAX, KnownType.Int.size.toInt, RCX, x.ty.elemSize.toInt) IndexAddress(RAX, KnownType.Int.size.toInt, RCX, x.ty.elemSize.toInt)
) )
chain += stack.push(x.ty.elemSize, RAX) asm += stack.push(x.ty.elemSize, RAX)
case UnaryOp(x, op) => case UnaryOp(x, op) =>
chain ++= evalExprOntoStack(x) asm ++= evalExprOntoStack(x)
op match { op match {
case UnaryOperator.Chr => case UnaryOperator.Chr =>
chain += Move(EAX, stack.head) asm += Move(EAX, stack.head)
chain += And(EAX, ImmediateVal(~_7_BIT_MASK)) asm += And(EAX, ImmediateVal(~_7_BIT_MASK))
chain += Compare(EAX, ImmediateVal(0)) asm += Compare(EAX, ImmediateVal(0))
chain += Jump(LabelArg(BadChrError.errLabel), Cond.NotEqual) asm += Jump(LabelArg(BadChrError.errLabel), Cond.NotEqual)
case UnaryOperator.Ord => // No op needed case UnaryOperator.Ord => // No op needed
case UnaryOperator.Len => case UnaryOperator.Len =>
chain += stack.pop(RAX) asm += stack.pop(RAX)
chain += Move(EAX, MemLocation(RAX, D32)) asm += Move(EAX, MemLocation(RAX, D32))
chain += stack.push(D32, RAX) asm += stack.push(D32, RAX)
case UnaryOperator.Negate => case UnaryOperator.Negate =>
chain += Xor(EAX, EAX) asm += Xor(EAX, EAX)
chain += Subtract(EAX, stack.head) asm += Subtract(EAX, stack.head)
chain += Jump(LabelArg(OverflowError.errLabel), Cond.Overflow) asm += Jump(LabelArg(OverflowError.errLabel), Cond.Overflow)
chain += stack.drop() asm += stack.drop()
chain += stack.push(Q64, RAX) asm += stack.push(Q64, RAX)
case UnaryOperator.Not => case UnaryOperator.Not =>
chain += Xor(stack.head, ImmediateVal(1)) asm += Xor(stack.head, ImmediateVal(1))
} }
case BinaryOp(x, y, op) => case BinaryOp(x, y, op) =>
val destX = Register(x.ty.size, AX) val destX = Register(x.ty.size, AX)
chain ++= evalExprOntoStack(y) asm ++= evalExprOntoStack(y)
chain ++= evalExprOntoStack(x) asm ++= evalExprOntoStack(x)
chain += stack.pop(RAX) asm += stack.pop(RAX)
op match { op match {
case BinaryOperator.Add => case BinaryOperator.Add =>
chain += Add(stack.head, destX) asm += Add(stack.head, destX)
chain += Jump(LabelArg(OverflowError.errLabel), Cond.Overflow) asm += Jump(LabelArg(OverflowError.errLabel), Cond.Overflow)
case BinaryOperator.Sub => case BinaryOperator.Sub =>
chain += Subtract(destX, stack.head) asm += Subtract(destX, stack.head)
chain += Jump(LabelArg(OverflowError.errLabel), Cond.Overflow) asm += Jump(LabelArg(OverflowError.errLabel), Cond.Overflow)
chain += stack.drop() asm += stack.drop()
chain += stack.push(destX.size, RAX) asm += stack.push(destX.size, RAX)
case BinaryOperator.Mul => case BinaryOperator.Mul =>
chain += Multiply(destX, stack.head) asm += Multiply(destX, stack.head)
chain += Jump(LabelArg(OverflowError.errLabel), Cond.Overflow) asm += Jump(LabelArg(OverflowError.errLabel), Cond.Overflow)
chain += stack.drop() asm += stack.drop()
chain += stack.push(destX.size, RAX) asm += stack.push(destX.size, RAX)
case BinaryOperator.Div => case BinaryOperator.Div =>
chain += Compare(stack.head, ImmediateVal(0)) asm += Compare(stack.head, ImmediateVal(0))
chain += Jump(LabelArg(ZeroDivError.errLabel), Cond.Equal) asm += Jump(LabelArg(ZeroDivError.errLabel), Cond.Equal)
chain += CDQ() asm += CDQ()
chain += Divide(stack.head) asm += Divide(stack.head)
chain += stack.drop() asm += stack.drop()
chain += stack.push(destX.size, RAX) asm += stack.push(destX.size, RAX)
case BinaryOperator.Mod => case BinaryOperator.Mod =>
chain += Compare(stack.head, ImmediateVal(0)) asm += Compare(stack.head, ImmediateVal(0))
chain += Jump(LabelArg(ZeroDivError.errLabel), Cond.Equal) asm += Jump(LabelArg(ZeroDivError.errLabel), Cond.Equal)
chain += CDQ() asm += CDQ()
chain += Divide(stack.head) asm += Divide(stack.head)
chain += stack.drop() asm += stack.drop()
chain += stack.push(destX.size, RDX) asm += stack.push(destX.size, RDX)
case BinaryOperator.Eq => chain ++= generateComparison(destX, Cond.Equal) case BinaryOperator.Eq => asm ++= generateComparison(destX, Cond.Equal)
case BinaryOperator.Neq => chain ++= generateComparison(destX, Cond.NotEqual) case BinaryOperator.Neq => asm ++= generateComparison(destX, Cond.NotEqual)
case BinaryOperator.Greater => chain ++= generateComparison(destX, Cond.Greater) case BinaryOperator.Greater => asm ++= generateComparison(destX, Cond.Greater)
case BinaryOperator.GreaterEq => chain ++= generateComparison(destX, Cond.GreaterEqual) case BinaryOperator.GreaterEq => asm ++= generateComparison(destX, Cond.GreaterEqual)
case BinaryOperator.Less => chain ++= generateComparison(destX, Cond.Less) case BinaryOperator.Less => asm ++= generateComparison(destX, Cond.Less)
case BinaryOperator.LessEq => chain ++= generateComparison(destX, Cond.LessEqual) case BinaryOperator.LessEq => asm ++= generateComparison(destX, Cond.LessEqual)
case BinaryOperator.And => chain += And(stack.head, destX) case BinaryOperator.And => asm += And(stack.head, destX)
case BinaryOperator.Or => chain += Or(stack.head, destX) case BinaryOperator.Or => asm += Or(stack.head, destX)
} }
case call: microWacc.Call => case call: microWacc.Call =>
chain ++= generateCall(call, isTail = false) asm ++= generateCall(call, isTail = false)
chain += stack.push(call.ty.size, RAX) asm += stack.push(call.ty.size, RAX)
} }
assert(stack.size == stackSizeStart + 1) assert(stack.size == stackSizeStart + 1)
chain ++= zeroRest(MemLocation(stack.head.pointer, Q64), expr.ty.size) asm ++= zeroRest(MemLocation(stack.head.pointer, Q64), expr.ty.size)
chain asm
} }
private def generateCall(call: microWacc.Call, isTail: Boolean)(using private def generateCall(call: microWacc.Call, isTail: Boolean)(using
@@ -408,65 +408,65 @@ object asmGenerator {
strings: ListBuffer[String], strings: ListBuffer[String],
labelGenerator: LabelGenerator labelGenerator: LabelGenerator
): Chain[AsmLine] = { ): Chain[AsmLine] = {
var chain = Chain.empty[AsmLine] var asm = Chain.empty[AsmLine]
val microWacc.Call(target, args) = call val microWacc.Call(target, args) = call
argRegs argRegs
.zip(args) .zip(args)
.map { (reg, expr) => .map { (reg, expr) =>
chain ++= evalExprOntoStack(expr) asm ++= evalExprOntoStack(expr)
reg reg
} }
.reverse .reverse
.foreach { reg => .foreach { reg =>
chain += stack.pop(Register(Q64, reg)) asm += stack.pop(Register(Q64, reg))
} }
args.drop(argRegs.size).foldMap { args.drop(argRegs.size).foldMap {
chain ++= evalExprOntoStack(_) asm ++= evalExprOntoStack(_)
} }
// Tail Call Optimisation (TCO) // Tail Call Optimisation (TCO)
if (isTail) { if (isTail) {
chain += Jump(LabelArg(labelGenerator.getLabel(target))) // tail call asm += Jump(LabelArg(labelGenerator.getLabel(target))) // tail call
} else { } else {
chain += assemblyIR.Call(LabelArg(labelGenerator.getLabel(target))) // regular call asm += assemblyIR.Call(LabelArg(labelGenerator.getLabel(target))) // regular call
} }
if (args.size > argRegs.size) { if (args.size > argRegs.size) {
chain += stack.drop(args.size - argRegs.size) asm += stack.drop(args.size - argRegs.size)
} }
chain asm
} }
private def generateComparison(destX: Register, cond: Cond)(using private def generateComparison(destX: Register, cond: Cond)(using
stack: Stack stack: Stack
): Chain[AsmLine] = { ): Chain[AsmLine] = {
var chain = Chain.empty[AsmLine] var asm = Chain.empty[AsmLine]
chain += Compare(destX, stack.head) asm += Compare(destX, stack.head)
chain += Set(Register(B8, AX), cond) asm += Set(Register(B8, AX), cond)
chain ++= zeroRest(RAX, B8) asm ++= zeroRest(RAX, B8)
chain += stack.drop() asm += stack.drop()
chain += stack.push(B8, RAX) asm += stack.push(B8, RAX)
chain asm
} }
private def funcPrologue()(using stack: Stack): Chain[AsmLine] = { private def funcPrologue()(using stack: Stack): Chain[AsmLine] = {
var chain = Chain.empty[AsmLine] var asm = Chain.empty[AsmLine]
chain += stack.push(Q64, RBP) asm += stack.push(Q64, RBP)
chain += Move(RBP, Register(Q64, SP)) asm += Move(RBP, Register(Q64, SP))
chain asm
} }
private def funcEpilogue(): Chain[AsmLine] = { private def funcEpilogue(): Chain[AsmLine] = {
var chain = Chain.empty[AsmLine] var asm = Chain.empty[AsmLine]
chain += Move(Register(Q64, SP), RBP) asm += Move(Register(Q64, SP), RBP)
chain += Pop(RBP) asm += Pop(RBP)
chain += assemblyIR.Return() asm += assemblyIR.Return()
chain asm
} }
def stackAlign: AsmLine = And(Register(Q64, SP), ImmediateVal(-16)) def stackAlign: AsmLine = And(Register(Q64, SP), ImmediateVal(-16))