Commit 310a44d5be

Isaac Freund <ifreund@ifreund.xyz>
2021-03-21 17:19:08
zir: add negate/negate_wrap, implement astgen
These were previously implemented as a sub/sub_wrap instruction with a lhs of 0. Making this separate instructions however allows us to save some memory as there is no need to store a lhs.
1 parent 7800ae0
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(
src/Module.zig
@@ -1462,6 +1462,8 @@ pub const WipZirCode = struct {
                 .str,
                 .sub,
                 .subwrap,
+                .negate,
+                .negate_wrap,
                 .typeof,
                 .xor,
                 .optional_type,
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),
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,