aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/spirv.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2023-10-08 12:09:25 +0200
committerRobin Voetter <robin@voetter.nl>2023-10-15 14:00:07 +0200
commitf858bf161602d72584da9e950c5a9eeadfe8b29d (patch)
treedf67f8739601d0dddf98204f8e5cd0bd51dc8e58 /src/codegen/spirv.zig
parent0af16a58a0af20efa063057e90f8f448b010afd1 (diff)
downloadzig-f858bf161602d72584da9e950c5a9eeadfe8b29d.tar.gz
zig-f858bf161602d72584da9e950c5a9eeadfe8b29d.zip
spirv: air bitcast for non-numeric non-pointer types
Diffstat (limited to 'src/codegen/spirv.zig')
-rw-r--r--src/codegen/spirv.zig35
1 files changed, 31 insertions, 4 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index 638bf7b187..62f945dd81 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -2578,25 +2578,52 @@ const DeclGen = struct {
return src_id;
}
- const result_id = self.spv.allocId();
-
// TODO: Some more cases are missing here
// See fn bitCast in llvm.zig
if (src_ty.zigTypeTag(mod) == .Int and dst_ty.isPtrAtRuntime(mod)) {
+ const result_id = self.spv.allocId();
try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
.id_result_type = self.typeId(dst_ty_ref),
.id_result = result_id,
.integer_value = src_id,
});
- } else {
+ return result_id;
+ }
+
+ // We can only use OpBitcast for specific conversions: between numerical types, and
+ // between pointers. If the resolved spir-v types fall into this category then emit OpBitcast,
+ // otherwise use a temporary and perform a pointer cast.
+ const src_key = self.spv.cache.lookup(src_ty_ref);
+ const dst_key = self.spv.cache.lookup(dst_ty_ref);
+
+ if ((src_key.isNumericalType() and dst_key.isNumericalType()) or (src_key == .ptr_type and dst_key == .ptr_type)) {
+ const result_id = self.spv.allocId();
try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
.id_result_type = self.typeId(dst_ty_ref),
.id_result = result_id,
.operand = src_id,
});
+ return result_id;
}
- return result_id;
+
+ const src_ptr_ty_ref = try self.spv.ptrType(src_ty_ref, .Function);
+ const dst_ptr_ty_ref = try self.spv.ptrType(dst_ty_ref, .Function);
+
+ const tmp_id = self.spv.allocId();
+ try self.func.prologue.emit(self.spv.gpa, .OpVariable, .{
+ .id_result_type = self.typeId(src_ptr_ty_ref),
+ .id_result = tmp_id,
+ .storage_class = .Function,
+ });
+ try self.store(src_ty, tmp_id, src_id, false);
+ const casted_ptr_id = self.spv.allocId();
+ try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
+ .id_result_type = self.typeId(dst_ptr_ty_ref),
+ .id_result = casted_ptr_id,
+ .operand = tmp_id,
+ });
+ return try self.load(dst_ty, casted_ptr_id, false);
}
fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {