feat: user functions and calls
This commit is contained in:
parent
85190ce174
commit
c748a34e4c
@ -42,6 +42,7 @@ object asmGenerator {
|
|||||||
val RCX = Register(RegSize.R64, RegName.CX)
|
val RCX = Register(RegSize.R64, RegName.CX)
|
||||||
val R8 = Register(RegSize.R64, RegName.Reg8)
|
val R8 = Register(RegSize.R64, RegName.Reg8)
|
||||||
val R9 = Register(RegSize.R64, RegName.Reg9)
|
val R9 = Register(RegSize.R64, RegName.Reg9)
|
||||||
|
val argRegs = List(RDI, RSI, RDX, RCX, R8, R9)
|
||||||
|
|
||||||
val _8_BIT_MASK = 0xff
|
val _8_BIT_MASK = 0xff
|
||||||
|
|
||||||
@ -75,7 +76,8 @@ object asmGenerator {
|
|||||||
main.foldMap(generateStmt(_)),
|
main.foldMap(generateStmt(_)),
|
||||||
Chain.one(Move(RAX, ImmediateVal(0))),
|
Chain.one(Move(RAX, ImmediateVal(0))),
|
||||||
funcEpilogue(),
|
funcEpilogue(),
|
||||||
generateBuiltInFuncs()
|
generateBuiltInFuncs(),
|
||||||
|
funcs.foldMap(generateUserFunc(_))
|
||||||
)
|
)
|
||||||
|
|
||||||
val strDirs = strings.toList.zipWithIndex.foldMap { case (str, i) =>
|
val strDirs = strings.toList.zipWithIndex.foldMap { case (str, i) =>
|
||||||
@ -111,6 +113,22 @@ object asmGenerator {
|
|||||||
chain
|
chain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def generateUserFunc(func: FuncDecl)(using
|
||||||
|
strings: ListBuffer[String],
|
||||||
|
labelGenerator: LabelGenerator
|
||||||
|
): Chain[AsmLine] = {
|
||||||
|
given stack: Stack = Stack()
|
||||||
|
// Setup the stack with param 7 and up
|
||||||
|
func.params.drop(argRegs.size).foreach(stack.reserve(_))
|
||||||
|
var chain = Chain.empty[AsmLine]
|
||||||
|
// Push the rest of params onto the stack for simplicity
|
||||||
|
argRegs.zip(func.params).foreach { (reg, param) =>
|
||||||
|
chain += stack.push(param, reg)
|
||||||
|
}
|
||||||
|
chain ++= func.body.foldMap(generateStmt(_))
|
||||||
|
wrapFunc(labelGenerator.getLabel(func.name), chain)
|
||||||
|
}
|
||||||
|
|
||||||
def generateBuiltInFuncs()(using
|
def generateBuiltInFuncs()(using
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
strings: ListBuffer[String],
|
strings: ListBuffer[String],
|
||||||
@ -223,7 +241,7 @@ object asmGenerator {
|
|||||||
case microWacc.Return(expr) =>
|
case microWacc.Return(expr) =>
|
||||||
chain ++= evalExprOntoStack(expr)
|
chain ++= evalExprOntoStack(expr)
|
||||||
chain += stack.pop(RAX)
|
chain += stack.pop(RAX)
|
||||||
chain += assemblyIR.Return()
|
chain ++= funcEpilogue()
|
||||||
|
|
||||||
case call: microWacc.Call =>
|
case call: microWacc.Call =>
|
||||||
chain ++= generateCall(call)
|
chain ++= generateCall(call)
|
||||||
@ -321,7 +339,6 @@ object asmGenerator {
|
|||||||
labelGenerator: LabelGenerator
|
labelGenerator: LabelGenerator
|
||||||
): Chain[AsmLine] = {
|
): Chain[AsmLine] = {
|
||||||
var chain = Chain.empty[AsmLine]
|
var chain = Chain.empty[AsmLine]
|
||||||
val argRegs = List(RDI, RSI, RDX, RCX, R8, R9)
|
|
||||||
val microWacc.Call(target, args) = call
|
val microWacc.Call(target, args) = call
|
||||||
|
|
||||||
argRegs.zip(args).foldMap { (reg, expr) =>
|
argRegs.zip(args).foldMap { (reg, expr) =>
|
||||||
@ -373,7 +390,7 @@ object asmGenerator {
|
|||||||
def funcEpilogue()(using stack: Stack): Chain[AsmLine] = {
|
def funcEpilogue()(using stack: Stack): Chain[AsmLine] = {
|
||||||
var chain = Chain.empty[AsmLine]
|
var chain = Chain.empty[AsmLine]
|
||||||
chain += Move(Register(RegSize.R64, RegName.SP), RBP)
|
chain += Move(Register(RegSize.R64, RegName.SP), RBP)
|
||||||
chain += stack.pop(RBP)
|
chain += Pop(RBP)
|
||||||
chain += assemblyIR.Return()
|
chain += assemblyIR.Return()
|
||||||
chain
|
chain
|
||||||
}
|
}
|
||||||
@ -382,7 +399,7 @@ object asmGenerator {
|
|||||||
private val stack = LinkedHashMap[Expr | Int, Int]()
|
private val stack = LinkedHashMap[Expr | Int, Int]()
|
||||||
private val RSP = Register(RegSize.R64, RegName.SP)
|
private val RSP = Register(RegSize.R64, RegName.SP)
|
||||||
|
|
||||||
def next: Int = stack.size + 1
|
private def next: Int = stack.size + 1
|
||||||
def push(expr: Expr, src: Src): AsmLine = {
|
def push(expr: Expr, src: Src): AsmLine = {
|
||||||
stack += expr -> next
|
stack += expr -> next
|
||||||
Push(src)
|
Push(src)
|
||||||
|
@ -110,7 +110,7 @@ object typeChecker {
|
|||||||
microWacc.FuncDecl(
|
microWacc.FuncDecl(
|
||||||
microWacc.Ident(name.v, name.uid)(retType),
|
microWacc.Ident(name.v, name.uid)(retType),
|
||||||
params.zip(paramTypes).map { case (ast.Param(_, ident), ty) =>
|
params.zip(paramTypes).map { case (ast.Param(_, ident), ty) =>
|
||||||
microWacc.Ident(ident.v, name.uid)(ty)
|
microWacc.Ident(ident.v, ident.uid)(ty)
|
||||||
},
|
},
|
||||||
stmts.toList
|
stmts.toList
|
||||||
.flatMap(
|
.flatMap(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user