authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-12-10 14:07:52+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2023-04-09 01:51:52+02:00
loge788dfa142f27717df1258009cadb61f314610dd
tree3d5384734c3518d8890f4e3c24ae46fe7970aea9
parent27833004dbf066158ddf9574acbdef5c695941fa
signature Commit is signed but in an unrecognized format.

spirv: string literals

Implements lowering string literal constants in the SPIR-V backend

1 files changed, 28 insertions(+), 2 deletions(-)

src/codegen/spirv.zig+28-2
...@@ -461,8 +461,9 @@ pub const DeclGen = struct {...@@ -461,8 +461,9 @@ pub const DeclGen = struct {
461 .repeated => {461 .repeated => {
462 const elem_val = val.castTag(.repeated).?.data;462 const elem_val = val.castTag(.repeated).?.data;
463 const elem_ty = ty.elemType();463 const elem_ty = ty.elemType();
464 const len = @intCast(u32, ty.arrayLenIncludingSentinel()); // TODO: limit spir-v to 32 bit arrays in a more elegant way.464 const len = @intCast(u32, ty.arrayLen());
465 const constituents = try self.spv.gpa.alloc(IdRef, len);465 const total_len = @intCast(u32, ty.arrayLenIncludingSentinel()); // TODO: limit spir-v to 32 bit arrays in a more elegant way.
466 const constituents = try self.spv.gpa.alloc(IdRef, total_len);
466 defer self.spv.gpa.free(constituents);467 defer self.spv.gpa.free(constituents);
467468
468 const elem_val_id = self.spv.allocId();469 const elem_val_id = self.spv.allocId();
...@@ -480,6 +481,31 @@ pub const DeclGen = struct {...@@ -480,6 +481,31 @@ pub const DeclGen = struct {
480 .constituents = constituents,481 .constituents = constituents,
481 });482 });
482 },483 },
484 .str_lit => {
485 // TODO: This is very efficient code generation, should probably implement constant caching for this.
486 const str_lit = val.castTag(.str_lit).?.data;
487 const bytes = self.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
488 const elem_ty = ty.elemType();
489 const elem_ty_id = try self.resolveTypeId(elem_ty);
490 const len = @intCast(u32, ty.arrayLen());
491 const total_len = @intCast(u32, ty.arrayLenIncludingSentinel());
492 const constituents = try self.spv.gpa.alloc(IdRef, total_len);
493 defer self.spv.gpa.free(constituents);
494 for (bytes) |byte, i| {
495 constituents[i] = self.spv.allocId();
496 try self.spv.emitConstant(elem_ty_id, constituents[i], .{ .uint32 = byte });
497 }
498 if (ty.sentinel()) |sentinel| {
499 constituents[len] = self.spv.allocId();
500 const byte = @intCast(u8, sentinel.toUnsignedInt(target));
501 try self.spv.emitConstant(elem_ty_id, constituents[len], .{ .uint32 = byte });
502 }
503 try section.emit(self.spv.gpa, .OpConstantComposite, .{
504 .id_result_type = result_ty_id,
505 .id_result = result_id,
506 .constituents = constituents,
507 });
508 },
483 else => return self.todo("array constant with tag {s}", .{@tagName(val.tag())}),509 else => return self.todo("array constant with tag {s}", .{@tagName(val.tag())}),
484 },510 },
485 .Vector => switch (val.tag()) {511 .Vector => switch (val.tag()) {