Skip to content

Commit e44152e

Browse files
alichraghiandrewrk
authored andcommitted
spirv: fieldParentPtr
1 parent 1456f95 commit e44152e

File tree

3 files changed

+48
-15
lines changed

3 files changed

+48
-15
lines changed

src/codegen/spirv.zig

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,12 @@ const DeclGen = struct {
950950
});
951951
return result_id;
952952
},
953-
.field => unreachable, // TODO
953+
.field => |field| {
954+
const base_ptr_ty = mod.intern_pool.typeOf(field.base).toType();
955+
const base_ptr = try self.constantPtr(base_ptr_ty, field.base.toValue());
956+
const field_index: u32 = @intCast(field.index);
957+
return try self.structFieldPtr(ptr_ty, base_ptr_ty, base_ptr, field_index);
958+
},
954959
}
955960
}
956961

@@ -2021,6 +2026,7 @@ const DeclGen = struct {
20212026
.union_init => try self.airUnionInit(inst),
20222027

20232028
.struct_field_val => try self.airStructFieldVal(inst),
2029+
.field_parent_ptr => try self.airFieldParentPtr(inst),
20242030

20252031
.struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0),
20262032
.struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1),
@@ -2918,13 +2924,8 @@ const DeclGen = struct {
29182924
return result_id;
29192925
}
29202926

2921-
fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2922-
if (self.liveness.isUnused(inst)) return null;
2923-
2924-
const un_op = self.air.instructions.items(.data)[inst].un_op;
2925-
const operand_id = try self.resolve(un_op);
2927+
fn intFromPtr(self: *DeclGen, operand_id: IdRef) !IdRef {
29262928
const result_type_id = try self.resolveTypeId(Type.usize);
2927-
29282929
const result_id = self.spv.allocId();
29292930
try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{
29302931
.id_result_type = result_type_id,
@@ -2934,6 +2935,14 @@ const DeclGen = struct {
29342935
return result_id;
29352936
}
29362937

2938+
fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
2939+
if (self.liveness.isUnused(inst)) return null;
2940+
2941+
const un_op = self.air.instructions.items(.data)[inst].un_op;
2942+
const operand_id = try self.resolve(un_op);
2943+
return try self.intFromPtr(operand_id);
2944+
}
2945+
29372946
fn airFloatFromInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
29382947
if (self.liveness.isUnused(inst)) return null;
29392948

@@ -3474,13 +3483,44 @@ const DeclGen = struct {
34743483
}
34753484
}
34763485

3486+
fn airFieldParentPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
3487+
const mod = self.module;
3488+
const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3489+
const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
3490+
3491+
const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod);
3492+
const res_ty = try self.resolveType(self.air.getRefType(ty_pl.ty), .indirect);
3493+
const usize_ty = Type.usize;
3494+
const usize_ty_ref = try self.resolveType(usize_ty, .direct);
3495+
3496+
const field_ptr = try self.resolve(extra.field_ptr);
3497+
const field_ptr_int = try self.intFromPtr(field_ptr);
3498+
const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);
3499+
3500+
const base_ptr_int = base_ptr_int: {
3501+
if (field_offset == 0) break :base_ptr_int field_ptr_int;
3502+
3503+
const field_offset_id = try self.constInt(usize_ty_ref, field_offset);
3504+
break :base_ptr_int try self.binOpSimple(usize_ty, field_ptr_int, field_offset_id, .OpISub);
3505+
};
3506+
3507+
const base_ptr = self.spv.allocId();
3508+
try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
3509+
.id_result_type = self.spv.resultId(res_ty),
3510+
.id_result = base_ptr,
3511+
.integer_value = base_ptr_int,
3512+
});
3513+
3514+
return base_ptr;
3515+
}
3516+
34773517
fn structFieldPtr(
34783518
self: *DeclGen,
34793519
result_ptr_ty: Type,
34803520
object_ptr_ty: Type,
34813521
object_ptr: IdRef,
34823522
field_index: u32,
3483-
) !?IdRef {
3523+
) !IdRef {
34843524
const result_ty_ref = try self.resolveType(result_ptr_ty, .direct);
34853525

34863526
const mod = self.module;

test/behavior/field_parent_ptr.zig

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const builtin = @import("builtin");
44
test "@fieldParentPtr non-first field" {
55
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
66
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
7-
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
87

98
try testParentFieldPtr(&foo.c);
109
try comptime testParentFieldPtr(&foo.c);
@@ -13,7 +12,6 @@ test "@fieldParentPtr non-first field" {
1312
test "@fieldParentPtr first field" {
1413
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1514
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
16-
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
1715

1816
try testParentFieldPtrFirst(&foo.a);
1917
try comptime testParentFieldPtrFirst(&foo.a);
@@ -53,7 +51,6 @@ test "@fieldParentPtr untagged union" {
5351
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
5452
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
5553
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
56-
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
5754

5855
try testFieldParentPtrUnion(&bar.c);
5956
try comptime testFieldParentPtrUnion(&bar.c);
@@ -80,7 +77,6 @@ test "@fieldParentPtr tagged union" {
8077
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
8178
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
8279
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
83-
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
8480

8581
try testFieldParentPtrTaggedUnion(&bar_tagged.c);
8682
try comptime testFieldParentPtrTaggedUnion(&bar_tagged.c);
@@ -107,7 +103,6 @@ test "@fieldParentPtr extern union" {
107103
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
108104
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
109105
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
110-
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
111106

112107
try testFieldParentPtrExternUnion(&bar_extern.c);
113108
try comptime testFieldParentPtrExternUnion(&bar_extern.c);

test/behavior/tuple.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ test "fieldParentPtr of tuple" {
214214
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
215215
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
216216
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
217-
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
218217

219218
var x: u32 = 0;
220219
const tuple = .{ x, x };
@@ -225,7 +224,6 @@ test "fieldParentPtr of anon struct" {
225224
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
226225
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
227226
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
228-
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
229227

230228
var x: u32 = 0;
231229
const anon_st = .{ .foo = x, .bar = x };

0 commit comments

Comments
 (0)