aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-06-29 09:05:34 +0200
committerJakub Konka <kubkon@jakubkonka.com>2022-06-29 17:19:49 +0200
commit59359b25474724018c14b8cb685837f4480c0de5 (patch)
treeff7de3ed01eb147e9717bbdc0e42efb4ced34db0 /src
parent234ccb4a5088cd6fa06144d7ba1aceab0596f1cc (diff)
downloadzig-59359b25474724018c14b8cb685837f4480c0de5.tar.gz
zig-59359b25474724018c14b8cb685837f4480c0de5.zip
aarch64: add airRetLoad for register mcv
Diffstat (limited to 'src')
-rw-r--r--src/arch/aarch64/CodeGen.zig70
1 files changed, 46 insertions, 24 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 {
});
// <store other registers>
- 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 {
+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);
const ret_ty = self.fn_type.fnReturnType();
+
switch (self.ret_mcv) {
+ .none => {},
.immediate => {
assert(ret_ty.isError());
},
- else => {
- try self.setRegOrMem(ret_ty, self.ret_mcv, mcv);
+ .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
- const index = try self.addInst(.{
- .tag = .nop,
- .data = .{ .nop = {} },
- });
- try self.exitlude_jump_relocs.append(self.gpa, index);
-}
+ try self.exitlude_jump_relocs.append(self.gpa, try self.addNop());
-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);
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 {