diff options
| author | Robin Voetter <robin@voetter.nl> | 2021-10-16 19:51:39 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2021-10-17 20:33:04 +0200 |
| commit | fd838584bfdc5ef4fb57927bded9e34474bc59d3 (patch) | |
| tree | 0c92bf6f81d2f4ca8aa94eec0460ad46e2041302 /src/codegen/llvm.zig | |
| parent | d193ba9843324dcaf239220df8db63ebe3adf67e (diff) | |
| download | zig-fd838584bfdc5ef4fb57927bded9e34474bc59d3.tar.gz zig-fd838584bfdc5ef4fb57927bded9e34474bc59d3.zip | |
stage2: vector constants
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 61 |
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}), } } |
