| ... | @@ -3009,7 +3009,23 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3009,7 +3009,23 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void { |
| 3009 | /// T to E!T | 3009 | /// T to E!T |
| 3010 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { | 3010 | fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void { |
| 3011 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 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 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 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,11 +3034,20 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 3018 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 3034 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 3019 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 3035 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 3020 | const error_union_ty = self.air.getRefType(ty_op.ty); | 3036 | const error_union_ty = self.air.getRefType(ty_op.ty); |
| | 3037 | const error_ty = error_union_ty.errorUnionSet(); |
| 3021 | const payload_ty = error_union_ty.errorUnionPayload(); | 3038 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 3022 | const mcv = try self.resolveInst(ty_op.operand); | 3039 | const operand = try self.resolveInst(ty_op.operand); |
| 3023 | if (!payload_ty.hasRuntimeBits()) break :result mcv; | 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 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 3052 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 3028 | } | 3053 | } |