Add support for stack parameters

This commit is contained in:
nub31
2025-01-26 20:44:22 +01:00
parent 84b3636e75
commit 6e6a1a830e
3 changed files with 43 additions and 12 deletions

View File

@@ -109,17 +109,16 @@ public class Generator
for (var i = 0; i < symbol.Parameters.Count; i++)
{
var parameter = symbol.Parameters.ElementAt(i);
var parameter = symbol.ResolveLocalVariable(symbol.Parameters.ElementAt(i).Name);
if (i < registers.Length)
{
var variable = symbol.ResolveLocalVariable(parameter.Name);
_builder.AppendLine($" mov [rbp - {variable.Offset}], {registers[i]}");
_builder.AppendLine($" mov [rbp - {parameter.Offset}], {registers[i]}");
}
else
{
// TODO: Implement parameters passed on the stack
throw new NotImplementedException();
var stackOffset = 16 + (i - registers.Length) * 8;
_builder.AppendLine($" mov rax, [rbp + {stackOffset}]");
_builder.AppendLine($" mov [rbp - {parameter.Offset}], rax");
}
}
@@ -262,24 +261,30 @@ public class Generator
_builder.AppendLine(" call strlen");
}
// TODO: Use stack for more than 6 parameters
private void GenerateFuncCall(FuncCall funcCall, Func func)
{
var symbol = _symbolTable.ResolveFunc(funcCall.Name, funcCall.Parameters.Select(p => p.Type).ToList());
string[] registers = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"];
foreach (var parameter in funcCall.Parameters)
for (var i = funcCall.Parameters.Count - 1; i >= 0; i--)
{
GenerateExpression(parameter, func);
GenerateExpression(funcCall.Parameters.ElementAt(i), func);
_builder.AppendLine(" push rax");
}
for (var i = funcCall.Parameters.Count - 1; i >= 0; i--)
var registerParameters = Math.Min(registers.Length, funcCall.Parameters.Count);
var stackParameters = funcCall.Parameters.Count - registerParameters;
for (var i = 0; i < registerParameters; i++)
{
_builder.AppendLine($" pop {registers[i]}");
}
_builder.AppendLine($" call {symbol.Label}");
if (stackParameters != 0)
{
_builder.AppendLine($" add rsp, {stackParameters}");
}
}
private void GenerateSyscall(Syscall syscall, Func func)

View File

@@ -4,7 +4,32 @@ let STD_OUT = 1;
let STD_ERR = 2;
func main() {
write("test\n");
test
(
"a\n",
"b\n",
"c\n",
"d\n",
"e\n",
"f\n",
"g\n",
"h\n",
"i\n",
"j\n",
);
}
func test(a: String, b: String, c: String, d: String, e: String, f: String, g: String, h: String, i: String, j: String) {
write(a);
write(b);
write(c);
write(d);
write(e);
write(f);
write(g);
write(h);
write(i);
write(j);
}
func write(msg: String) {

View File

@@ -56,6 +56,7 @@ public class Parser
while (!TryExpectSymbol(Symbol.CloseParen))
{
parameters.Add(ParseFuncParameter());
TryExpectSymbol(Symbol.Comma);
}
}