authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-05-18 22:39:28+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-05-20 17:30:22+02:00
log2f28713bd7c8eefd90d59d69a0786ee3f12400e1
tree72e3a24e90a735edf235b9b9a21d43364bd902e3
parent4203d099be2a5fd4d7fd2a24d6e682c817cba7fa
signaturelock-open Commit is signed but in an unrecognized format.

spirv: pointer bitcasting


2 files changed, 29 insertions(+), 13 deletions(-)

src/codegen/spirv.zig+29-10
...@@ -1752,7 +1752,7 @@ pub const DeclGen = struct {...@@ -1752,7 +1752,7 @@ pub const DeclGen = struct {
17521752
1753 .shl => try self.airShift(inst, .OpShiftLeftLogical),1753 .shl => try self.airShift(inst, .OpShiftLeftLogical),
17541754
1755 .bitcast => try self.airBitcast(inst),1755 .bitcast => try self.airBitCast(inst),
1756 .intcast, .trunc => try self.airIntCast(inst),1756 .intcast, .trunc => try self.airIntCast(inst),
1757 .ptrtoint => try self.airPtrToInt(inst),1757 .ptrtoint => try self.airPtrToInt(inst),
1758 .int_to_float => try self.airIntToFloat(inst),1758 .int_to_float => try self.airIntToFloat(inst),
...@@ -2269,22 +2269,41 @@ pub const DeclGen = struct {...@@ -2269,22 +2269,41 @@ pub const DeclGen = struct {
2269 return try self.cmp(op, bool_ty_id, ty, lhs_id, rhs_id);2269 return try self.cmp(op, bool_ty_id, ty, lhs_id, rhs_id);
2270 }2270 }
22712271
2272 fn bitcast(self: *DeclGen, target_type_id: IdResultType, value_id: IdRef) !IdRef {2272 fn bitCast(
2273 self: *DeclGen,
2274 dst_ty: Type,
2275 src_ty: Type,
2276 src_id: IdRef,
2277 ) !IdRef {
2278 const dst_ty_ref = try self.resolveType(dst_ty, .direct);
2273 const result_id = self.spv.allocId();2279 const result_id = self.spv.allocId();
2274 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{2280
2275 .id_result_type = target_type_id,2281 // TODO: Some more cases are missing here
2276 .id_result = result_id,2282 // See fn bitCast in llvm.zig
2277 .operand = value_id,2283
2278 });2284 if (src_ty.zigTypeTag() == .Int and dst_ty.isPtrAtRuntime()) {
2285 try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
2286 .id_result_type = self.typeId(dst_ty_ref),
2287 .id_result = result_id,
2288 .integer_value = src_id,
2289 });
2290 } else {
2291 try self.func.body.emit(self.spv.gpa, .OpBitcast, .{
2292 .id_result_type = self.typeId(dst_ty_ref),
2293 .id_result = result_id,
2294 .operand = src_id,
2295 });
2296 }
2279 return result_id;2297 return result_id;
2280 }2298 }
22812299
2282 fn airBitcast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2300 fn airBitCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2283 if (self.liveness.isUnused(inst)) return null;2301 if (self.liveness.isUnused(inst)) return null;
2284 const ty_op = self.air.instructions.items(.data)[inst].ty_op;2302 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
2285 const operand_id = try self.resolve(ty_op.operand);2303 const operand_id = try self.resolve(ty_op.operand);
2286 const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst));2304 const operand_ty = self.air.typeOf(ty_op.operand);
2287 return try self.bitcast(result_type_id, operand_id);2305 const result_ty = self.air.typeOfIndex(inst);
2306 return try self.bitCast(result_ty, operand_ty, operand_id);
2288 }2307 }
22892308
2290 fn airIntCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {2309 fn airIntCast(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
test/behavior/pointers.zig-3
...@@ -5,7 +5,6 @@ const expect = testing.expect;...@@ -5,7 +5,6 @@ const expect = testing.expect;
5const expectError = testing.expectError;5const expectError = testing.expectError;
66
7test "dereference pointer" {7test "dereference pointer" {
8 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
9 comptime try testDerefPtr();8 comptime try testDerefPtr();
10 try testDerefPtr();9 try testDerefPtr();
11}10}
...@@ -53,7 +52,6 @@ fn PtrOf(comptime T: type) type {...@@ -53,7 +52,6 @@ fn PtrOf(comptime T: type) type {
5352
54test "implicit cast single item pointer to C pointer and back" {53test "implicit cast single item pointer to C pointer and back" {
55 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO54 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5755
58 var y: u8 = 11;56 var y: u8 = 11;
59 var x: [*c]u8 = &y;57 var x: [*c]u8 = &y;
...@@ -70,7 +68,6 @@ test "initialize const optional C pointer to null" {...@@ -70,7 +68,6 @@ test "initialize const optional C pointer to null" {
7068
71test "assigning integer to C pointer" {69test "assigning integer to C pointer" {
72 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO70 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
73 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
7471
75 var x: i32 = 0;72 var x: i32 = 0;
76 var y: i32 = 1;73 var y: i32 = 1;