mirror of
https://github.com/ziglang/zig.git
synced 2024-12-03 10:28:48 +00:00
stage2 codegen: Make sure function return value is in a callee
preserved register
This commit is contained in:
parent
e088a17f56
commit
1b657e6e41
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
\\}
|
||||
,
|
||||
"",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user