authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-20 02:56:20+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-22 16:11:56+02:00
logb8444d2c51f334e3afec74ff80b051ed797ab480
tree8cf7285b60fb8ebd9656e844c73e0904e4118588
parentc190b2ff83308a6680b9d4587d742c253dcdee5d

SPIR-V: Preliminary integer constant encoding


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

src/codegen/spirv.zig+36-2
......@@ -264,6 +264,40 @@ pub const DeclGen = struct {
264264 }
265265
266266 switch (ty.zigTypeTag()) {
267 .Int => {
268 const int_info = ty.intInfo(target);
269 const backing_bits = self.backingIntBits(int_info.bits) orelse {
270 // Integers too big for any native type are represented as "composite integers": An array of largestSupportedIntBits.
271 return self.fail(.{ .node_offset = 0 }, "TODO: SPIR-V backend: implement composite int constants for {}", .{ty});
272 };
273
274 // We can just use toSignedInt/toUnsignedInt here as it returns u64 - a type large enough to hold any
275 // SPIR-V native type (up to i/u64 with Int64). If SPIR-V ever supports native ints of a larger size, this
276 // might need to be updated.
277 std.debug.assert(self.largestSupportedIntBits() <= std.meta.bitCount(u64));
278 var int_bits = if (ty.isSignedInt()) @bitCast(u64, val.toSignedInt()) else val.toUnsignedInt();
279
280 // Mask the low bits which make up the actual integer. This is to make sure that negative values
281 // only use the actual bits of the type.
282 // TODO: Should this be the backing type bits or the actual type bits?
283 int_bits &= (@as(u64, 1) << @intCast(u6, backing_bits)) - 1;
284
285 switch (backing_bits) {
286 0 => unreachable,
287 1...32 => try writeInstruction(code, .OpConstant, &[_]Word{
288 result_type_id,
289 result_id,
290 @truncate(u32, int_bits),
291 }),
292 33...64 => try writeInstruction(code, .OpConstant, &[_]Word{
293 result_type_id,
294 result_id,
295 @truncate(u32, int_bits),
296 @truncate(u32, int_bits >> @bitSizeOf(u32)),
297 }),
298 else => unreachable, // backing_bits is bounded by largestSupportedIntBits.
299 }
300 },
267301 .Bool => {
268302 const opcode: Opcode = if (val.toBool()) .OpConstantTrue else .OpConstantFalse;
269303 try writeInstruction(code, opcode, &[_]Word{ result_type_id, result_id });
......@@ -282,8 +316,8 @@ pub const DeclGen = struct {
282316 try writeInstruction(code, .OpConstant, &[_]Word{
283317 result_type_id,
284318 result_id,
285 @truncate(Word, float_bits),
286 @truncate(Word, float_bits >> 32),
319 @truncate(u32, float_bits),
320 @truncate(u32, float_bits >> @bitSizeOf(u32)),
287321 });
288322 },
289323 128 => unreachable, // Filtered out in the call to getOrGenType.