aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2021-05-16 14:55:09 +0200
committerRobin Voetter <robin@voetter.nl>2021-05-16 14:55:09 +0200
commit880473dc3f08e2f8c0cef85777d50e25e4bcb062 (patch)
tree7479e7ed6573a4552200503e79e8ee8a9a53d8a3 /src/codegen
parent489b3ef7d47c877aa7e761ddf00763bfe1dc03a7 (diff)
downloadzig-880473dc3f08e2f8c0cef85777d50e25e4bcb062.tar.gz
zig-880473dc3f08e2f8c0cef85777d50e25e4bcb062.zip
SPIR-V: Unary not operation
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/spirv.zig22
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];