| ... | @@ -264,6 +264,40 @@ pub const DeclGen = struct { | ... | @@ -264,6 +264,40 @@ pub const DeclGen = struct { |
| 264 | } | 264 | } |
| 265 | | 265 | |
| 266 | switch (ty.zigTypeTag()) { | 266 | 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 | }, |
| 267 | .Bool => { | 301 | .Bool => { |
| 268 | const opcode: Opcode = if (val.toBool()) .OpConstantTrue else .OpConstantFalse; | 302 | const opcode: Opcode = if (val.toBool()) .OpConstantTrue else .OpConstantFalse; |
| 269 | try writeInstruction(code, opcode, &[_]Word{ result_type_id, result_id }); | 303 | try writeInstruction(code, opcode, &[_]Word{ result_type_id, result_id }); |
| ... | @@ -282,8 +316,8 @@ pub const DeclGen = struct { | ... | @@ -282,8 +316,8 @@ pub const DeclGen = struct { |
| 282 | try writeInstruction(code, .OpConstant, &[_]Word{ | 316 | try writeInstruction(code, .OpConstant, &[_]Word{ |
| 283 | result_type_id, | 317 | result_type_id, |
| 284 | result_id, | 318 | result_id, |
| 285 | @truncate(Word, float_bits), | 319 | @truncate(u32, float_bits), |
| 286 | @truncate(Word, float_bits >> 32), | 320 | @truncate(u32, float_bits >> @bitSizeOf(u32)), |
| 287 | }); | 321 | }); |
| 288 | }, | 322 | }, |
| 289 | 128 => unreachable, // Filtered out in the call to getOrGenType. | 323 | 128 => unreachable, // Filtered out in the call to getOrGenType. |