| author | |
| committer | |
| log | e44152e25200a9129724d10c093e64255289e811 |
| tree | ff1cef4de0a11bbd62125956a09c1ecee971d8ea |
| parent | 1456f95b3c043aa7e5b655c362cc3bd05aa3c795 |
3 files changed, 48 insertions(+), 15 deletions(-)
src/codegen/spirv.zig+48-8| ... | @@ -950,7 +950,12 @@ const DeclGen = struct { | ... | @@ -950,7 +950,12 @@ const DeclGen = struct { |
| 950 | }); | 950 | }); |
| 951 | return result_id; | 951 | return result_id; |
| 952 | }, | 952 | }, |
| 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 | }, | ||
| 954 | } | 959 | } |
| 955 | } | 960 | } |
| 956 | 961 | ||
| ... | @@ -2021,6 +2026,7 @@ const DeclGen = struct { | ... | @@ -2021,6 +2026,7 @@ const DeclGen = struct { |
| 2021 | .union_init => try self.airUnionInit(inst), | 2026 | .union_init => try self.airUnionInit(inst), |
| 2022 | 2027 | ||
| 2023 | .struct_field_val => try self.airStructFieldVal(inst), | 2028 | .struct_field_val => try self.airStructFieldVal(inst), |
| 2029 | .field_parent_ptr => try self.airFieldParentPtr(inst), | ||
| 2024 | 2030 | ||
| 2025 | .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), | 2031 | .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), |
| 2026 | .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1), | 2032 | .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1), |
| ... | @@ -2918,13 +2924,8 @@ const DeclGen = struct { | ... | @@ -2918,13 +2924,8 @@ const DeclGen = struct { |
| 2918 | return result_id; | 2924 | return result_id; |
| 2919 | } | 2925 | } |
| 2920 | 2926 | ||
| 2921 | fn airIntFromPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2927 | fn intFromPtr(self: *DeclGen, operand_id: IdRef) !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); | ||
| 2926 | const result_type_id = try self.resolveTypeId(Type.usize); | 2928 | const result_type_id = try self.resolveTypeId(Type.usize); |
| 2927 | |||
| 2928 | const result_id = self.spv.allocId(); | 2929 | const result_id = self.spv.allocId(); |
| 2929 | try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{ | 2930 | try self.func.body.emit(self.spv.gpa, .OpConvertPtrToU, .{ |
| 2930 | .id_result_type = result_type_id, | 2931 | .id_result_type = result_type_id, |
| ... | @@ -2934,6 +2935,14 @@ const DeclGen = struct { | ... | @@ -2934,6 +2935,14 @@ const DeclGen = struct { |
| 2934 | return result_id; | 2935 | return result_id; |
| 2935 | } | 2936 | } |
| 2936 | 2937 | ||
| 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 | |||
| 2937 | fn airFloatFromInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 2946 | fn airFloatFromInt(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2938 | if (self.liveness.isUnused(inst)) return null; | 2947 | if (self.liveness.isUnused(inst)) return null; |
| 2939 | 2948 | ||
| ... | @@ -3474,13 +3483,44 @@ const DeclGen = struct { | ... | @@ -3474,13 +3483,44 @@ const DeclGen = struct { |
| 3474 | } | 3483 | } |
| 3475 | } | 3484 | } |
| 3476 | 3485 | ||
| 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 | |||
| 3477 | fn structFieldPtr( | 3517 | fn structFieldPtr( |
| 3478 | self: *DeclGen, | 3518 | self: *DeclGen, |
| 3479 | result_ptr_ty: Type, | 3519 | result_ptr_ty: Type, |
| 3480 | object_ptr_ty: Type, | 3520 | object_ptr_ty: Type, |
| 3481 | object_ptr: IdRef, | 3521 | object_ptr: IdRef, |
| 3482 | field_index: u32, | 3522 | field_index: u32, |
| 3483 | ) !?IdRef { | 3523 | ) !IdRef { |
| 3484 | const result_ty_ref = try self.resolveType(result_ptr_ty, .direct); | 3524 | const result_ty_ref = try self.resolveType(result_ptr_ty, .direct); |
| 3485 | 3525 | ||
| 3486 | const mod = self.module; | 3526 | const mod = self.module; |
test/behavior/field_parent_ptr.zig-5| ... | @@ -4,7 +4,6 @@ const builtin = @import("builtin"); | ... | @@ -4,7 +4,6 @@ const builtin = @import("builtin"); |
| 4 | test "@fieldParentPtr non-first field" { | 4 | test "@fieldParentPtr non-first field" { |
| 5 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 5 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 6 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 6 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 7 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 8 | 7 | ||
| 9 | try testParentFieldPtr(&foo.c); | 8 | try testParentFieldPtr(&foo.c); |
| 10 | try comptime testParentFieldPtr(&foo.c); | 9 | try comptime testParentFieldPtr(&foo.c); |
| ... | @@ -13,7 +12,6 @@ test "@fieldParentPtr non-first field" { | ... | @@ -13,7 +12,6 @@ test "@fieldParentPtr non-first field" { |
| 13 | test "@fieldParentPtr first field" { | 12 | test "@fieldParentPtr first field" { |
| 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 13 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 15 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 14 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 16 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 17 | 15 | ||
| 18 | try testParentFieldPtrFirst(&foo.a); | 16 | try testParentFieldPtrFirst(&foo.a); |
| 19 | try comptime testParentFieldPtrFirst(&foo.a); | 17 | try comptime testParentFieldPtrFirst(&foo.a); |
| ... | @@ -53,7 +51,6 @@ test "@fieldParentPtr untagged union" { | ... | @@ -53,7 +51,6 @@ test "@fieldParentPtr untagged union" { |
| 53 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 51 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 54 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 52 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 55 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 53 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 56 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 57 | 54 | ||
| 58 | try testFieldParentPtrUnion(&bar.c); | 55 | try testFieldParentPtrUnion(&bar.c); |
| 59 | try comptime testFieldParentPtrUnion(&bar.c); | 56 | try comptime testFieldParentPtrUnion(&bar.c); |
| ... | @@ -80,7 +77,6 @@ test "@fieldParentPtr tagged union" { | ... | @@ -80,7 +77,6 @@ test "@fieldParentPtr tagged union" { |
| 80 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 77 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 81 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 78 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 82 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 79 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 83 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 84 | 80 | ||
| 85 | try testFieldParentPtrTaggedUnion(&bar_tagged.c); | 81 | try testFieldParentPtrTaggedUnion(&bar_tagged.c); |
| 86 | try comptime testFieldParentPtrTaggedUnion(&bar_tagged.c); | 82 | try comptime testFieldParentPtrTaggedUnion(&bar_tagged.c); |
| ... | @@ -107,7 +103,6 @@ test "@fieldParentPtr extern union" { | ... | @@ -107,7 +103,6 @@ test "@fieldParentPtr extern union" { |
| 107 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 103 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 108 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 104 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 109 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 105 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 110 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 111 | 106 | ||
| 112 | try testFieldParentPtrExternUnion(&bar_extern.c); | 107 | try testFieldParentPtrExternUnion(&bar_extern.c); |
| 113 | try comptime testFieldParentPtrExternUnion(&bar_extern.c); | 108 | try comptime testFieldParentPtrExternUnion(&bar_extern.c); |
test/behavior/tuple.zig-2| ... | @@ -214,7 +214,6 @@ test "fieldParentPtr of tuple" { | ... | @@ -214,7 +214,6 @@ test "fieldParentPtr of tuple" { |
| 214 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 214 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 215 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 215 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 216 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 216 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 217 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 218 | 217 | ||
| 219 | var x: u32 = 0; | 218 | var x: u32 = 0; |
| 220 | const tuple = .{ x, x }; | 219 | const tuple = .{ x, x }; |
| ... | @@ -225,7 +224,6 @@ test "fieldParentPtr of anon struct" { | ... | @@ -225,7 +224,6 @@ test "fieldParentPtr of anon struct" { |
| 225 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 224 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 226 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 225 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 227 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 226 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 228 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 229 | 227 | ||
| 230 | var x: u32 = 0; | 228 | var x: u32 = 0; |
| 231 | const anon_st = .{ .foo = x, .bar = x }; | 229 | const anon_st = .{ .foo = x, .bar = x }; |