authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-16 13:39:17+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-16 14:20:18+02:00
logf14000c7e1bd9032185b3c0a2a28a73eec6c48f7
tree8fadf3ababf41f70ed02badaa9ec2bf1d5f19581
parent4735e95d1699c90e821655bdbe0afbb1044738ea

SPIR-V: More bitwise binary operations


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

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