From 59359b25474724018c14b8cb685837f4480c0de5 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 29 Jun 2022 09:05:34 +0200 Subject: [PATCH] aarch64: add airRetLoad for register mcv --- src/arch/aarch64/CodeGen.zig | 82 ++++++++++++------- test/behavior/incomplete_struct_param_tld.zig | 1 - 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 4cf428bd9a..47d7d1282f 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -362,6 +362,13 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { return result_index; } +fn addNop(self: *Self) error{OutOfMemory}!Mir.Inst.Index { + return try self.addInst(.{ + .tag = .nop, + .data = .{ .nop = {} }, + }); +} + pub fn addExtra(self: *Self, extra: anytype) Allocator.Error!u32 { const fields = std.meta.fields(@TypeOf(extra)); try self.mir_extra.ensureUnusedCapacity(self.gpa, fields.len); @@ -396,10 +403,7 @@ fn gen(self: *Self) !void { }); // - const backpatch_save_registers = try self.addInst(.{ - .tag = .nop, - .data = .{ .nop = {} }, - }); + const backpatch_save_registers = try self.addNop(); // mov fp, sp _ = try self.addInst(.{ @@ -408,10 +412,7 @@ fn gen(self: *Self) !void { }); // sub sp, sp, #reloc - const backpatch_reloc = try self.addInst(.{ - .tag = .nop, - .data = .{ .nop = {} }, - }); + const backpatch_reloc = try self.addNop(); _ = try self.addInst(.{ .tag = .dbg_prologue_end, @@ -3261,37 +3262,58 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions. return bt.finishAir(result); } -fn ret(self: *Self, mcv: MCValue) !void { - const ret_ty = self.fn_type.fnReturnType(); - switch (self.ret_mcv) { - .immediate => { - assert(ret_ty.isError()); - }, - else => { - try self.setRegOrMem(ret_ty, self.ret_mcv, mcv); - }, - } - // Just add space for an instruction, patch this later - const index = try self.addInst(.{ - .tag = .nop, - .data = .{ .nop = {} }, - }); - try self.exitlude_jump_relocs.append(self.gpa, index); -} - fn airRet(self: *Self, inst: Air.Inst.Index) !void { const un_op = self.air.instructions.items(.data)[inst].un_op; const operand = try self.resolveInst(un_op); - try self.ret(operand); + const ret_ty = self.fn_type.fnReturnType(); + + switch (self.ret_mcv) { + .none => {}, + .immediate => { + assert(ret_ty.isError()); + }, + .register => |reg| { + // Return result by value + try self.genSetReg(ret_ty, reg, operand); + }, + .stack_offset => { + // Return result by reference + // TODO + return self.fail("TODO implement airRet for {}", .{self.ret_mcv}); + }, + else => unreachable, + } + + // Just add space for an instruction, patch this later + try self.exitlude_jump_relocs.append(self.gpa, try self.addNop()); + return self.finishAir(inst, .dead, .{ un_op, .none, .none }); } fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { const un_op = self.air.instructions.items(.data)[inst].un_op; const ptr = try self.resolveInst(un_op); - _ = ptr; - return self.fail("TODO implement airRetLoad for {}", .{self.target.cpu.arch}); - //return self.finishAir(inst, .dead, .{ un_op, .none, .none }); + const ptr_ty = self.air.typeOf(un_op); + const ret_ty = self.fn_type.fnReturnType(); + _ = ret_ty; + + switch (self.ret_mcv) { + .none => {}, + .register => { + // Return result by value + try self.load(self.ret_mcv, ptr, ptr_ty); + }, + .stack_offset => { + // Return result by reference + // TODO + return self.fail("TODO implement airRetLoad for {}", .{self.ret_mcv}); + }, + else => unreachable, + } + + try self.exitlude_jump_relocs.append(self.gpa, try self.addNop()); + + return self.finishAir(inst, .dead, .{ un_op, .none, .none }); } fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { diff --git a/test/behavior/incomplete_struct_param_tld.zig b/test/behavior/incomplete_struct_param_tld.zig index 385c64dbdb..29f57ed971 100644 --- a/test/behavior/incomplete_struct_param_tld.zig +++ b/test/behavior/incomplete_struct_param_tld.zig @@ -22,7 +22,6 @@ fn foo(a: A) i32 { } test "incomplete struct param top level declaration" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const a = A{ .b = B{ .c = C{ .x = 13 },