stage2 codegen: Make sure function return value is in a callee

preserved register
This commit is contained in:
joachimschmidt557 2021-03-27 22:23:14 +01:00 committed by Jakub Konka
parent e088a17f56
commit 1b657e6e41
2 changed files with 51 additions and 0 deletions

View File

@ -2194,6 +2194,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
unreachable;
}
switch (info.return_value) {
.register => |reg| {
if (Register.allocIndex(reg) == null) {
// Save function return value in a callee saved register
return try self.copyToNewRegister(&inst.base, info.return_value);
}
},
else => {},
}
return info.return_value;
}

View File

@ -378,4 +378,45 @@ pub fn addCases(ctx: *TestContext) !void {
"",
);
}
{
var case = ctx.exe("save function return values in callee preserved register", linux_arm);
// Here, it is necessary to save the result of bar() into a
// callee preserved register, otherwise it will be overwritten
// by the first parameter to baz.
case.addCompareOutput(
\\export fn _start() noreturn {
\\ assert(foo() == 43);
\\ exit();
\\}
\\
\\fn foo() u32 {
\\ return bar() + baz(42);
\\}
\\
\\fn bar() u32 {
\\ return 1;
\\}
\\
\\fn baz(x: u32) u32 {
\\ return x;
\\}
\\
\\fn assert(ok: bool) void {
\\ if (!ok) unreachable;
\\}
\\
\\fn exit() noreturn {
\\ asm volatile ("svc #0"
\\ :
\\ : [number] "{r7}" (1),
\\ [arg1] "{r0}" (0)
\\ : "memory"
\\ );
\\ unreachable;
\\}
,
"",
);
}
}