| ... | ... | @@ -3009,7 +3009,23 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3009 | 3009 | /// T to E!T |
| 3010 | 3010 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3011 | 3011 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3012 | | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement wrap errunion payload for {}", .{self.target.cpu.arch}); |
| 3012 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 3013 | const error_union_ty = self.air.getRefType(ty_op.ty); |
| 3014 | const error_ty = error_union_ty.errorUnionSet(); |
| 3015 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 3016 | const operand = try self.resolveInst(ty_op.operand); |
| 3017 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand; |
| 3018 | |
| 3019 | const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*)); |
| 3020 | const abi_align = error_union_ty.abiAlignment(self.target.*); |
| 3021 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 3022 | const payload_off = errUnionPayloadOffset(payload_ty, self.target.*); |
| 3023 | const err_off = errUnionErrorOffset(payload_ty, self.target.*); |
| 3024 | try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), operand); |
| 3025 | try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), .{ .immediate = 0 }); |
| 3026 | |
| 3027 | break :result MCValue{ .stack_offset = stack_offset }; |
| 3028 | }; |
| 3013 | 3029 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 3014 | 3030 | } |
| 3015 | 3031 | |
| ... | ... | @@ -3018,11 +3034,20 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 3018 | 3034 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3019 | 3035 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 3020 | 3036 | const error_union_ty = self.air.getRefType(ty_op.ty); |
| 3037 | const error_ty = error_union_ty.errorUnionSet(); |
| 3021 | 3038 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 3022 | | const mcv = try self.resolveInst(ty_op.operand); |
| 3023 | | if (!payload_ty.hasRuntimeBits()) break :result mcv; |
| 3039 | const operand = try self.resolveInst(ty_op.operand); |
| 3040 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) break :result operand; |
| 3041 | |
| 3042 | const abi_size = @intCast(u32, error_union_ty.abiSize(self.target.*)); |
| 3043 | const abi_align = error_union_ty.abiAlignment(self.target.*); |
| 3044 | const stack_offset = try self.allocMem(abi_size, abi_align, inst); |
| 3045 | const payload_off = errUnionPayloadOffset(payload_ty, self.target.*); |
| 3046 | const err_off = errUnionErrorOffset(payload_ty, self.target.*); |
| 3047 | try self.genSetStack(error_ty, stack_offset - @intCast(u32, err_off), operand); |
| 3048 | try self.genSetStack(payload_ty, stack_offset - @intCast(u32, payload_off), .undef); |
| 3024 | 3049 | |
| 3025 | | return self.fail("TODO implement wrap errunion error for non-empty payloads", .{}); |
| 3050 | break :result MCValue{ .stack_offset = stack_offset }; |
| 3026 | 3051 | }; |
| 3027 | 3052 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 3028 | 3053 | } |