Commit 1ebb761244

Travis Staloch <twostepted@gmail.com>
2022-12-13 22:55:59
codegen - lower str_lit to vector
1 parent 8a0a6b7
Changed files (4)
src/codegen/llvm.zig
@@ -3882,6 +3882,32 @@ pub const DeclGen = struct {
                         @intCast(c_uint, llvm_elems.len),
                     );
                 },
+                .str_lit => {
+                    // Note, sentinel is not stored
+                    const str_lit = tv.val.castTag(.str_lit).?.data;
+                    const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
+                    const vector_len = @intCast(usize, tv.ty.arrayLen());
+                    assert(vector_len == bytes.len);
+
+                    const elem_ty = tv.ty.elemType();
+                    const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len);
+                    defer dg.gpa.free(llvm_elems);
+                    for (llvm_elems) |*elem, i| {
+                        var byte_payload: Value.Payload.U64 = .{
+                            .base = .{ .tag = .int_u64 },
+                            .data = bytes[i],
+                        };
+
+                        elem.* = try dg.lowerValue(.{
+                            .ty = elem_ty,
+                            .val = Value.initPayload(&byte_payload.base),
+                        });
+                    }
+                    return llvm.constVector(
+                        llvm_elems.ptr,
+                        @intCast(c_uint, llvm_elems.len),
+                    );
+                },
                 else => unreachable,
             },
 
src/codegen.zig
@@ -854,6 +854,14 @@ pub fn generateSymbol(
                 }
                 return Result{ .appended = {} };
             },
+            .str_lit => {
+                const str_lit = typed_value.val.castTag(.str_lit).?.data;
+                const mod = bin_file.options.module.?;
+                const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len];
+                try code.ensureUnusedCapacity(str_lit.len);
+                code.appendSliceAssumeCapacity(bytes);
+                return Result{ .appended = {} };
+            },
             else => unreachable,
         },
         else => |t| {
test/behavior/lower_strlit_to_vector.zig
@@ -0,0 +1,18 @@
+const std = @import("std");
+const builtin = @import("builtin");
+
+test "strlit to vector" {
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    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_wasm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+
+    const strlit = "0123456789abcdef0123456789ABCDEF";
+    const vec_from_strlit: @Vector(32, u8) = strlit.*;
+    const arr_from_vec = @as([32]u8, vec_from_strlit);
+    for (strlit) |c, i|
+        try std.testing.expect(c == arr_from_vec[i]);
+    try std.testing.expectEqualSlices(u8, strlit, &arr_from_vec);
+}
test/behavior.zig
@@ -161,6 +161,7 @@ test {
     _ = @import("behavior/int_div.zig");
     _ = @import("behavior/inttoptr.zig");
     _ = @import("behavior/ir_block_deps.zig");
+    _ = @import("behavior/lower_strlit_to_vector.zig");
     _ = @import("behavior/math.zig");
     _ = @import("behavior/maximum_minimum.zig");
     _ = @import("behavior/member_func.zig");