authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-15 02:39:58+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-16 14:13:23+02:00
log4403f3598a97d93466c62a91cf3a5aacc6d113a6
treefb827f3ca132165fd25a15e380a4dad255c1f89b
parent38cdfebad3889853e5393b9f7b63e3c85e9d793f

SPIR-V: Proper floating point type generation


1 files changed, 24 insertions(+), 5 deletions(-)

src/codegen/spirv.zig+24-5
......@@ -117,6 +117,7 @@ pub const DeclGen = struct {
117117 return already_generated;
118118 }
119119
120 const target = self.module.getTarget();
120121 const code = &self.spv.types_and_globals;
121122 const result_id = self.spv.allocResultId();
122123
......@@ -126,7 +127,7 @@ pub const DeclGen = struct {
126127 .Int => {
127128 const int_info = ty.intInfo(self.module.getTarget());
128129 const backing_bits = self.backingIntBits(int_info.bits) orelse
129 return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: implement fallback for integer of {} bits", .{ int_info.bits });
130 return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: implement fallback for {}", .{ ty });
130131
131132 try writeInstruction(code, .OpTypeInt, &[_]u32{
132133 result_id,
......@@ -137,14 +138,32 @@ pub const DeclGen = struct {
137138 },
138139 });
139140 },
140 // TODO: Capabilities.
141 .Float => try writeInstruction(code, .OpTypeFloat, &[_]u32{ result_id, ty.floatBits(self.module.getTarget()) }),
141 .Float => {
142 // We can (and want) not really emulate floating points with other floating point types like with the integer types,
143 // so if the float is not supported, just return an error.
144 const bits = ty.floatBits(target);
145 const supported = switch (bits) {
146 16 => Target.spirv.featureSetHas(target.cpu.features, .Float16),
147 32 => true,
148 64 => Target.spirv.featureSetHas(target.cpu.features, .Float64),
149 else => false
150 };
151
152 if (!supported) {
153 return self.fail(.{.node_offset = 0}, "Floating point width of {} bits is not supported for the current SPIR-V feature set", .{ bits });
154 }
155
156 try writeInstruction(code, .OpTypeFloat, &.{
157 result_id,
158 bits
159 });
160 },
142161 .Fn => {
143162 // We only support zig-calling-convention functions, no varargs.
144163 if (ty.fnCallingConvention() != .Unspecified)
145 return self.fail(.{.node_offset = 0}, "Invalid calling convention for SPIR-V", .{});
164 return self.fail(.{.node_offset = 0}, "Unsupported calling convention for SPIR-V", .{});
146165 if (ty.fnIsVarArgs())
147 return self.fail(.{.node_offset = 0}, "VarArgs are not supported for SPIR-V", .{});
166 return self.fail(.{.node_offset = 0}, "VarArgs unsupported for SPIR-V", .{});
148167
149168 // In order to avoid a temporary here, first generate all the required types and then simply look them up
150169 // when generating the function type.