| author | |
| committer | |
| log | d9a8c779d8d7e251bcb549c4b1627508c012ee8c |
| tree | 97dbd460de42664793762646e8d4cd4f52675332 |
| parent | a75300c8d8cfe21647db1d50f77a9a1ee8d62a0e |
3 files changed, 33 insertions(+), 29 deletions(-)
src/codegen/spirv.zig+33-18| ... | @@ -694,24 +694,7 @@ pub const DeclGen = struct { | ... | @@ -694,24 +694,7 @@ pub const DeclGen = struct { |
| 694 | .none => ty, | 694 | .none => ty, |
| 695 | else => ty.slicePtrFieldType(mod), | 695 | else => ty.slicePtrFieldType(mod), |
| 696 | }; | 696 | }; |
| 697 | const ptr_id = switch (ptr.addr) { | 697 | const ptr_id = try self.constantPtr(ptr_ty, val); |
| 698 | .decl => |decl| try self.constructDeclRef(ptr_ty, decl), | ||
| 699 | .mut_decl => |mut_decl| try self.constructDeclRef(ptr_ty, mut_decl.decl), // TODO | ||
| 700 | .int => |int| blk: { | ||
| 701 | const ptr_id = self.spv.allocId(); | ||
| 702 | // TODO: This can probably be an OpSpecConstantOp Bitcast, but | ||
| 703 | // that is not implemented by Mesa yet. Therefore, just generate it | ||
| 704 | // as a runtime operation. | ||
| 705 | try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ | ||
| 706 | .id_result_type = try self.resolveTypeId(ptr_ty), | ||
| 707 | .id_result = ptr_id, | ||
| 708 | .integer_value = try self.constant(Type.usize, int.toValue(), .direct), | ||
| 709 | }); | ||
| 710 | break :blk ptr_id; | ||
| 711 | }, | ||
| 712 | .comptime_field => unreachable, | ||
| 713 | else => |tag| return self.todo("pointer value of type {s}", .{@tagName(tag)}), | ||
| 714 | }; | ||
| 715 | if (ptr.len == .none) { | 698 | if (ptr.len == .none) { |
| 716 | return ptr_id; | 699 | return ptr_id; |
| 717 | } | 700 | } |
| ... | @@ -818,6 +801,38 @@ pub const DeclGen = struct { | ... | @@ -818,6 +801,38 @@ pub const DeclGen = struct { |
| 818 | } | 801 | } |
| 819 | } | 802 | } |
| 820 | 803 | ||
| 804 | fn constantPtr(self: *DeclGen, ptr_ty: Type, ptr_val: Value) !IdRef { | ||
| 805 | const result_ty_ref = try self.resolveType(ptr_ty, .direct); | ||
| 806 | const mod = self.module; | ||
| 807 | switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) { | ||
| 808 | .decl => |decl| return try self.constructDeclRef(ptr_ty, decl), | ||
| 809 | .mut_decl => |decl_mut| return try self.constructDeclRef(ptr_ty, decl_mut.decl), | ||
| 810 | .int => |int| { | ||
| 811 | const ptr_id = self.spv.allocId(); | ||
| 812 | // TODO: This can probably be an OpSpecConstantOp Bitcast, but | ||
| 813 | // that is not implemented by Mesa yet. Therefore, just generate it | ||
| 814 | // as a runtime operation. | ||
| 815 | try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{ | ||
| 816 | .id_result_type = self.typeId(result_ty_ref), | ||
| 817 | .id_result = ptr_id, | ||
| 818 | .integer_value = try self.constant(Type.usize, int.toValue(), .direct), | ||
| 819 | }); | ||
| 820 | return ptr_id; | ||
| 821 | }, | ||
| 822 | .eu_payload => unreachable, // TODO | ||
| 823 | .opt_payload => unreachable, // TODO | ||
| 824 | .comptime_field => unreachable, | ||
| 825 | .elem => |elem_ptr| { | ||
| 826 | const elem_ptr_ty = mod.intern_pool.typeOf(elem_ptr.base).toType(); | ||
| 827 | const parent_ptr_id = try self.constantPtr(elem_ptr_ty, elem_ptr.base.toValue()); | ||
| 828 | const size_ty_ref = try self.sizeType(); | ||
| 829 | const index_id = try self.constInt(size_ty_ref, elem_ptr.index); | ||
| 830 | return self.ptrAccessChain(result_ty_ref, parent_ptr_id, index_id, &.{}); | ||
| 831 | }, | ||
| 832 | .field => unreachable, // TODO | ||
| 833 | } | ||
| 834 | } | ||
| 835 | |||
| 821 | // Turn a Zig type's name into a cache reference. | 836 | // Turn a Zig type's name into a cache reference. |
| 822 | fn resolveTypeName(self: *DeclGen, ty: Type) !CacheString { | 837 | fn resolveTypeName(self: *DeclGen, ty: Type) !CacheString { |
| 823 | var name = std.ArrayList(u8).init(self.gpa); | 838 | var name = std.ArrayList(u8).init(self.gpa); |
test/behavior/pointers.zig-8| ... | @@ -141,7 +141,6 @@ test "peer type resolution with C pointers" { | ... | @@ -141,7 +141,6 @@ test "peer type resolution with C pointers" { |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | test "peer type resolution with C pointer and const pointer" { | 143 | test "peer type resolution with C pointer and const pointer" { |
| 144 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 145 | var ptr_c: [*c]u8 = undefined; | 144 | var ptr_c: [*c]u8 = undefined; |
| 146 | const ptr_const: u8 = undefined; | 145 | const ptr_const: u8 = undefined; |
| 147 | try expect(@TypeOf(ptr_c, &ptr_const) == [*c]const u8); | 146 | try expect(@TypeOf(ptr_c, &ptr_const) == [*c]const u8); |
| ... | @@ -314,7 +313,6 @@ test "allow any sentinel" { | ... | @@ -314,7 +313,6 @@ test "allow any sentinel" { |
| 314 | test "pointer sentinel with enums" { | 313 | test "pointer sentinel with enums" { |
| 315 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 314 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 316 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 315 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 317 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 318 | 316 | ||
| 319 | const S = struct { | 317 | const S = struct { |
| 320 | const Number = enum { | 318 | const Number = enum { |
| ... | @@ -336,7 +334,6 @@ test "pointer sentinel with optional element" { | ... | @@ -336,7 +334,6 @@ test "pointer sentinel with optional element" { |
| 336 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 334 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 337 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 335 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 338 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 336 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 339 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 340 | 337 | ||
| 341 | const S = struct { | 338 | const S = struct { |
| 342 | fn doTheTest() !void { | 339 | fn doTheTest() !void { |
| ... | @@ -353,7 +350,6 @@ test "pointer sentinel with +inf" { | ... | @@ -353,7 +350,6 @@ test "pointer sentinel with +inf" { |
| 353 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 350 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 354 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 351 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 355 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 352 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 356 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 357 | 353 | ||
| 358 | const S = struct { | 354 | const S = struct { |
| 359 | fn doTheTest() !void { | 355 | fn doTheTest() !void { |
| ... | @@ -374,7 +370,6 @@ test "pointer to array at fixed address" { | ... | @@ -374,7 +370,6 @@ test "pointer to array at fixed address" { |
| 374 | } | 370 | } |
| 375 | 371 | ||
| 376 | test "pointer arithmetic affects the alignment" { | 372 | test "pointer arithmetic affects the alignment" { |
| 377 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 378 | { | 373 | { |
| 379 | var ptr: [*]align(8) u32 = undefined; | 374 | var ptr: [*]align(8) u32 = undefined; |
| 380 | var x: usize = 1; | 375 | var x: usize = 1; |
| ... | @@ -430,7 +425,6 @@ test "indexing array with sentinel returns correct type" { | ... | @@ -430,7 +425,6 @@ test "indexing array with sentinel returns correct type" { |
| 430 | test "element pointer to slice" { | 425 | test "element pointer to slice" { |
| 431 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 426 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 432 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 427 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 433 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 434 | 428 | ||
| 435 | const S = struct { | 429 | const S = struct { |
| 436 | fn doTheTest() !void { | 430 | fn doTheTest() !void { |
| ... | @@ -453,7 +447,6 @@ test "element pointer to slice" { | ... | @@ -453,7 +447,6 @@ test "element pointer to slice" { |
| 453 | test "element pointer arithmetic to slice" { | 447 | test "element pointer arithmetic to slice" { |
| 454 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 448 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 455 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 449 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 456 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 457 | 450 | ||
| 458 | const S = struct { | 451 | const S = struct { |
| 459 | fn doTheTest() !void { | 452 | fn doTheTest() !void { |
| ... | @@ -478,7 +471,6 @@ test "element pointer arithmetic to slice" { | ... | @@ -478,7 +471,6 @@ test "element pointer arithmetic to slice" { |
| 478 | 471 | ||
| 479 | test "array slicing to slice" { | 472 | test "array slicing to slice" { |
| 480 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 473 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 481 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 482 | 474 | ||
| 483 | const S = struct { | 475 | const S = struct { |
| 484 | fn doTheTest() !void { | 476 | fn doTheTest() !void { |
test/behavior/slice.zig-3| ... | @@ -121,7 +121,6 @@ test "slice of type" { | ... | @@ -121,7 +121,6 @@ test "slice of type" { |
| 121 | 121 | ||
| 122 | test "generic malloc free" { | 122 | test "generic malloc free" { |
| 123 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 123 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 124 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 125 | 124 | ||
| 126 | const a = memAlloc(u8, 10) catch unreachable; | 125 | const a = memAlloc(u8, 10) catch unreachable; |
| 127 | memFree(u8, a); | 126 | memFree(u8, a); |
| ... | @@ -302,7 +301,6 @@ test "slice type with custom alignment" { | ... | @@ -302,7 +301,6 @@ test "slice type with custom alignment" { |
| 302 | 301 | ||
| 303 | test "obtaining a null terminated slice" { | 302 | test "obtaining a null terminated slice" { |
| 304 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 303 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 305 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 306 | 304 | ||
| 307 | // here we have a normal array | 305 | // here we have a normal array |
| 308 | var buf: [50]u8 = undefined; | 306 | var buf: [50]u8 = undefined; |
| ... | @@ -623,7 +621,6 @@ test "type coercion of pointer to anon struct literal to pointer to slice" { | ... | @@ -623,7 +621,6 @@ test "type coercion of pointer to anon struct literal to pointer to slice" { |
| 623 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 621 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 624 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 622 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 625 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 623 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 626 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 627 | 624 | ||
| 628 | const S = struct { | 625 | const S = struct { |
| 629 | const U = union { | 626 | const U = union { |