aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-04-10 22:43:55 +0200
committerRobin Voetter <robin@voetter.nl>2023-05-11 20:31:51 +0200
commitf62735d98ce9055ca08cff587e438412404818cd (patch)
tree0ede7c8736728f985d40eec600cd1d30724e67eb /src/codegen
parent78c44d63da14437fe0d64da92606a22d543b8169 (diff)
downloadzig-f62735d98ce9055ca08cff587e438412404818cd.tar.gz
zig-f62735d98ce9055ca08cff587e438412404818cd.zip
spirv: lower air wrap_errunion_err
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/spirv.zig37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index ad500af772..68f64dc353 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -1613,6 +1613,7 @@ pub const DeclGen = struct {
.unreach => return self.airUnreach(),
.unwrap_errunion_err => try self.airErrUnionErr(inst),
+ .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
.assembly => try self.airAssembly(inst),
@@ -2561,6 +2562,42 @@ pub const DeclGen = struct {
return try self.extractField(err_ty_ref, operand_id, eu_layout.errorFieldIndex());
}
+ fn airWrapErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
+ if (self.liveness.isUnused(inst)) return null;
+
+ const ty_op = self.air.instructions.items(.data)[inst].ty_op;
+ const err_union_ty = self.air.typeOfIndex(inst);
+ const payload_ty = err_union_ty.errorUnionPayload();
+ const operand_id = try self.resolve(ty_op.operand);
+ const eu_layout = self.errorUnionLayout(payload_ty);
+
+ if (!eu_layout.payload_has_bits) {
+ return operand_id;
+ }
+
+ const payload_ty_ref = try self.resolveType(payload_ty, .indirect);
+ var members = std.BoundedArray(IdRef, 2){};
+ const payload_id = try self.constUndef(payload_ty_ref);
+ if (eu_layout.error_first) {
+ members.appendAssumeCapacity(operand_id);
+ members.appendAssumeCapacity(payload_id);
+ // TODO: ABI padding?
+ } else {
+ members.appendAssumeCapacity(payload_id);
+ members.appendAssumeCapacity(operand_id);
+ // TODO: ABI padding?
+ }
+
+ const err_union_ty_ref = try self.resolveType(err_union_ty, .direct);
+ const result_id = self.spv.allocId();
+ try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{
+ .id_result_type = self.typeId(err_union_ty_ref),
+ .id_result = result_id,
+ .constituents = members.slice(),
+ });
+ return result_id;
+ }
+
fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {
const target = self.getTarget();
const pl_op = self.air.instructions.items(.data)[inst].pl_op;