| ... | ... | @@ -84,7 +84,7 @@ pub const DeclGen = struct { |
| 84 | 84 | const ArithmeticTypeInfo = struct { |
| 85 | 85 | /// A classification of the inner type. |
| 86 | 86 | const Class = enum { |
| 87 | | /// A regular, **native**, integer operation. |
| 87 | /// A regular, **native**, integer. |
| 88 | 88 | /// This is only returned when the backend supports this int as a native type (when |
| 89 | 89 | /// the relevant capability is enabled). |
| 90 | 90 | integer, |
| ... | ... | @@ -112,7 +112,7 @@ pub const DeclGen = struct { |
| 112 | 112 | /// Whether the inner type is signed. Only relevant for integers. |
| 113 | 113 | signedness: std.builtin.Signedness, |
| 114 | 114 | |
| 115 | | /// A classification of the inner type. These four scenarios |
| 115 | /// A classification of the inner type. These scenarios |
| 116 | 116 | /// will all have to be handled slightly different. |
| 117 | 117 | class: Class, |
| 118 | 118 | }; |
| ... | ... | @@ -149,6 +149,7 @@ pub const DeclGen = struct { |
| 149 | 149 | std.debug.assert(bits != 0); |
| 150 | 150 | |
| 151 | 151 | // 8, 16 and 64-bit integers require the Int8, Int16 and Inr64 capabilities respectively. |
| 152 | // 32-bit integers are always supported (see spec, 2.16.1, Data rules). |
| 152 | 153 | const ints = [_]struct{ bits: u16, feature: ?Target.spirv.Feature } { |
| 153 | 154 | .{ .bits = 8, .feature = .Int8 }, |
| 154 | 155 | .{ .bits = 16, .feature = .Int16 }, |
| ... | ... | @@ -198,8 +199,8 @@ pub const DeclGen = struct { |
| 198 | 199 | .Float => ArithmeticTypeInfo{ |
| 199 | 200 | .bits = ty.floatBits(target), |
| 200 | 201 | .is_vector = false, |
| 201 | | .signedness = .signed, // I guess technically it is. |
| 202 | | .class = .float |
| 202 | .signedness = .signed, // Technically, but doesn't matter for this class. |
| 203 | .class = .float, |
| 203 | 204 | }, |
| 204 | 205 | .Int => blk: { |
| 205 | 206 | const int_info = ty.intInfo(target); |
| ... | ... | @@ -315,6 +316,7 @@ pub const DeclGen = struct { |
| 315 | 316 | const bits = ty.floatBits(target); |
| 316 | 317 | const supported = switch (bits) { |
| 317 | 318 | 16 => Target.spirv.featureSetHas(target.cpu.features, .Float16), |
| 319 | // 32-bit floats are always supported (see spec, 2.16.1, Data rules). |
| 318 | 320 | 32 => true, |
| 319 | 321 | 64 => Target.spirv.featureSetHas(target.cpu.features, .Float64), |
| 320 | 322 | else => false, |
| ... | ... | @@ -358,6 +360,8 @@ pub const DeclGen = struct { |
| 358 | 360 | // which work on them), so simply use those. |
| 359 | 361 | // Note: SPIR-V vectors only support bools, ints and floats, so pointer vectors need to be supported another way. |
| 360 | 362 | // "composite integers" (larger than the largest supported native type) can probably be represented by an array of vectors. |
| 363 | // TODO: The SPIR-V spec mentions that vector sizes may be quite restricted! look into which we can use, and whether OpTypeVector |
| 364 | // is adequate at all for this. |
| 361 | 365 | |
| 362 | 366 | // TODO: Vectors are not yet supported by the self-hosted compiler itself it seems. |
| 363 | 367 | return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: implement type Vector", .{}); |
| ... | ... | @@ -429,6 +433,9 @@ pub const DeclGen = struct { |
| 429 | 433 | .sub, .subwrap => try self.genBinOp(inst.castTag(.sub).?), |
| 430 | 434 | .mul, .mulwrap => try self.genBinOp(inst.castTag(.mul).?), |
| 431 | 435 | .div => try self.genBinOp(inst.castTag(.div).?), |
| 436 | .bit_and => try self.genBinOp(inst.castTag(.bit_and).?), |
| 437 | .bit_or => try self.genBinOp(inst.castTag(.bit_or).?), |
| 438 | .xor => try self.genBinOp(inst.castTag(.xor).?), |
| 432 | 439 | .arg => self.genArg(), |
| 433 | 440 | // TODO: Breakpoints won't be supported in SPIR-V, but the compiler seems to insert them |
| 434 | 441 | // throughout the IR. |
| ... | ... | @@ -472,7 +479,10 @@ pub const DeclGen = struct { |
| 472 | 479 | // TODO: Trap if divisor is 0? |
| 473 | 480 | // TODO: Figure out of OpSDiv for unsigned/OpUDiv for signed does anything useful. |
| 474 | 481 | .div => if (is_float) Opcode.OpFDiv else if (is_signed) Opcode.OpSDiv else Opcode.OpUDiv, |
| 475 | | |
| 482 | // Only integer versions for these. |
| 483 | .bit_and => Opcode.OpBitwiseAnd, |
| 484 | .bit_or => Opcode.OpBitwiseOr, |
| 485 | .xor => Opcode.OpBitwiseXor, |
| 476 | 486 | else => unreachable, |
| 477 | 487 | }; |
| 478 | 488 | |