aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2021-10-16 19:51:39 +0200
committerRobin Voetter <robin@voetter.nl>2021-10-17 20:33:04 +0200
commitfd838584bfdc5ef4fb57927bded9e34474bc59d3 (patch)
tree0c92bf6f81d2f4ca8aa94eec0460ad46e2041302 /src/codegen/llvm.zig
parentd193ba9843324dcaf239220df8db63ebe3adf67e (diff)
downloadzig-fd838584bfdc5ef4fb57927bded9e34474bc59d3.tar.gz
zig-fd838584bfdc5ef4fb57927bded9e34474bc59d3.zip
stage2: vector constants
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig61
1 files changed, 60 insertions, 1 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 70442729ba..61227b188c 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1279,6 +1279,66 @@ pub const DeclGen = struct {
}
return llvm_union_ty.constNamedStruct(&fields, fields.len);
},
+ .Vector => switch (tv.val.tag()) {
+ .bytes => {
+ // Note, sentinel is not stored even if the type has a sentinel.
+ const bytes = tv.val.castTag(.bytes).?.data;
+ const vector_len = tv.ty.arrayLen();
+ assert(vector_len == bytes.len or vector_len + 1 == bytes.len);
+
+ const elem_ty = tv.ty.elemType();
+ const llvm_elems = try self.gpa.alloc(*const llvm.Value, vector_len);
+ defer self.gpa.free(llvm_elems);
+ for (llvm_elems) |*elem, i| {
+ var byte_payload: Value.Payload.U64 = .{
+ .base = .{ .tag = .int_u64 },
+ .data = bytes[i],
+ };
+
+ elem.* = try self.genTypedValue(.{
+ .ty = elem_ty,
+ .val = Value.initPayload(&byte_payload.base),
+ });
+ }
+ return llvm.constVector(
+ llvm_elems.ptr,
+ @intCast(c_uint, llvm_elems.len),
+ );
+ },
+ .array => {
+ // Note, sentinel is not stored even if the type has a sentinel.
+ // The value includes the sentinel in those cases.
+ const elem_vals = tv.val.castTag(.array).?.data;
+ const vector_len = tv.ty.arrayLen();
+ assert(vector_len == elem_vals.len or vector_len + 1 == elem_vals.len);
+ const elem_ty = tv.ty.elemType();
+ const llvm_elems = try self.gpa.alloc(*const llvm.Value, vector_len);
+ defer self.gpa.free(llvm_elems);
+ for (llvm_elems) |*elem, i| {
+ elem.* = try self.genTypedValue(.{ .ty = elem_ty, .val = elem_vals[i] });
+ }
+ return llvm.constVector(
+ llvm_elems.ptr,
+ @intCast(c_uint, llvm_elems.len),
+ );
+ },
+ .repeated => {
+ // Note, sentinel is not stored even if the type has a sentinel.
+ const val = tv.val.castTag(.repeated).?.data;
+ const elem_ty = tv.ty.elemType();
+ const len = tv.ty.arrayLen();
+ const llvm_elems = try self.gpa.alloc(*const llvm.Value, len);
+ defer self.gpa.free(llvm_elems);
+ for (llvm_elems) |*elem| {
+ elem.* = try self.genTypedValue(.{ .ty = elem_ty, .val = val });
+ }
+ return llvm.constVector(
+ llvm_elems.ptr,
+ @intCast(c_uint, llvm_elems.len),
+ );
+ },
+ else => unreachable,
+ },
.ComptimeInt => unreachable,
.ComptimeFloat => unreachable,
@@ -1293,7 +1353,6 @@ pub const DeclGen = struct {
.Frame,
.AnyFrame,
- .Vector,
=> return self.todo("implement const of type '{}'", .{tv.ty}),
}
}