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