authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-16 19:51:39+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-17 20:33:04+02:00
logfd838584bfdc5ef4fb57927bded9e34474bc59d3
tree0c92bf6f81d2f4ca8aa94eec0460ad46e2041302
parentd193ba9843324dcaf239220df8db63ebe3adf67e

stage2: vector constants


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

src/codegen/llvm.zig+60-1
...@@ -1279,6 +1279,66 @@ pub const DeclGen = struct {...@@ -1279,6 +1279,66 @@ pub const DeclGen = struct {
1279 }1279 }
1280 return llvm_union_ty.constNamedStruct(&fields, fields.len);1280 return llvm_union_ty.constNamedStruct(&fields, fields.len);
1281 },1281 },
1282 .Vector => switch (tv.val.tag()) {
1283 .bytes => {
1284 // Note, sentinel is not stored even if the type has a sentinel.
1285 const bytes = tv.val.castTag(.bytes).?.data;
1286 const vector_len = tv.ty.arrayLen();
1287 assert(vector_len == bytes.len or vector_len + 1 == bytes.len);
1288
1289 const elem_ty = tv.ty.elemType();
1290 const llvm_elems = try self.gpa.alloc(*const llvm.Value, vector_len);
1291 defer self.gpa.free(llvm_elems);
1292 for (llvm_elems) |*elem, i| {
1293 var byte_payload: Value.Payload.U64 = .{
1294 .base = .{ .tag = .int_u64 },
1295 .data = bytes[i],
1296 };
1297
1298 elem.* = try self.genTypedValue(.{
1299 .ty = elem_ty,
1300 .val = Value.initPayload(&byte_payload.base),
1301 });
1302 }
1303 return llvm.constVector(
1304 llvm_elems.ptr,
1305 @intCast(c_uint, llvm_elems.len),
1306 );
1307 },
1308 .array => {
1309 // Note, sentinel is not stored even if the type has a sentinel.
1310 // The value includes the sentinel in those cases.
1311 const elem_vals = tv.val.castTag(.array).?.data;
1312 const vector_len = tv.ty.arrayLen();
1313 assert(vector_len == elem_vals.len or vector_len + 1 == elem_vals.len);
1314 const elem_ty = tv.ty.elemType();
1315 const llvm_elems = try self.gpa.alloc(*const llvm.Value, vector_len);
1316 defer self.gpa.free(llvm_elems);
1317 for (llvm_elems) |*elem, i| {
1318 elem.* = try self.genTypedValue(.{ .ty = elem_ty, .val = elem_vals[i] });
1319 }
1320 return llvm.constVector(
1321 llvm_elems.ptr,
1322 @intCast(c_uint, llvm_elems.len),
1323 );
1324 },
1325 .repeated => {
1326 // Note, sentinel is not stored even if the type has a sentinel.
1327 const val = tv.val.castTag(.repeated).?.data;
1328 const elem_ty = tv.ty.elemType();
1329 const len = tv.ty.arrayLen();
1330 const llvm_elems = try self.gpa.alloc(*const llvm.Value, len);
1331 defer self.gpa.free(llvm_elems);
1332 for (llvm_elems) |*elem| {
1333 elem.* = try self.genTypedValue(.{ .ty = elem_ty, .val = val });
1334 }
1335 return llvm.constVector(
1336 llvm_elems.ptr,
1337 @intCast(c_uint, llvm_elems.len),
1338 );
1339 },
1340 else => unreachable,
1341 },
12821342
1283 .ComptimeInt => unreachable,1343 .ComptimeInt => unreachable,
1284 .ComptimeFloat => unreachable,1344 .ComptimeFloat => unreachable,
...@@ -1293,7 +1353,6 @@ pub const DeclGen = struct {...@@ -1293,7 +1353,6 @@ pub const DeclGen = struct {
12931353
1294 .Frame,1354 .Frame,
1295 .AnyFrame,1355 .AnyFrame,
1296 .Vector,
1297 => return self.todo("implement const of type '{}'", .{tv.ty}),1356 => return self.todo("implement const of type '{}'", .{tv.ty}),
1298 }1357 }
1299 }1358 }
src/codegen/llvm/bindings.zig+6
...@@ -313,6 +313,12 @@ pub const VerifierFailureAction = enum(c_int) {...@@ -313,6 +313,12 @@ pub const VerifierFailureAction = enum(c_int) {
313pub const constNeg = LLVMConstNeg;313pub const constNeg = LLVMConstNeg;
314extern fn LLVMConstNeg(ConstantVal: *const Value) *const Value;314extern fn LLVMConstNeg(ConstantVal: *const Value) *const Value;
315315
316pub const constVector = LLVMConstVector;
317extern fn LLVMConstVector(
318 ScalarConstantVals: [*]*const Value,
319 Size: c_uint,
320) *const Value;
321
316pub const getEnumAttributeKindForName = LLVMGetEnumAttributeKindForName;322pub const getEnumAttributeKindForName = LLVMGetEnumAttributeKindForName;
317extern fn LLVMGetEnumAttributeKindForName(Name: [*]const u8, SLen: usize) c_uint;323extern fn LLVMGetEnumAttributeKindForName(Name: [*]const u8, SLen: usize) c_uint;
318324