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 {
8484 const ArithmeticTypeInfo = struct {
8585 /// A classification of the inner type.
8686 const Class = enum {
87 /// A regular, **native**, integer operation.
87 /// A regular, **native**, integer.
8888 /// This is only returned when the backend supports this int as a native type (when
8989 /// the relevant capability is enabled).
9090 integer,
......@@ -112,7 +112,7 @@ pub const DeclGen = struct {
112112 /// Whether the inner type is signed. Only relevant for integers.
113113 signedness: std.builtin.Signedness,
114114
115 /// A classification of the inner type. These four scenarios
115 /// A classification of the inner type. These scenarios
116116 /// will all have to be handled slightly different.
117117 class: Class,
118118 };
......@@ -149,6 +149,7 @@ pub const DeclGen = struct {
149149 std.debug.assert(bits != 0);
150150
151151 // 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).
152153 const ints = [_]struct{ bits: u16, feature: ?Target.spirv.Feature } {
153154 .{ .bits = 8, .feature = .Int8 },
154155 .{ .bits = 16, .feature = .Int16 },
......@@ -198,8 +199,8 @@ pub const DeclGen = struct {
198199 .Float => ArithmeticTypeInfo{
199200 .bits = ty.floatBits(target),
200201 .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,
203204 },
204205 .Int => blk: {
205206 const int_info = ty.intInfo(target);
......@@ -315,6 +316,7 @@ pub const DeclGen = struct {
315316 const bits = ty.floatBits(target);
316317 const supported = switch (bits) {
317318 16 => Target.spirv.featureSetHas(target.cpu.features, .Float16),
319 // 32-bit floats are always supported (see spec, 2.16.1, Data rules).
318320 32 => true,
319321 64 => Target.spirv.featureSetHas(target.cpu.features, .Float64),
320322 else => false,
......@@ -358,6 +360,8 @@ pub const DeclGen = struct {
358360 // which work on them), so simply use those.
359361 // Note: SPIR-V vectors only support bools, ints and floats, so pointer vectors need to be supported another way.
360362 // "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
362366 // TODO: Vectors are not yet supported by the self-hosted compiler itself it seems.
363367 return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: implement type Vector", .{});
......@@ -429,6 +433,9 @@ pub const DeclGen = struct {
429433 .sub, .subwrap => try self.genBinOp(inst.castTag(.sub).?),
430434 .mul, .mulwrap => try self.genBinOp(inst.castTag(.mul).?),
431435 .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).?),
432439 .arg => self.genArg(),
433440 // TODO: Breakpoints won't be supported in SPIR-V, but the compiler seems to insert them
434441 // throughout the IR.
......@@ -472,7 +479,10 @@ pub const DeclGen = struct {
472479 // TODO: Trap if divisor is 0?
473480 // TODO: Figure out of OpSDiv for unsigned/OpUDiv for signed does anything useful.
474481 .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,
476486 else => unreachable,
477487 };
478488