authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-03-27 22:23:14+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-03-31 23:27:50+02:00
log1b657e6e41bcaf362d1cc9455c17e06e57973554
tree796f29c590abe7d5dc5d0ab5ad195ab8a890e7d0
parente088a17f56a154ecc43c36e8308833d657e6f43e

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

preserved register

2 files changed, 51 insertions(+), 0 deletions(-)

src/codegen.zig+10
...@@ -2194,6 +2194,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2194,6 +2194,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2194 unreachable;2194 unreachable;
2195 }2195 }
21962196
2197 switch (info.return_value) {
2198 .register => |reg| {
2199 if (Register.allocIndex(reg) == null) {
2200 // Save function return value in a callee saved register
2201 return try self.copyToNewRegister(&inst.base, info.return_value);
2202 }
2203 },
2204 else => {},
2205 }
2206
2197 return info.return_value;2207 return info.return_value;
2198 }2208 }
21992209
test/stage2/arm.zig+41
...@@ -378,4 +378,45 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -378,4 +378,45 @@ pub fn addCases(ctx: *TestContext) !void {
378 "",378 "",
379 );379 );
380 }380 }
381
382 {
383 var case = ctx.exe("save function return values in callee preserved register", linux_arm);
384 // Here, it is necessary to save the result of bar() into a
385 // callee preserved register, otherwise it will be overwritten
386 // by the first parameter to baz.
387 case.addCompareOutput(
388 \\export fn _start() noreturn {
389 \\ assert(foo() == 43);
390 \\ exit();
391 \\}
392 \\
393 \\fn foo() u32 {
394 \\ return bar() + baz(42);
395 \\}
396 \\
397 \\fn bar() u32 {
398 \\ return 1;
399 \\}
400 \\
401 \\fn baz(x: u32) u32 {
402 \\ return x;
403 \\}
404 \\
405 \\fn assert(ok: bool) void {
406 \\ if (!ok) unreachable;
407 \\}
408 \\
409 \\fn exit() noreturn {
410 \\ asm volatile ("svc #0"
411 \\ :
412 \\ : [number] "{r7}" (1),
413 \\ [arg1] "{r0}" (0)
414 \\ : "memory"
415 \\ );
416 \\ unreachable;
417 \\}
418 ,
419 "",
420 );
421 }
381}422}