From e788dfa142f27717df1258009cadb61f314610dd Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sat, 10 Dec 2022 14:07:52 +0100 Subject: [PATCH] spirv: string literals Implements lowering string literal constants in the SPIR-V backend --- src/codegen/spirv.zig | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index f81a248f63..7df4360c41 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -461,8 +461,9 @@ pub const DeclGen = struct { .repeated => { const elem_val = val.castTag(.repeated).?.data; const elem_ty = ty.elemType(); - const len = @intCast(u32, ty.arrayLenIncludingSentinel()); // TODO: limit spir-v to 32 bit arrays in a more elegant way. - const constituents = try self.spv.gpa.alloc(IdRef, len); + const len = @intCast(u32, ty.arrayLen()); + const total_len = @intCast(u32, ty.arrayLenIncludingSentinel()); // TODO: limit spir-v to 32 bit arrays in a more elegant way. + const constituents = try self.spv.gpa.alloc(IdRef, total_len); defer self.spv.gpa.free(constituents); const elem_val_id = self.spv.allocId(); @@ -480,6 +481,31 @@ pub const DeclGen = struct { .constituents = constituents, }); }, + .str_lit => { + // TODO: This is very efficient code generation, should probably implement constant caching for this. + const str_lit = val.castTag(.str_lit).?.data; + const bytes = self.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; + const elem_ty = ty.elemType(); + const elem_ty_id = try self.resolveTypeId(elem_ty); + const len = @intCast(u32, ty.arrayLen()); + const total_len = @intCast(u32, ty.arrayLenIncludingSentinel()); + const constituents = try self.spv.gpa.alloc(IdRef, total_len); + defer self.spv.gpa.free(constituents); + for (bytes) |byte, i| { + constituents[i] = self.spv.allocId(); + try self.spv.emitConstant(elem_ty_id, constituents[i], .{ .uint32 = byte }); + } + if (ty.sentinel()) |sentinel| { + constituents[len] = self.spv.allocId(); + const byte = @intCast(u8, sentinel.toUnsignedInt(target)); + try self.spv.emitConstant(elem_ty_id, constituents[len], .{ .uint32 = byte }); + } + try section.emit(self.spv.gpa, .OpConstantComposite, .{ + .id_result_type = result_ty_id, + .id_result = result_id, + .constituents = constituents, + }); + }, else => return self.todo("array constant with tag {s}", .{@tagName(val.tag())}), }, .Vector => switch (val.tag()) {