| ... | @@ -453,6 +453,7 @@ pub const DeclGen = struct { | ... | @@ -453,6 +453,7 @@ pub const DeclGen = struct { |
| 453 | .cmp_lte => try self.genBinOp(inst.castTag(.cmp_lte).?), | 453 | .cmp_lte => try self.genBinOp(inst.castTag(.cmp_lte).?), |
| 454 | .bool_and => try self.genBinOp(inst.castTag(.bool_and).?), | 454 | .bool_and => try self.genBinOp(inst.castTag(.bool_and).?), |
| 455 | .bool_or => try self.genBinOp(inst.castTag(.bool_or).?), | 455 | .bool_or => try self.genBinOp(inst.castTag(.bool_or).?), |
| | 456 | .not => try self.genUnOp(inst.castTag(.not).?), |
| 456 | .arg => self.genArg(), | 457 | .arg => self.genArg(), |
| 457 | // TODO: Breakpoints won't be supported in SPIR-V, but the compiler seems to insert them | 458 | // TODO: Breakpoints won't be supported in SPIR-V, but the compiler seems to insert them |
| 458 | // throughout the IR. | 459 | // throughout the IR. |
| ... | @@ -527,7 +528,7 @@ pub const DeclGen = struct { | ... | @@ -527,7 +528,7 @@ pub const DeclGen = struct { |
| 527 | try writeInstruction(&self.spv.fn_decls, opcode, &[_]u32{ result_type_id, result_id, lhs_id, rhs_id }); | 528 | try writeInstruction(&self.spv.fn_decls, opcode, &[_]u32{ result_type_id, result_id, lhs_id, rhs_id }); |
| 528 | | 529 | |
| 529 | // TODO: Trap on overflow? Probably going to be annoying. | 530 | // TODO: Trap on overflow? Probably going to be annoying. |
| 530 | // TODO: Look into NoSignedWrap/NoUnsignedWrap extensions. | 531 | // TODO: Look into SPV_KHR_no_integer_wrap_decoration which provides NoSignedWrap/NoUnsignedWrap. |
| 531 | | 532 | |
| 532 | if (info.class != .strange_integer) | 533 | if (info.class != .strange_integer) |
| 533 | return result_id; | 534 | return result_id; |
| ... | @@ -535,6 +536,25 @@ pub const DeclGen = struct { | ... | @@ -535,6 +536,25 @@ pub const DeclGen = struct { |
| 535 | return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: strange integer operation mask", .{}); | 536 | return self.fail(.{.node_offset = 0}, "TODO: SPIR-V backend: strange integer operation mask", .{}); |
| 536 | } | 537 | } |
| 537 | | 538 | |
| | 539 | fn genUnOp(self: *DeclGen, inst: *Inst.UnOp) !u32 { |
| | 540 | const operand_id = try self.resolve(inst.operand); |
| | 541 | |
| | 542 | const result_id = self.spv.allocResultId(); |
| | 543 | const result_type_id = try self.getOrGenType(inst.base.ty); |
| | 544 | |
| | 545 | const info = try self.arithmeticTypeInfo(inst.operand.ty); |
| | 546 | |
| | 547 | const opcode = switch (inst.base.tag) { |
| | 548 | // Bool -> bool |
| | 549 | .not => Opcode.OpLogicalNot, |
| | 550 | else => unreachable, |
| | 551 | }; |
| | 552 | |
| | 553 | try writeInstruction(&self.spv.fn_decls, opcode, &[_]u32{ result_type_id, result_id, operand_id }); |
| | 554 | |
| | 555 | return result_id; |
| | 556 | } |
| | 557 | |
| 538 | fn genArg(self: *DeclGen) u32 { | 558 | fn genArg(self: *DeclGen) u32 { |
| 539 | defer self.next_arg_index += 1; | 559 | defer self.next_arg_index += 1; |
| 540 | return self.args.items[self.next_arg_index]; | 560 | return self.args.items[self.next_arg_index]; |