diff options
| author | Robin Voetter <robin@voetter.nl> | 2021-05-15 14:04:41 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2021-05-16 14:13:23 +0200 |
| commit | ae2e21639a958b0bc8c085c8eac6733aaa933457 (patch) | |
| tree | fd828ba3d5f399b0e01c90eafc96b001d8e0f904 /src/codegen/spirv.zig | |
| parent | cbf5280f54509e7aa58d8fd14258274a12efeee1 (diff) | |
| download | zig-ae2e21639a958b0bc8c085c8eac6733aaa933457.tar.gz zig-ae2e21639a958b0bc8c085c8eac6733aaa933457.zip | |
SPIR-V: Some initial floating point constant generation
Diffstat (limited to 'src/codegen/spirv.zig')
| -rw-r--r-- | src/codegen/spirv.zig | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 8be42627ff..f4f437a064 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -143,6 +143,13 @@ pub const DeclGen = struct { 32; } + /// Checks whether the type is "composite int", an integer consisting of multiple native integers. These are represented by + /// arrays of largestSupportedIntBits(). + /// Asserts `ty` is an integer. + fn isCompositeInt(self: *DeclGen, ty: Type) bool { + return self.backingIntBits(ty) == null; + } + /// Generate a constant representing `val`. /// TODO: Deduplication? fn genConstant(self: *DeclGen, ty: Type, val: Value) Error!u32 { @@ -160,6 +167,37 @@ pub const DeclGen = struct { const opcode: spec.Opcode = if (val.toBool()) .OpConstantTrue else .OpConstantFalse; try writeInstruction(code, opcode, &[_]u32{ result_type_id, result_id }); }, + .Float => { + // At this point we are guaranteed that the target floating point type is supported, otherwise the function + // would have exited at getOrGenType(ty). + + // f16 and f32 require one word of storage. f64 requires 2, low-order first. + + switch (val.tag()) { + .float_16 => try writeInstruction(code, .OpConstant, &[_]u32{ + result_type_id, + result_id, + @bitCast(u16, val.castTag(.float_16).?.data) + }), + .float_32 => try writeInstruction(code, .OpConstant, &[_]u32{ + result_type_id, + result_id, + @bitCast(u32, val.castTag(.float_32).?.data) + }), + .float_64 => { + const float_bits = @bitCast(u64, val.castTag(.float_64).?.data); + try writeInstruction(code, .OpConstant, &[_]u32{ + result_type_id, + result_id, + @truncate(u32, float_bits), + @truncate(u32, float_bits >> 32), + }); + }, + .float_128 => unreachable, // Filtered out in the call to getOrGenType. + // TODO: What tags do we need to handle here anyway? + else => return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: float constant generation of value {s}\n", .{ val.tag() }), + } + }, else => return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: constant generation of type {s}\n", .{ ty.zigTypeTag() }), } @@ -180,8 +218,10 @@ pub const DeclGen = struct { .Void => try writeInstruction(code, .OpTypeVoid, &[_]u32{ result_id }), .Bool => try writeInstruction(code, .OpTypeBool, &[_]u32{ result_id }), .Int => { - const backing_bits = self.backingIntBits(ty) orelse - return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: implement fallback for {}", .{ ty }); + const backing_bits = self.backingIntBits(ty) orelse { + // Integers too big for any native type are represented as "composite integers": An array of largestSupportedIntBits. + return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: implement composite ints {}", .{ ty }); + }; // TODO: If backing_bits != int_info.bits, a duplicate type might be generated here. try writeInstruction(code, .OpTypeInt, &[_]u32{ @@ -238,7 +278,7 @@ pub const DeclGen = struct { // Although not 100% the same, Zig vectors map quite neatly to SPIR-V vectors (including many integer and float operations // which work on them), so simply use those. // Note: SPIR-V vectors only support bools, ints and floats, so pointer vectors need to be supported another way. - // "big integers" (larger than the largest supported native type) can probably be represented by an array of vectors. + // "composite integers" (larger than the largest supported native type) can probably be represented by an array of vectors. // TODO: Vectors are not yet supported by the self-hosted compiler itself it seems. return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: implement type Vector", .{}); @@ -310,7 +350,6 @@ pub const DeclGen = struct { // TODO: Breakpoints won't be supported in SPIR-V, but the compiler seems to insert them // throughout the IR. .breakpoint => null, - // TODO: What does this entail? .dbg_stmt => null, .ret => self.genRet(inst.castTag(.ret).?), .retvoid => self.genRetVoid(), |
