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.
This commit is contained in:
@@ -1462,6 +1462,8 @@ pub const WipZirCode = struct {
|
||||
.str,
|
||||
.sub,
|
||||
.subwrap,
|
||||
.negate,
|
||||
.negate_wrap,
|
||||
.typeof,
|
||||
.xor,
|
||||
.optional_type,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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(
|
||||
|
||||
12
src/zir.zig
12
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,
|
||||
|
||||
Reference in New Issue
Block a user