| ... | @@ -117,6 +117,7 @@ pub const DeclGen = struct { | ... | @@ -117,6 +117,7 @@ pub const DeclGen = struct { |
| 117 | return already_generated; | 117 | return already_generated; |
| 118 | } | 118 | } |
| 119 | | 119 | |
| | 120 | const target = self.module.getTarget(); |
| 120 | const code = &self.spv.types_and_globals; | 121 | const code = &self.spv.types_and_globals; |
| 121 | const result_id = self.spv.allocResultId(); | 122 | const result_id = self.spv.allocResultId(); |
| 122 | | 123 | |
| ... | @@ -126,7 +127,7 @@ pub const DeclGen = struct { | ... | @@ -126,7 +127,7 @@ pub const DeclGen = struct { |
| 126 | .Int => { | 127 | .Int => { |
| 127 | const int_info = ty.intInfo(self.module.getTarget()); | 128 | const int_info = ty.intInfo(self.module.getTarget()); |
| 128 | const backing_bits = self.backingIntBits(int_info.bits) orelse | 129 | 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 }); |
| 130 | | 131 | |
| 131 | try writeInstruction(code, .OpTypeInt, &[_]u32{ | 132 | try writeInstruction(code, .OpTypeInt, &[_]u32{ |
| 132 | result_id, | 133 | result_id, |
| ... | @@ -137,14 +138,32 @@ pub const DeclGen = struct { | ... | @@ -137,14 +138,32 @@ pub const DeclGen = struct { |
| 137 | }, | 138 | }, |
| 138 | }); | 139 | }); |
| 139 | }, | 140 | }, |
| 140 | // TODO: Capabilities. | 141 | .Float => { |
| 141 | .Float => try writeInstruction(code, .OpTypeFloat, &[_]u32{ result_id, ty.floatBits(self.module.getTarget()) }), | 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 | }, |
| 142 | .Fn => { | 161 | .Fn => { |
| 143 | // We only support zig-calling-convention functions, no varargs. | 162 | // We only support zig-calling-convention functions, no varargs. |
| 144 | if (ty.fnCallingConvention() != .Unspecified) | 163 | 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", .{}); |
| 146 | if (ty.fnIsVarArgs()) | 165 | 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", .{}); |
| 148 | | 167 | |
| 149 | // In order to avoid a temporary here, first generate all the required types and then simply look them up | 168 | // In order to avoid a temporary here, first generate all the required types and then simply look them up |
| 150 | // when generating the function type. | 169 | // when generating the function type. |