diff --git a/src/Module.zig b/src/Module.zig index dcf57bb709..27d585054a 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1462,6 +1462,8 @@ pub const WipZirCode = struct { .str, .sub, .subwrap, + .negate, + .negate_wrap, .typeof, .xor, .optional_type, diff --git a/src/Sema.zig b/src/Sema.zig index 807160eec0..b078e6dc43 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -156,6 +156,8 @@ pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Inde .addwrap => try sema.zirArithmetic(block, zir_inst), .sub => try sema.zirArithmetic(block, zir_inst), .subwrap => try sema.zirArithmetic(block, zir_inst), + .negate => @panic("TODO"), + .negate_wrap => @panic("TODO"), .mul => try sema.zirArithmetic(block, zir_inst), .mulwrap => try sema.zirArithmetic(block, zir_inst), .div => try sema.zirArithmetic(block, zir_inst), diff --git a/src/astgen.zig b/src/astgen.zig index 5c621fa54f..6a6d7997a1 100644 --- a/src/astgen.zig +++ b/src/astgen.zig @@ -373,12 +373,11 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In .bool_and => return boolBinOp(mod, scope, rl, node, true), .bool_or => return boolBinOp(mod, scope, rl, node, false), - .negation => @panic("TODO"), - .negation_wrap => @panic("TODO"), .bool_not => return boolNot(mod, scope, rl, node), .bit_not => return bitNot(mod, scope, rl, node), - //.negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)), - //.negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)), + + .negation => return negation(mod, scope, rl, node, .negate), + .negation_wrap => return negation(mod, scope, rl, node, .negate_wrap), .identifier => return identifier(mod, scope, rl, node), @@ -1318,26 +1317,24 @@ fn bitNot(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne const gz = scope.getGenZir(); const operand = try expr(mod, scope, .none, node_datas[node].lhs); - const result = try gz.addUnTok(.bit_not, operand, node); + const result = try gz.addUnNode(.bit_not, operand, node); return rvalue(mod, scope, rl, result, node); } fn negation( mod: *Module, scope: *Scope, + rl: ResultLoc, node: ast.Node.Index, - op_inst_tag: zir.Inst.Tag, + tag: zir.Inst.Tag, ) InnerError!zir.Inst.Ref { const tree = scope.tree(); const node_datas = tree.nodes.items(.data); - const main_tokens = tree.nodes.items(.main_token); - const lhs = try addZIRInstConst(mod, scope, src, .{ - .ty = Type.initTag(.comptime_int), - .val = Value.initTag(.zero), - }); - const rhs = try expr(mod, scope, .none, node_datas[node].lhs); - return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); + const gz = scope.getGenZir(); + const operand = try expr(mod, scope, .none, node_datas[node].lhs); + const result = try gz.addUnNode(tag, operand, node); + return rvalue(mod, scope, rl, result, node); } fn ptrType( diff --git a/src/zir.zig b/src/zir.zig index 286d5585df..58abd7e8d8 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -737,6 +737,14 @@ pub const Inst = struct { sub, /// Twos complement wrapping integer subtraction. subwrap, + /// Arithmetic negation. Asserts no integer overflow. + /// Same as sub with a lhs of 0, split into a separate instruction to save memory. + /// Uses `un_node`. + negate, + /// Twos complement wrapping integer negation. + /// Same as subwrap with a lhs of 0, split into a separate instruction to save memory. + /// Uses `un_node`. + negate_wrap, /// Returns the type of a value. /// Uses the `un_tok` field. typeof, @@ -944,6 +952,8 @@ pub const Inst = struct { .str, .sub, .subwrap, + .negate, + .negate_wrap, .typeof, .xor, .optional_type, @@ -1341,6 +1351,8 @@ const Writer = struct { .@"await", .bit_not, .bool_not, + .negate, + .negate_wrap, .call_none, .compile_error, .deref_node,