Commit 8a022d9c92
Changed files (1)
src
arch
aarch64
src/arch/aarch64/CodeGen.zig
@@ -3009,7 +3009,23 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
/// T to E!T
fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement wrap errunion payload for {}", .{self.target.cpu.arch});
+ const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
+ const error_union_ty = self.air.getRefType(ty_op.ty);
+ const error_ty = error_union_ty.errorUnionSet();
+ const payload_ty = error_union_ty.errorUnionPayload();
+ const operand = try self.resolveInst(ty_op.operand);
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand;
+
+ const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*));
+ const abi_align = error_union_ty.abiAlignment(self.target.*);
+ const stack_offset = try self.allocMem(abi_size, abi_align, inst);
+ const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);
+ const err_off = errUnionErrorOffset(payload_ty, self.target.*);
+ try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), operand);
+ try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), .{ .immediate = 0 });
+
+ break :result MCValue{ .stack_offset = stack_offset };
+ };
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}
@@ -3018,11 +3034,20 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
const error_union_ty = self.air.getRefType(ty_op.ty);
+ const error_ty = error_union_ty.errorUnionSet();
const payload_ty = error_union_ty.errorUnionPayload();
- const mcv = try self.resolveInst(ty_op.operand);
- if (!payload_ty.hasRuntimeBits()) break :result mcv;
+ const operand = try self.resolveInst(ty_op.operand);
+ if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand;
+
+ const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*));
+ const abi_align = error_union_ty.abiAlignment(self.target.*);
+ const stack_offset = try self.allocMem(abi_size, abi_align, inst);
+ const payload_off = errUnionPayloadOffset(payload_ty, self.target.*);
+ const err_off = errUnionErrorOffset(payload_ty, self.target.*);
+ try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), operand);
+ try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), .undef);
- return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});
+ break :result MCValue{ .stack_offset = stack_offset };
};
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
}