authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-13 20:47:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-13 20:47:47-07:00
log4f5e065d6ec10cb27589995bf5d6390647f783f2
treef00a00cdbdd3b0ffa807b5f52e63fff345584d63
parent14cef9dd3d8074b0dc2ee48a0905300ce6317aed

stage2: add ZIR support for BoolNot


4 files changed, 59 insertions(+), 0 deletions(-)

src-self-hosted/Module.zig+12
...@@ -2566,6 +2566,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In...@@ -2566,6 +2566,7 @@ fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*In
2566 .condbr => return self.analyzeInstCondBr(scope, old_inst.cast(zir.Inst.CondBr).?),2566 .condbr => return self.analyzeInstCondBr(scope, old_inst.cast(zir.Inst.CondBr).?),
2567 .isnull => return self.analyzeInstIsNull(scope, old_inst.cast(zir.Inst.IsNull).?),2567 .isnull => return self.analyzeInstIsNull(scope, old_inst.cast(zir.Inst.IsNull).?),
2568 .isnonnull => return self.analyzeInstIsNonNull(scope, old_inst.cast(zir.Inst.IsNonNull).?),2568 .isnonnull => return self.analyzeInstIsNonNull(scope, old_inst.cast(zir.Inst.IsNonNull).?),
2569 .boolnot => return self.analyzeInstBoolNot(scope, old_inst.cast(zir.Inst.BoolNot).?),
2569 }2570 }
2570}2571}
25712572
...@@ -3243,6 +3244,17 @@ fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError!...@@ -3243,6 +3244,17 @@ fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError!
3243 return self.fail(scope, inst.base.src, "TODO implement more cmp analysis", .{});3244 return self.fail(scope, inst.base.src, "TODO implement more cmp analysis", .{});
3244}3245}
32453246
3247fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.BoolNot) InnerError!*Inst {
3248 const uncasted_operand = try self.resolveInst(scope, inst.positionals.operand);
3249 const bool_type = Type.initTag(.bool);
3250 const operand = try self.coerce(scope, bool_type, uncasted_operand);
3251 if (try self.resolveDefinedValue(scope, operand)) |val| {
3252 return self.constBool(scope, inst.base.src, !val.toBool());
3253 }
3254 const b = try self.requireRuntimeBlock(scope, inst.base.src);
3255 return self.addNewInstArgs(b, inst.base.src, bool_type, Inst.Not, .{ .operand = operand });
3256}
3257
3246fn analyzeInstIsNull(self: *Module, scope: *Scope, inst: *zir.Inst.IsNull) InnerError!*Inst {3258fn analyzeInstIsNull(self: *Module, scope: *Scope, inst: *zir.Inst.IsNull) InnerError!*Inst {
3247 const operand = try self.resolveInst(scope, inst.positionals.operand);3259 const operand = try self.resolveInst(scope, inst.positionals.operand);
3248 return self.analyzeIsNull(scope, inst.base.src, operand, true);3260 return self.analyzeIsNull(scope, inst.base.src, operand, true);
src-self-hosted/codegen.zig+7
...@@ -407,6 +407,13 @@ const Function = struct {...@@ -407,6 +407,13 @@ const Function = struct {
407 .retvoid => return self.genRetVoid(inst.cast(ir.Inst.RetVoid).?, arch),407 .retvoid => return self.genRetVoid(inst.cast(ir.Inst.RetVoid).?, arch),
408 .sub => return self.genSub(inst.cast(ir.Inst.Sub).?, arch),408 .sub => return self.genSub(inst.cast(ir.Inst.Sub).?, arch),
409 .unreach => return MCValue{ .unreach = {} },409 .unreach => return MCValue{ .unreach = {} },
410 .not => return self.genNot(inst.cast(ir.Inst.Not).?, arch),
411 }
412 }
413
414 fn genNot(self: *Function, inst: *ir.Inst.Not, comptime arch: std.Target.Cpu.Arch) !MCValue {
415 switch (arch) {
416 else => return self.fail(inst.base.src, "TODO implement NOT for {}", .{self.target.cpu.arch}),
410 }417 }
411 }418 }
412419
src-self-hosted/ir.zig+10
...@@ -60,6 +60,7 @@ pub const Inst = struct {...@@ -60,6 +60,7 @@ pub const Inst = struct {
60 retvoid,60 retvoid,
61 sub,61 sub,
62 unreach,62 unreach,
63 not,
63 };64 };
6465
65 pub fn cast(base: *Inst, comptime T: type) ?*T {66 pub fn cast(base: *Inst, comptime T: type) ?*T {
...@@ -194,6 +195,15 @@ pub const Inst = struct {...@@ -194,6 +195,15 @@ pub const Inst = struct {
194 false_death_count: u32 = 0,195 false_death_count: u32 = 0,
195 };196 };
196197
198 pub const Not = struct {
199 pub const base_tag = Tag.not;
200
201 base: Inst,
202 args: struct {
203 operand: *Inst,
204 },
205 };
206
197 pub const Constant = struct {207 pub const Constant = struct {
198 pub const base_tag = Tag.constant;208 pub const base_tag = Tag.constant;
199 base: Inst,209 base: Inst,
src-self-hosted/zir.zig+30
...@@ -56,6 +56,7 @@ pub const Inst = struct {...@@ -56,6 +56,7 @@ pub const Inst = struct {
56 declval,56 declval,
57 /// Same as declval but the parameter is a `*Module.Decl` rather than a name.57 /// Same as declval but the parameter is a `*Module.Decl` rather than a name.
58 declval_in_module,58 declval_in_module,
59 boolnot,
59 /// String Literal. Makes an anonymous Decl and then takes a pointer to it.60 /// String Literal. Makes an anonymous Decl and then takes a pointer to it.
60 str,61 str,
61 int,62 int,
...@@ -115,6 +116,7 @@ pub const Inst = struct {...@@ -115,6 +116,7 @@ pub const Inst = struct {
115 .cmp,116 .cmp,
116 .isnull,117 .isnull,
117 .isnonnull,118 .isnonnull,
119 .boolnot,
118 => false,120 => false,
119121
120 .condbr,122 .condbr,
...@@ -143,6 +145,7 @@ pub const Inst = struct {...@@ -143,6 +145,7 @@ pub const Inst = struct {
143 .declval_in_module => DeclValInModule,145 .declval_in_module => DeclValInModule,
144 .compileerror => CompileError,146 .compileerror => CompileError,
145 .@"const" => Const,147 .@"const" => Const,
148 .boolnot => BoolNot,
146 .str => Str,149 .str => Str,
147 .int => Int,150 .int => Int,
148 .inttype => IntType,151 .inttype => IntType,
...@@ -299,6 +302,16 @@ pub const Inst = struct {...@@ -299,6 +302,16 @@ pub const Inst = struct {
299 kw_args: struct {},302 kw_args: struct {},
300 };303 };
301304
305 pub const BoolNot = struct {
306 pub const base_tag = Tag.boolnot;
307 base: Inst,
308
309 positionals: struct {
310 operand: *Inst,
311 },
312 kw_args: struct {},
313 };
314
302 pub const Str = struct {315 pub const Str = struct {
303 pub const base_tag = Tag.str;316 pub const base_tag = Tag.str;
304 base: Inst,317 base: Inst,
...@@ -762,6 +775,7 @@ const Writer = struct {...@@ -762,6 +775,7 @@ const Writer = struct {
762 .declval_in_module => return self.writeInstToStreamGeneric(stream, .declval_in_module, inst),775 .declval_in_module => return self.writeInstToStreamGeneric(stream, .declval_in_module, inst),
763 .compileerror => return self.writeInstToStreamGeneric(stream, .compileerror, inst),776 .compileerror => return self.writeInstToStreamGeneric(stream, .compileerror, inst),
764 .@"const" => return self.writeInstToStreamGeneric(stream, .@"const", inst),777 .@"const" => return self.writeInstToStreamGeneric(stream, .@"const", inst),
778 .boolnot => return self.writeInstToStreamGeneric(stream, .boolnot, inst),
765 .str => return self.writeInstToStreamGeneric(stream, .str, inst),779 .str => return self.writeInstToStreamGeneric(stream, .str, inst),
766 .int => return self.writeInstToStreamGeneric(stream, .int, inst),780 .int => return self.writeInstToStreamGeneric(stream, .int, inst),
767 .inttype => return self.writeInstToStreamGeneric(stream, .inttype, inst),781 .inttype => return self.writeInstToStreamGeneric(stream, .inttype, inst),
...@@ -1658,6 +1672,22 @@ const EmitZIR = struct {...@@ -1658,6 +1672,22 @@ const EmitZIR = struct {
1658 };1672 };
1659 for (body.instructions) |inst| {1673 for (body.instructions) |inst| {
1660 const new_inst = switch (inst.tag) {1674 const new_inst = switch (inst.tag) {
1675 .not => blk: {
1676 const old_inst = inst.cast(ir.Inst.Not).?;
1677 assert(inst.ty.zigTypeTag() == .Bool);
1678 const new_inst = try self.arena.allocator.create(Inst.BoolNot);
1679 new_inst.* = .{
1680 .base = .{
1681 .src = inst.src,
1682 .tag = Inst.BoolNot.base_tag,
1683 },
1684 .positionals = .{
1685 .operand = try self.resolveInst(new_body, old_inst.args.operand),
1686 },
1687 .kw_args = .{},
1688 };
1689 break :blk &new_inst.base;
1690 },
1661 .add => blk: {1691 .add => blk: {
1662 const old_inst = inst.cast(ir.Inst.Add).?;1692 const old_inst = inst.cast(ir.Inst.Add).?;
1663 const new_inst = try self.arena.allocator.create(Inst.Add);1693 const new_inst = try self.arena.allocator.create(Inst.Add);