Add support for stack parameters
This commit is contained in:
@@ -109,17 +109,16 @@ public class Generator
|
|||||||
|
|
||||||
for (var i = 0; i < symbol.Parameters.Count; i++)
|
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)
|
if (i < registers.Length)
|
||||||
{
|
{
|
||||||
var variable = symbol.ResolveLocalVariable(parameter.Name);
|
_builder.AppendLine($" mov [rbp - {parameter.Offset}], {registers[i]}");
|
||||||
_builder.AppendLine($" mov [rbp - {variable.Offset}], {registers[i]}");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: Implement parameters passed on the stack
|
var stackOffset = 16 + (i - registers.Length) * 8;
|
||||||
throw new NotImplementedException();
|
_builder.AppendLine($" mov rax, [rbp + {stackOffset}]");
|
||||||
|
_builder.AppendLine($" mov [rbp - {parameter.Offset}], rax");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,24 +261,30 @@ public class Generator
|
|||||||
_builder.AppendLine(" call strlen");
|
_builder.AppendLine(" call strlen");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use stack for more than 6 parameters
|
|
||||||
private void GenerateFuncCall(FuncCall funcCall, Func func)
|
private void GenerateFuncCall(FuncCall funcCall, Func func)
|
||||||
{
|
{
|
||||||
var symbol = _symbolTable.ResolveFunc(funcCall.Name, funcCall.Parameters.Select(p => p.Type).ToList());
|
var symbol = _symbolTable.ResolveFunc(funcCall.Name, funcCall.Parameters.Select(p => p.Type).ToList());
|
||||||
string[] registers = ["rdi", "rsi", "rdx", "rcx", "r8", "r9"];
|
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");
|
_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($" pop {registers[i]}");
|
||||||
}
|
}
|
||||||
|
|
||||||
_builder.AppendLine($" call {symbol.Label}");
|
_builder.AppendLine($" call {symbol.Label}");
|
||||||
|
if (stackParameters != 0)
|
||||||
|
{
|
||||||
|
_builder.AppendLine($" add rsp, {stackParameters}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateSyscall(Syscall syscall, Func func)
|
private void GenerateSyscall(Syscall syscall, Func func)
|
||||||
|
|||||||
@@ -4,7 +4,32 @@ let STD_OUT = 1;
|
|||||||
let STD_ERR = 2;
|
let STD_ERR = 2;
|
||||||
|
|
||||||
func main() {
|
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) {
|
func write(msg: String) {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public class Parser
|
|||||||
while (!TryExpectSymbol(Symbol.CloseParen))
|
while (!TryExpectSymbol(Symbol.CloseParen))
|
||||||
{
|
{
|
||||||
parameters.Add(ParseFuncParameter());
|
parameters.Add(ParseFuncParameter());
|
||||||
|
TryExpectSymbol(Symbol.Comma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user