authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-22 11:18:38+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-05-11 20:31:51+02:00
logd961b11cde81e92ed3d35c98f7b191255aac58a6
tree4a14f2036d76efec74054d0dc105978ae2cf6c01
parent6c16465d45527c195302beb1f3a1a6d41cdcdd92
signaturelock-open Commit is signed but in an unrecognized format.

spirv: lower wrap_optional

This implements the wrap_optional AIR instruction.

1 files changed, 48 insertions(+), 0 deletions(-)

src/codegen/spirv.zig+48
...@@ -420,6 +420,26 @@ pub const DeclGen = struct {...@@ -420,6 +420,26 @@ pub const DeclGen = struct {
420 return result_id;420 return result_id;
421 }421 }
422422
423 fn constBool(self: *DeclGen, value: bool, repr: Repr) !IdRef {
424 switch (repr) {
425 .indirect => {
426 const int_ty_ref = try self.intType(.unsigned, 1);
427 return self.constInt(int_ty_ref, @boolToInt(value));
428 },
429 .direct => {
430 const bool_ty_ref = try self.resolveType(Type.bool, .direct);
431 const result_id = self.spv.allocId();
432 const operands = .{ .id_result_type = self.typeId(bool_ty_ref), .id_result = result_id };
433 if (value) {
434 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpConstantTrue, operands);
435 } else {
436 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpConstantFalse, operands);
437 }
438 return result_id;
439 },
440 }
441 }
442
423 const IndirectConstantLowering = struct {443 const IndirectConstantLowering = struct {
424 const undef = 0xAA;444 const undef = 0xAA;
425445
...@@ -1718,6 +1738,7 @@ pub const DeclGen = struct {...@@ -1718,6 +1738,7 @@ pub const DeclGen = struct {
1718 .is_non_null => try self.airIsNull(inst, .is_non_null),1738 .is_non_null => try self.airIsNull(inst, .is_non_null),
17191739
1720 .optional_payload => try self.airUnwrapOptional(inst),1740 .optional_payload => try self.airUnwrapOptional(inst),
1741 .wrap_optional => try self.airWrapOptional(inst),
17211742
1722 .assembly => try self.airAssembly(inst),1743 .assembly => try self.airAssembly(inst),
17231744
...@@ -2713,6 +2734,33 @@ pub const DeclGen = struct {...@@ -2713,6 +2734,33 @@ pub const DeclGen = struct {
2713 return try self.extractField(payload_ty, operand_id, 0);2734 return try self.extractField(payload_ty, operand_id, 0);
2714 }2735 }
27152736
2737 fn airWrapOptional(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2738 if (self.liveness.isUnused(inst)) return null;
2739
2740 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2741 const payload_ty = self.air.typeOf(ty_op.operand);
2742
2743 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
2744 return try self.constBool(true, .direct);
2745 }
2746
2747 const operand_id = try self.resolve(ty_op.operand);
2748 const optional_ty = self.air.typeOfIndex(inst);
2749 if (optional_ty.optionalReprIsPayload()) {
2750 return operand_id;
2751 }
2752
2753 const optional_ty_ref = try self.resolveType(optional_ty, .direct);
2754 const result_id = self.spv.allocId();
2755 const members = [_]IdRef{ operand_id, try self.constBool(true, .indirect) };
2756 try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{
2757 .id_result_type = self.typeId(optional_ty_ref),
2758 .id_result = result_id,
2759 .constituents = &members,
2760 });
2761 return result_id;
2762 }
2763
2716 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {2764 fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void {
2717 const target = self.getTarget();2765 const target = self.getTarget();
2718 const pl_op = self.air.instructions.items(.data)[inst].pl_op;2766 const pl_op = self.air.instructions.items(.data)[inst].pl_op;