authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-21 17:19:08+01:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-21 20:32:39+01:00
log310a44d5be051a339b5739d59416a70604375541
tree585f13adadeb49cd50ffd85f0343921ebc203a02
parent7800ae05a2e00eb289a6fb8589e132ce8d30fa18

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.

4 files changed, 26 insertions(+), 13 deletions(-)

src/Module.zig+2
...@@ -1462,6 +1462,8 @@ pub const WipZirCode = struct {...@@ -1462,6 +1462,8 @@ pub const WipZirCode = struct {
1462 .str,1462 .str,
1463 .sub,1463 .sub,
1464 .subwrap,1464 .subwrap,
1465 .negate,
1466 .negate_wrap,
1465 .typeof,1467 .typeof,
1466 .xor,1468 .xor,
1467 .optional_type,1469 .optional_type,
src/Sema.zig+2
...@@ -156,6 +156,8 @@ pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Inde...@@ -156,6 +156,8 @@ pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Inde
156 .addwrap => try sema.zirArithmetic(block, zir_inst),156 .addwrap => try sema.zirArithmetic(block, zir_inst),
157 .sub => try sema.zirArithmetic(block, zir_inst),157 .sub => try sema.zirArithmetic(block, zir_inst),
158 .subwrap => try sema.zirArithmetic(block, zir_inst),158 .subwrap => try sema.zirArithmetic(block, zir_inst),
159 .negate => @panic("TODO"),
160 .negate_wrap => @panic("TODO"),
159 .mul => try sema.zirArithmetic(block, zir_inst),161 .mul => try sema.zirArithmetic(block, zir_inst),
160 .mulwrap => try sema.zirArithmetic(block, zir_inst),162 .mulwrap => try sema.zirArithmetic(block, zir_inst),
161 .div => try sema.zirArithmetic(block, zir_inst),163 .div => try sema.zirArithmetic(block, zir_inst),
src/astgen.zig+10-13
...@@ -373,12 +373,11 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -373,12 +373,11 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
373 .bool_and => return boolBinOp(mod, scope, rl, node, true),373 .bool_and => return boolBinOp(mod, scope, rl, node, true),
374 .bool_or => return boolBinOp(mod, scope, rl, node, false),374 .bool_or => return boolBinOp(mod, scope, rl, node, false),
375375
376 .negation => @panic("TODO"),
377 .negation_wrap => @panic("TODO"),
378 .bool_not => return boolNot(mod, scope, rl, node),376 .bool_not => return boolNot(mod, scope, rl, node),
379 .bit_not => return bitNot(mod, scope, rl, node),377 .bit_not => return bitNot(mod, scope, rl, node),
380 //.negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)),378
381 //.negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)),379 .negation => return negation(mod, scope, rl, node, .negate),
380 .negation_wrap => return negation(mod, scope, rl, node, .negate_wrap),
382381
383 .identifier => return identifier(mod, scope, rl, node),382 .identifier => return identifier(mod, scope, rl, node),
384383
...@@ -1318,26 +1317,24 @@ fn bitNot(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne...@@ -1318,26 +1317,24 @@ fn bitNot(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inne
13181317
1319 const gz = scope.getGenZir();1318 const gz = scope.getGenZir();
1320 const operand = try expr(mod, scope, .none, node_datas[node].lhs);1319 const operand = try expr(mod, scope, .none, node_datas[node].lhs);
1321 const result = try gz.addUnTok(.bit_not, operand, node);1320 const result = try gz.addUnNode(.bit_not, operand, node);
1322 return rvalue(mod, scope, rl, result, node);1321 return rvalue(mod, scope, rl, result, node);
1323}1322}
13241323
1325fn negation(1324fn negation(
1326 mod: *Module,1325 mod: *Module,
1327 scope: *Scope,1326 scope: *Scope,
1327 rl: ResultLoc,
1328 node: ast.Node.Index,1328 node: ast.Node.Index,
1329 op_inst_tag: zir.Inst.Tag,1329 tag: zir.Inst.Tag,
1330) InnerError!zir.Inst.Ref {1330) InnerError!zir.Inst.Ref {
1331 const tree = scope.tree();1331 const tree = scope.tree();
1332 const node_datas = tree.nodes.items(.data);1332 const node_datas = tree.nodes.items(.data);
1333 const main_tokens = tree.nodes.items(.main_token);
13341333
1335 const lhs = try addZIRInstConst(mod, scope, src, .{1334 const gz = scope.getGenZir();
1336 .ty = Type.initTag(.comptime_int),1335 const operand = try expr(mod, scope, .none, node_datas[node].lhs);
1337 .val = Value.initTag(.zero),1336 const result = try gz.addUnNode(tag, operand, node);
1338 });1337 return rvalue(mod, scope, rl, result, node);
1339 const rhs = try expr(mod, scope, .none, node_datas[node].lhs);
1340 return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
1341}1338}
13421339
1343fn ptrType(1340fn ptrType(
src/zir.zig+12
...@@ -737,6 +737,14 @@ pub const Inst = struct {...@@ -737,6 +737,14 @@ pub const Inst = struct {
737 sub,737 sub,
738 /// Twos complement wrapping integer subtraction.738 /// Twos complement wrapping integer subtraction.
739 subwrap,739 subwrap,
740 /// Arithmetic negation. Asserts no integer overflow.
741 /// Same as sub with a lhs of 0, split into a separate instruction to save memory.
742 /// Uses `un_node`.
743 negate,
744 /// Twos complement wrapping integer negation.
745 /// Same as subwrap with a lhs of 0, split into a separate instruction to save memory.
746 /// Uses `un_node`.
747 negate_wrap,
740 /// Returns the type of a value.748 /// Returns the type of a value.
741 /// Uses the `un_tok` field.749 /// Uses the `un_tok` field.
742 typeof,750 typeof,
...@@ -944,6 +952,8 @@ pub const Inst = struct {...@@ -944,6 +952,8 @@ pub const Inst = struct {
944 .str,952 .str,
945 .sub,953 .sub,
946 .subwrap,954 .subwrap,
955 .negate,
956 .negate_wrap,
947 .typeof,957 .typeof,
948 .xor,958 .xor,
949 .optional_type,959 .optional_type,
...@@ -1341,6 +1351,8 @@ const Writer = struct {...@@ -1341,6 +1351,8 @@ const Writer = struct {
1341 .@"await",1351 .@"await",
1342 .bit_not,1352 .bit_not,
1343 .bool_not,1353 .bool_not,
1354 .negate,
1355 .negate_wrap,
1344 .call_none,1356 .call_none,
1345 .compile_error,1357 .compile_error,
1346 .deref_node,1358 .deref_node,