mirror of
https://github.com/ziglang/zig.git
synced 2026-01-02 03:25:01 +00:00
stage2 AArch64: implement wrap_errunion_{err,payload}
This commit is contained in:
parent
3ecec50f0c
commit
8a022d9c92
@ -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;
|
||||
|
||||
return self.fail("TODO implement wrap errunion error for non-empty payloads", .{});
|
||||
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);
|
||||
|
||||
break :result MCValue{ .stack_offset = stack_offset };
|
||||
};
|
||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user