From e44152e25200a9129724d10c093e64255289e811 Mon Sep 17 00:00:00 2001 From: Ali Chraghi Date: Sun, 15 Oct 2023 22:45:00 +0330 Subject: [PATCH] spirv: fieldParentPtr --- src/codegen/spirv.zig | 56 +++++++++++++++++++++++++----- test/behavior/field_parent_ptr.zig | 5 --- test/behavior/tuple.zig | 2 -- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 0f0adf5646..2c9018463d 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -950,7 +950,12 @@ const DeclGen = struct { }); return result_id; }, - .field => unreachable, // TODO + .field => |field| { + const base_ptr_ty = mod.intern_pool.typeOf(field.base).toType(); + const base_ptr = try self.constantPtr(base_ptr_ty, field.base.toValue()); + const field_index: u32 = @intCast(field.index); + return try self.structFieldPtr(ptr_ty, base_ptr_ty, base_ptr, field_index); + }, } } @@ -2021,6 +2026,7 @@ const DeclGen = struct { .union_init => try self.airUnionInit(inst), .struct_field_val => try self.airStructFieldVal(inst), + .field_parent_ptr => try self.airFieldParentPtr(inst), .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1), @@ -2918,13 +2924,8 @@ const DeclGen = struct { return result_id; } - fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { - if (self.liveness.isUnused(inst)) return null; - - const un_op = self.air.instructions.items(.data)[inst].un_op; - const operand_id = try self.resolve(un_op); + fn intFromPtr(self: *DeclGen, operand_id: IdRef) !IdRef { const result_type_id = try self.resolveTypeId(Type.usize); - const result_id = self.spv.allocId(); try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{ .id_result_type = result_type_id, @@ -2934,6 +2935,14 @@ const DeclGen = struct { return result_id; } + fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + if (self.liveness.isUnused(inst)) return null; + + const un_op = self.air.instructions.items(.data)[inst].un_op; + const operand_id = try self.resolve(un_op); + return try self.intFromPtr(operand_id); + } + fn airFloatFromInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { if (self.liveness.isUnused(inst)) return null; @@ -3474,13 +3483,44 @@ const DeclGen = struct { } } + fn airFieldParentPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + const mod = self.module; + const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; + const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; + + const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod); + const res_ty = try self.resolveType(self.air.getRefType(ty_pl.ty), .indirect); + const usize_ty = Type.usize; + const usize_ty_ref = try self.resolveType(usize_ty, .direct); + + const field_ptr = try self.resolve(extra.field_ptr); + const field_ptr_int = try self.intFromPtr(field_ptr); + const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); + + const base_ptr_int = base_ptr_int: { + if (field_offset == 0) break :base_ptr_int field_ptr_int; + + const field_offset_id = try self.constInt(usize_ty_ref, field_offset); + break :base_ptr_int try self.binOpSimple(usize_ty, field_ptr_int, field_offset_id, .OpISub); + }; + + const base_ptr = self.spv.allocId(); + try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ + .id_result_type = self.spv.resultId(res_ty), + .id_result = base_ptr, + .integer_value = base_ptr_int, + }); + + return base_ptr; + } + fn structFieldPtr( self: *DeclGen, result_ptr_ty: Type, object_ptr_ty: Type, object_ptr: IdRef, field_index: u32, - ) !?IdRef { + ) !IdRef { const result_ty_ref = try self.resolveType(result_ptr_ty, .direct); const mod = self.module; diff --git a/test/behavior/field_parent_ptr.zig b/test/behavior/field_parent_ptr.zig index 6e3eda9032..adb0e66ed6 100644 --- a/test/behavior/field_parent_ptr.zig +++ b/test/behavior/field_parent_ptr.zig @@ -4,7 +4,6 @@ const builtin = @import("builtin"); test "@fieldParentPtr non-first field" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; try testParentFieldPtr(&foo.c); try comptime testParentFieldPtr(&foo.c); @@ -13,7 +12,6 @@ test "@fieldParentPtr non-first field" { test "@fieldParentPtr first field" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; try testParentFieldPtrFirst(&foo.a); try comptime testParentFieldPtrFirst(&foo.a); @@ -53,7 +51,6 @@ test "@fieldParentPtr untagged union" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; try testFieldParentPtrUnion(&bar.c); try comptime testFieldParentPtrUnion(&bar.c); @@ -80,7 +77,6 @@ test "@fieldParentPtr tagged union" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; try testFieldParentPtrTaggedUnion(&bar_tagged.c); try comptime testFieldParentPtrTaggedUnion(&bar_tagged.c); @@ -107,7 +103,6 @@ test "@fieldParentPtr extern union" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; try testFieldParentPtrExternUnion(&bar_extern.c); try comptime testFieldParentPtrExternUnion(&bar_extern.c); diff --git a/test/behavior/tuple.zig b/test/behavior/tuple.zig index 04da0ee47b..8580123a6e 100644 --- a/test/behavior/tuple.zig +++ b/test/behavior/tuple.zig @@ -214,7 +214,6 @@ test "fieldParentPtr of tuple" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; var x: u32 = 0; const tuple = .{ x, x }; @@ -225,7 +224,6 @@ test "fieldParentPtr of anon struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; var x: u32 = 0; const anon_st = .{ .foo = x, .bar = x };