diff options
| author | Robin Voetter <robin@voetter.nl> | 2021-05-16 14:55:09 +0200 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2021-05-16 14:55:09 +0200 |
| commit | 880473dc3f08e2f8c0cef85777d50e25e4bcb062 (patch) | |
| tree | 7479e7ed6573a4552200503e79e8ee8a9a53d8a3 /src/codegen | |
| parent | 489b3ef7d47c877aa7e761ddf00763bfe1dc03a7 (diff) | |
| download | zig-880473dc3f08e2f8c0cef85777d50e25e4bcb062.tar.gz zig-880473dc3f08e2f8c0cef85777d50e25e4bcb062.zip | |
SPIR-V: Unary not operation
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/spirv.zig | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index 949e9fc6a2..7992a7a465 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -453,6 +453,7 @@ pub const DeclGen = struct { .cmp_lte => try self.genBinOp(inst.castTag(.cmp_lte).?), .bool_and => try self.genBinOp(inst.castTag(.bool_and).?), .bool_or => try self.genBinOp(inst.castTag(.bool_or).?), + .not => try self.genUnOp(inst.castTag(.not).?), .arg => self.genArg(), // TODO: Breakpoints won't be supported in SPIR-V, but the compiler seems to insert them // throughout the IR. @@ -527,7 +528,7 @@ pub const DeclGen = struct { try writeInstruction(&self.spv.fn_decls, opcode, &[_]u32{ result_type_id, result_id, lhs_id, rhs_id }); // TODO: Trap on overflow? Probably going to be annoying. - // TODO: Look into NoSignedWrap/NoUnsignedWrap extensions. + // TODO: Look into SPV_KHR_no_integer_wrap_decoration which provides NoSignedWrap/NoUnsignedWrap. if (info.class != .strange_integer) return result_id; @@ -535,6 +536,25 @@ pub const DeclGen = struct { return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: strange integer operation mask", .{}); } + fn genUnOp(self: *DeclGen, inst: *Inst.UnOp) !u32 { + const operand_id = try self.resolve(inst.operand); + + const result_id = self.spv.allocResultId(); + const result_type_id = try self.getOrGenType(inst.base.ty); + + const info = try self.arithmeticTypeInfo(inst.operand.ty); + + const opcode = switch (inst.base.tag) { + // Bool -> bool + .not => Opcode.OpLogicalNot, + else => unreachable, + }; + + try writeInstruction(&self.spv.fn_decls, opcode, &[_]u32{ result_type_id, result_id, operand_id }); + + return result_id; + } + fn genArg(self: *DeclGen) u32 { defer self.next_arg_index += 1; return self.args.items[self.next_arg_index]; |
