spirv: constant elem ptr
This commit is contained in:
committed by
Andrew Kelley
parent
a75300c8d8
commit
d9a8c779d8
@@ -694,24 +694,7 @@ pub const DeclGen = struct {
|
||||
.none => ty,
|
||||
else => ty.slicePtrFieldType(mod),
|
||||
};
|
||||
const ptr_id = switch (ptr.addr) {
|
||||
.decl => |decl| try self.constructDeclRef(ptr_ty, decl),
|
||||
.mut_decl => |mut_decl| try self.constructDeclRef(ptr_ty, mut_decl.decl), // TODO
|
||||
.int => |int| blk: {
|
||||
const ptr_id = self.spv.allocId();
|
||||
// TODO: This can probably be an OpSpecConstantOp Bitcast, but
|
||||
// that is not implemented by Mesa yet. Therefore, just generate it
|
||||
// as a runtime operation.
|
||||
try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
|
||||
.id_result_type = try self.resolveTypeId(ptr_ty),
|
||||
.id_result = ptr_id,
|
||||
.integer_value = try self.constant(Type.usize, int.toValue(), .direct),
|
||||
});
|
||||
break :blk ptr_id;
|
||||
},
|
||||
.comptime_field => unreachable,
|
||||
else => |tag| return self.todo("pointer value of type {s}", .{@tagName(tag)}),
|
||||
};
|
||||
const ptr_id = try self.constantPtr(ptr_ty, val);
|
||||
if (ptr.len == .none) {
|
||||
return ptr_id;
|
||||
}
|
||||
@@ -818,6 +801,38 @@ pub const DeclGen = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn constantPtr(self: *DeclGen, ptr_ty: Type, ptr_val: Value) !IdRef {
|
||||
const result_ty_ref = try self.resolveType(ptr_ty, .direct);
|
||||
const mod = self.module;
|
||||
switch (mod.intern_pool.indexToKey(ptr_val.toIntern()).ptr.addr) {
|
||||
.decl => |decl| return try self.constructDeclRef(ptr_ty, decl),
|
||||
.mut_decl => |decl_mut| return try self.constructDeclRef(ptr_ty, decl_mut.decl),
|
||||
.int => |int| {
|
||||
const ptr_id = self.spv.allocId();
|
||||
// TODO: This can probably be an OpSpecConstantOp Bitcast, but
|
||||
// that is not implemented by Mesa yet. Therefore, just generate it
|
||||
// as a runtime operation.
|
||||
try self.func.body.emit(self.spv.gpa, .OpConvertUToPtr, .{
|
||||
.id_result_type = self.typeId(result_ty_ref),
|
||||
.id_result = ptr_id,
|
||||
.integer_value = try self.constant(Type.usize, int.toValue(), .direct),
|
||||
});
|
||||
return ptr_id;
|
||||
},
|
||||
.eu_payload => unreachable, // TODO
|
||||
.opt_payload => unreachable, // TODO
|
||||
.comptime_field => unreachable,
|
||||
.elem => |elem_ptr| {
|
||||
const elem_ptr_ty = mod.intern_pool.typeOf(elem_ptr.base).toType();
|
||||
const parent_ptr_id = try self.constantPtr(elem_ptr_ty, elem_ptr.base.toValue());
|
||||
const size_ty_ref = try self.sizeType();
|
||||
const index_id = try self.constInt(size_ty_ref, elem_ptr.index);
|
||||
return self.ptrAccessChain(result_ty_ref, parent_ptr_id, index_id, &.{});
|
||||
},
|
||||
.field => unreachable, // TODO
|
||||
}
|
||||
}
|
||||
|
||||
// Turn a Zig type's name into a cache reference.
|
||||
fn resolveTypeName(self: *DeclGen, ty: Type) !CacheString {
|
||||
var name = std.ArrayList(u8).init(self.gpa);
|
||||
|
||||
@@ -141,7 +141,6 @@ test "peer type resolution with C pointers" {
|
||||
}
|
||||
|
||||
test "peer type resolution with C pointer and const pointer" {
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
var ptr_c: [*c]u8 = undefined;
|
||||
const ptr_const: u8 = undefined;
|
||||
try expect(@TypeOf(ptr_c, &ptr_const) == [*c]const u8);
|
||||
@@ -314,7 +313,6 @@ test "allow any sentinel" {
|
||||
test "pointer sentinel with enums" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
const Number = enum {
|
||||
@@ -336,7 +334,6 @@ test "pointer sentinel with optional element" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@@ -353,7 +350,6 @@ test "pointer sentinel with +inf" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@@ -374,7 +370,6 @@ test "pointer to array at fixed address" {
|
||||
}
|
||||
|
||||
test "pointer arithmetic affects the alignment" {
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
{
|
||||
var ptr: [*]align(8) u32 = undefined;
|
||||
var x: usize = 1;
|
||||
@@ -430,7 +425,6 @@ test "indexing array with sentinel returns correct type" {
|
||||
test "element pointer to slice" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@@ -453,7 +447,6 @@ test "element pointer to slice" {
|
||||
test "element pointer arithmetic to slice" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@@ -478,7 +471,6 @@ test "element pointer arithmetic to slice" {
|
||||
|
||||
test "array slicing to slice" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
|
||||
@@ -121,7 +121,6 @@ test "slice of type" {
|
||||
|
||||
test "generic malloc free" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const a = memAlloc(u8, 10) catch unreachable;
|
||||
memFree(u8, a);
|
||||
@@ -302,7 +301,6 @@ test "slice type with custom alignment" {
|
||||
|
||||
test "obtaining a null terminated slice" {
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
// here we have a normal array
|
||||
var buf: [50]u8 = undefined;
|
||||
@@ -623,7 +621,6 @@ test "type coercion of pointer to anon struct literal to pointer to slice" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
const U = union {
|
||||
|
||||
Reference in New Issue
Block a user