authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-21 12:13:15-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-21 12:13:15-07:00
log8ee629aa4c7fb0127c71aec0b2c81353c4291ebb
tree221c6b97638b189d66e328c300d013292e0227f6
parent7a1a92478878f591abbadcd5735f03c817c6eb53

stage2: ability for ZIR to map multiple tags to the same type


4 files changed, 298 insertions(+), 325 deletions(-)

src-self-hosted/Module.zig+142-70
......@@ -1215,7 +1215,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
12151215 .return_type = return_type_inst,
12161216 .param_types = param_types,
12171217 }, .{});
1218 _ = try self.addZIRInst(&fn_type_scope.base, fn_src, zir.Inst.Return, .{ .operand = fn_type_inst }, .{});
1218 _ = try self.addZIRUnOp(&fn_type_scope.base, fn_src, .@"return", fn_type_inst);
12191219
12201220 // We need the memory for the Type to go into the arena for the Decl
12211221 var decl_arena = std.heap.ArenaAllocator.init(self.gpa);
......@@ -1256,7 +1256,15 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
12561256 const name_token = param.name_token.?;
12571257 const src = tree.token_locs[name_token].start;
12581258 const param_name = tree.tokenSlice(name_token);
1259 const arg = try newZIRInst(&gen_scope_arena.allocator, src, zir.Inst.Arg, .{}, .{});
1259 const arg = try gen_scope_arena.allocator.create(zir.Inst.NoOp);
1260 arg.* = .{
1261 .base = .{
1262 .tag = .arg,
1263 .src = src,
1264 },
1265 .positionals = .{},
1266 .kw_args = .{},
1267 };
12601268 gen_scope.instructions.items[i] = &arg.base;
12611269 const sub_scope = try gen_scope_arena.allocator.create(Scope.LocalVar);
12621270 sub_scope.* = .{
......@@ -1276,7 +1284,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
12761284 !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn()))
12771285 {
12781286 const src = tree.token_locs[body_block.rbrace].start;
1279 _ = try self.addZIRInst(&gen_scope.base, src, zir.Inst.ReturnVoid, .{}, .{});
1287 _ = try self.addZIRNoOp(&gen_scope.base, src, .returnvoid);
12801288 }
12811289
12821290 const fn_zir = try gen_scope_arena.allocator.create(Fn.ZIR);
......@@ -2067,14 +2075,17 @@ fn addCall(
20672075 return &inst.base;
20682076}
20692077
2070fn newZIRInst(
2071 gpa: *Allocator,
2078pub fn addZIRInstSpecial(
2079 self: *Module,
2080 scope: *Scope,
20722081 src: usize,
20732082 comptime T: type,
20742083 positionals: std.meta.fieldInfo(T, "positionals").field_type,
20752084 kw_args: std.meta.fieldInfo(T, "kw_args").field_type,
20762085) !*T {
2077 const inst = try gpa.create(T);
2086 const gen_zir = scope.getGenZIR();
2087 try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1);
2088 const inst = try gen_zir.arena.create(T);
20782089 inst.* = .{
20792090 .base = .{
20802091 .tag = T.base_tag,
......@@ -2083,22 +2094,79 @@ fn newZIRInst(
20832094 .positionals = positionals,
20842095 .kw_args = kw_args,
20852096 };
2097 gen_zir.instructions.appendAssumeCapacity(&inst.base);
20862098 return inst;
20872099}
20882100
2089pub fn addZIRInstSpecial(
2101pub fn addZIRNoOp(
20902102 self: *Module,
20912103 scope: *Scope,
20922104 src: usize,
2093 comptime T: type,
2094 positionals: std.meta.fieldInfo(T, "positionals").field_type,
2095 kw_args: std.meta.fieldInfo(T, "kw_args").field_type,
2096) !*T {
2105 tag: zir.Inst.Tag,
2106) !*zir.Inst {
20972107 const gen_zir = scope.getGenZIR();
20982108 try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1);
2099 const inst = try newZIRInst(gen_zir.arena, src, T, positionals, kw_args);
2109 const inst = try gen_zir.arena.create(zir.Inst.NoOp);
2110 inst.* = .{
2111 .base = .{
2112 .tag = tag,
2113 .src = src,
2114 },
2115 .positionals = .{},
2116 .kw_args = .{},
2117 };
21002118 gen_zir.instructions.appendAssumeCapacity(&inst.base);
2101 return inst;
2119 return &inst.base;
2120}
2121
2122pub fn addZIRUnOp(
2123 self: *Module,
2124 scope: *Scope,
2125 src: usize,
2126 tag: zir.Inst.Tag,
2127 operand: *zir.Inst,
2128) !*zir.Inst {
2129 const gen_zir = scope.getGenZIR();
2130 try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1);
2131 const inst = try gen_zir.arena.create(zir.Inst.UnOp);
2132 inst.* = .{
2133 .base = .{
2134 .tag = tag,
2135 .src = src,
2136 },
2137 .positionals = .{
2138 .operand = operand,
2139 },
2140 .kw_args = .{},
2141 };
2142 gen_zir.instructions.appendAssumeCapacity(&inst.base);
2143 return &inst.base;
2144}
2145
2146pub fn addZIRBinOp(
2147 self: *Module,
2148 scope: *Scope,
2149 src: usize,
2150 tag: zir.Inst.Tag,
2151 lhs: *zir.Inst,
2152 rhs: *zir.Inst,
2153) !*zir.Inst {
2154 const gen_zir = scope.getGenZIR();
2155 try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1);
2156 const inst = try gen_zir.arena.create(zir.Inst.BinOp);
2157 inst.* = .{
2158 .base = .{
2159 .tag = tag,
2160 .src = src,
2161 },
2162 .positionals = .{
2163 .lhs = lhs,
2164 .rhs = rhs,
2165 },
2166 .kw_args = .{},
2167 };
2168 gen_zir.instructions.appendAssumeCapacity(&inst.base);
2169 return &inst.base;
21022170}
21032171
21042172pub fn addZIRInst(
......@@ -2252,46 +2320,51 @@ fn analyzeInstConst(self: *Module, scope: *Scope, const_inst: *zir.Inst.Const) I
22522320
22532321fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Inst {
22542322 switch (old_inst.tag) {
2255 .arg => return self.analyzeInstArg(scope, old_inst.cast(zir.Inst.Arg).?),
2256 .block => return self.analyzeInstBlock(scope, old_inst.cast(zir.Inst.Block).?),
2257 .@"break" => return self.analyzeInstBreak(scope, old_inst.cast(zir.Inst.Break).?),
2258 .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.cast(zir.Inst.Breakpoint).?),
2259 .breakvoid => return self.analyzeInstBreakVoid(scope, old_inst.cast(zir.Inst.BreakVoid).?),
2260 .call => return self.analyzeInstCall(scope, old_inst.cast(zir.Inst.Call).?),
2261 .compileerror => return self.analyzeInstCompileError(scope, old_inst.cast(zir.Inst.CompileError).?),
2262 .@"const" => return self.analyzeInstConst(scope, old_inst.cast(zir.Inst.Const).?),
2263 .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?),
2264 .declref_str => return self.analyzeInstDeclRefStr(scope, old_inst.cast(zir.Inst.DeclRefStr).?),
2265 .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?),
2266 .declval_in_module => return self.analyzeInstDeclValInModule(scope, old_inst.cast(zir.Inst.DeclValInModule).?),
2267 .str => return self.analyzeInstStr(scope, old_inst.cast(zir.Inst.Str).?),
2323 .arg => return self.analyzeInstArg(scope, old_inst.castTag(.arg).?),
2324 .block => return self.analyzeInstBlock(scope, old_inst.castTag(.block).?),
2325 .@"break" => return self.analyzeInstBreak(scope, old_inst.castTag(.@"break").?),
2326 .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.castTag(.breakpoint).?),
2327 .breakvoid => return self.analyzeInstBreakVoid(scope, old_inst.castTag(.breakvoid).?),
2328 .call => return self.analyzeInstCall(scope, old_inst.castTag(.call).?),
2329 .compileerror => return self.analyzeInstCompileError(scope, old_inst.castTag(.compileerror).?),
2330 .@"const" => return self.analyzeInstConst(scope, old_inst.castTag(.@"const").?),
2331 .declref => return self.analyzeInstDeclRef(scope, old_inst.castTag(.declref).?),
2332 .declref_str => return self.analyzeInstDeclRefStr(scope, old_inst.castTag(.declref_str).?),
2333 .declval => return self.analyzeInstDeclVal(scope, old_inst.castTag(.declval).?),
2334 .declval_in_module => return self.analyzeInstDeclValInModule(scope, old_inst.castTag(.declval_in_module).?),
2335 .str => return self.analyzeInstStr(scope, old_inst.castTag(.str).?),
22682336 .int => {
2269 const big_int = old_inst.cast(zir.Inst.Int).?.positionals.int;
2337 const big_int = old_inst.castTag(.int).?.positionals.int;
22702338 return self.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int);
22712339 },
2272 .inttype => return self.analyzeInstIntType(scope, old_inst.cast(zir.Inst.IntType).?),
2273 .ptrtoint => return self.analyzeInstPtrToInt(scope, old_inst.cast(zir.Inst.PtrToInt).?),
2274 .fieldptr => return self.analyzeInstFieldPtr(scope, old_inst.cast(zir.Inst.FieldPtr).?),
2275 .deref => return self.analyzeInstDeref(scope, old_inst.cast(zir.Inst.Deref).?),
2276 .as => return self.analyzeInstAs(scope, old_inst.cast(zir.Inst.As).?),
2277 .@"asm" => return self.analyzeInstAsm(scope, old_inst.cast(zir.Inst.Asm).?),
2278 .@"unreachable" => return self.analyzeInstUnreachable(scope, old_inst.cast(zir.Inst.Unreachable).?),
2279 .@"return" => return self.analyzeInstRet(scope, old_inst.cast(zir.Inst.Return).?),
2280 .returnvoid => return self.analyzeInstRetVoid(scope, old_inst.cast(zir.Inst.ReturnVoid).?),
2281 .@"fn" => return self.analyzeInstFn(scope, old_inst.cast(zir.Inst.Fn).?),
2282 .@"export" => return self.analyzeInstExport(scope, old_inst.cast(zir.Inst.Export).?),
2283 .primitive => return self.analyzeInstPrimitive(scope, old_inst.cast(zir.Inst.Primitive).?),
2284 .fntype => return self.analyzeInstFnType(scope, old_inst.cast(zir.Inst.FnType).?),
2285 .intcast => return self.analyzeInstIntCast(scope, old_inst.cast(zir.Inst.IntCast).?),
2286 .bitcast => return self.analyzeInstBitCast(scope, old_inst.cast(zir.Inst.BitCast).?),
2287 .elemptr => return self.analyzeInstElemPtr(scope, old_inst.cast(zir.Inst.ElemPtr).?),
2288 .add => return self.analyzeInstAdd(scope, old_inst.cast(zir.Inst.Add).?),
2289 .sub => return self.analyzeInstSub(scope, old_inst.cast(zir.Inst.Sub).?),
2290 .cmp => return self.analyzeInstCmp(scope, old_inst.cast(zir.Inst.Cmp).?),
2291 .condbr => return self.analyzeInstCondBr(scope, old_inst.cast(zir.Inst.CondBr).?),
2292 .isnull => return self.analyzeInstIsNull(scope, old_inst.cast(zir.Inst.IsNull).?),
2293 .isnonnull => return self.analyzeInstIsNonNull(scope, old_inst.cast(zir.Inst.IsNonNull).?),
2294 .boolnot => return self.analyzeInstBoolNot(scope, old_inst.cast(zir.Inst.BoolNot).?),
2340 .inttype => return self.analyzeInstIntType(scope, old_inst.castTag(.inttype).?),
2341 .ptrtoint => return self.analyzeInstPtrToInt(scope, old_inst.castTag(.ptrtoint).?),
2342 .fieldptr => return self.analyzeInstFieldPtr(scope, old_inst.castTag(.fieldptr).?),
2343 .deref => return self.analyzeInstDeref(scope, old_inst.castTag(.deref).?),
2344 .as => return self.analyzeInstAs(scope, old_inst.castTag(.as).?),
2345 .@"asm" => return self.analyzeInstAsm(scope, old_inst.castTag(.@"asm").?),
2346 .@"unreachable" => return self.analyzeInstUnreachable(scope, old_inst.castTag(.@"unreachable").?),
2347 .@"return" => return self.analyzeInstRet(scope, old_inst.castTag(.@"return").?),
2348 .returnvoid => return self.analyzeInstRetVoid(scope, old_inst.castTag(.returnvoid).?),
2349 .@"fn" => return self.analyzeInstFn(scope, old_inst.castTag(.@"fn").?),
2350 .@"export" => return self.analyzeInstExport(scope, old_inst.castTag(.@"export").?),
2351 .primitive => return self.analyzeInstPrimitive(scope, old_inst.castTag(.primitive).?),
2352 .fntype => return self.analyzeInstFnType(scope, old_inst.castTag(.fntype).?),
2353 .intcast => return self.analyzeInstIntCast(scope, old_inst.castTag(.intcast).?),
2354 .bitcast => return self.analyzeInstBitCast(scope, old_inst.castTag(.bitcast).?),
2355 .elemptr => return self.analyzeInstElemPtr(scope, old_inst.castTag(.elemptr).?),
2356 .add => return self.analyzeInstAdd(scope, old_inst.castTag(.add).?),
2357 .sub => return self.analyzeInstSub(scope, old_inst.castTag(.sub).?),
2358 .cmp_lt => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_lt).?, .lt),
2359 .cmp_lte => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_lte).?, .lte),
2360 .cmp_eq => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_eq).?, .eq),
2361 .cmp_gte => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_gte).?, .gte),
2362 .cmp_gt => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_gt).?, .gt),
2363 .cmp_neq => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_neq).?, .neq),
2364 .condbr => return self.analyzeInstCondBr(scope, old_inst.castTag(.condbr).?),
2365 .isnull => return self.analyzeInstIsNonNull(scope, old_inst.castTag(.isnull).?, true),
2366 .isnonnull => return self.analyzeInstIsNonNull(scope, old_inst.castTag(.isnonnull).?, false),
2367 .boolnot => return self.analyzeInstBoolNot(scope, old_inst.castTag(.boolnot).?),
22952368 }
22962369}
22972370
......@@ -2372,7 +2445,7 @@ fn analyzeInstCompileError(self: *Module, scope: *Scope, inst: *zir.Inst.Compile
23722445 return self.fail(scope, inst.base.src, "{}", .{inst.positionals.msg});
23732446}
23742447
2375fn analyzeInstArg(self: *Module, scope: *Scope, inst: *zir.Inst.Arg) InnerError!*Inst {
2448fn analyzeInstArg(self: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
23762449 const b = try self.requireRuntimeBlock(scope, inst.base.src);
23772450 const fn_ty = b.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
23782451 const param_index = b.instructions.items.len;
......@@ -2435,7 +2508,7 @@ fn analyzeInstBlock(self: *Module, scope: *Scope, inst: *zir.Inst.Block) InnerEr
24352508 return &block_inst.base;
24362509}
24372510
2438fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.Breakpoint) InnerError!*Inst {
2511fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
24392512 const b = try self.requireRuntimeBlock(scope, inst.base.src);
24402513 return self.addNoOp(b, inst.base.src, Type.initTag(.void), .breakpoint);
24412514}
......@@ -2791,11 +2864,11 @@ fn analyzeInstElemPtr(self: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inn
27912864 return self.fail(scope, inst.base.src, "TODO implement more analyze elemptr", .{});
27922865}
27932866
2794fn analyzeInstSub(self: *Module, scope: *Scope, inst: *zir.Inst.Sub) InnerError!*Inst {
2867fn analyzeInstSub(self: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
27952868 return self.fail(scope, inst.base.src, "TODO implement analysis of sub", .{});
27962869}
27972870
2798fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError!*Inst {
2871fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
27992872 const tracy = trace(@src());
28002873 defer tracy.end();
28012874
......@@ -2848,9 +2921,9 @@ fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError!
28482921 return self.fail(scope, inst.base.src, "TODO analyze add for {} + {}", .{ lhs.ty.zigTypeTag(), rhs.ty.zigTypeTag() });
28492922}
28502923
2851fn analyzeInstDeref(self: *Module, scope: *Scope, deref: *zir.Inst.Deref) InnerError!*Inst {
2852 const ptr = try self.resolveInst(scope, deref.positionals.ptr);
2853 return self.analyzeDeref(scope, deref.base.src, ptr, deref.positionals.ptr.src);
2924fn analyzeInstDeref(self: *Module, scope: *Scope, deref: *zir.Inst.UnOp) InnerError!*Inst {
2925 const ptr = try self.resolveInst(scope, deref.positionals.operand);
2926 return self.analyzeDeref(scope, deref.base.src, ptr, deref.positionals.operand.src);
28542927}
28552928
28562929fn analyzeDeref(self: *Module, scope: *Scope, src: usize, ptr: *Inst, ptr_src: usize) InnerError!*Inst {
......@@ -2907,10 +2980,14 @@ fn analyzeInstAsm(self: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerEr
29072980 return &inst.base;
29082981}
29092982
2910fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError!*Inst {
2983fn analyzeInstCmp(
2984 self: *Module,
2985 scope: *Scope,
2986 inst: *zir.Inst.BinOp,
2987 op: std.math.CompareOperator,
2988) InnerError!*Inst {
29112989 const lhs = try self.resolveInst(scope, inst.positionals.lhs);
29122990 const rhs = try self.resolveInst(scope, inst.positionals.rhs);
2913 const op = inst.positionals.op;
29142991
29152992 const is_equality_cmp = switch (op) {
29162993 .eq, .neq => true,
......@@ -2964,7 +3041,7 @@ fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError!
29643041 return self.fail(scope, inst.base.src, "TODO implement more cmp analysis", .{});
29653042}
29663043
2967fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.BoolNot) InnerError!*Inst {
3044fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
29683045 const uncasted_operand = try self.resolveInst(scope, inst.positionals.operand);
29693046 const bool_type = Type.initTag(.bool);
29703047 const operand = try self.coerce(scope, bool_type, uncasted_operand);
......@@ -2975,14 +3052,9 @@ fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.BoolNot) Inn
29753052 return self.addUnOp(b, inst.base.src, bool_type, .not, operand);
29763053}
29773054
2978fn analyzeInstIsNull(self: *Module, scope: *Scope, inst: *zir.Inst.IsNull) InnerError!*Inst {
2979 const operand = try self.resolveInst(scope, inst.positionals.operand);
2980 return self.analyzeIsNull(scope, inst.base.src, operand, true);
2981}
2982
2983fn analyzeInstIsNonNull(self: *Module, scope: *Scope, inst: *zir.Inst.IsNonNull) InnerError!*Inst {
3055fn analyzeInstIsNonNull(self: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst {
29843056 const operand = try self.resolveInst(scope, inst.positionals.operand);
2985 return self.analyzeIsNull(scope, inst.base.src, operand, false);
3057 return self.analyzeIsNull(scope, inst.base.src, operand, invert_logic);
29863058}
29873059
29883060fn analyzeInstCondBr(self: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst {
......@@ -3031,7 +3103,7 @@ fn wantSafety(self: *Module, scope: *Scope) bool {
30313103 };
30323104}
30333105
3034fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.Unreachable) InnerError!*Inst {
3106fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.NoOp) InnerError!*Inst {
30353107 const b = try self.requireRuntimeBlock(scope, unreach.base.src);
30363108 if (self.wantSafety(scope)) {
30373109 // TODO Once we have a panic function to call, call it here instead of this.
......@@ -3040,13 +3112,13 @@ fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.Unrea
30403112 return self.addNoOp(b, unreach.base.src, Type.initTag(.noreturn), .unreach);
30413113}
30423114
3043fn analyzeInstRet(self: *Module, scope: *Scope, inst: *zir.Inst.Return) InnerError!*Inst {
3115fn analyzeInstRet(self: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
30443116 const operand = try self.resolveInst(scope, inst.positionals.operand);
30453117 const b = try self.requireRuntimeBlock(scope, inst.base.src);
30463118 return self.addUnOp(b, inst.base.src, Type.initTag(.noreturn), .ret, operand);
30473119}
30483120
3049fn analyzeInstRetVoid(self: *Module, scope: *Scope, inst: *zir.Inst.ReturnVoid) InnerError!*Inst {
3121fn analyzeInstRetVoid(self: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
30503122 const b = try self.requireRuntimeBlock(scope, inst.base.src);
30513123 return self.addNoOp(b, inst.base.src, Type.initTag(.noreturn), .retvoid);
30523124}
src-self-hosted/astgen.zig+18-40
......@@ -16,6 +16,15 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
1616 switch (node.tag) {
1717 .VarDecl => unreachable, // Handled in `blockExpr`.
1818
19 .Add => return simpleInfixOp(mod, scope, node.castTag(.Add).?, .add),
20 .Sub => return simpleInfixOp(mod, scope, node.castTag(.Sub).?, .sub),
21 .BangEqual => return simpleInfixOp(mod, scope, node.castTag(.BangEqual).?, .cmp_neq),
22 .EqualEqual => return simpleInfixOp(mod, scope, node.castTag(.EqualEqual).?, .cmp_eq),
23 .GreaterThan => return simpleInfixOp(mod, scope, node.castTag(.GreaterThan).?, .cmp_gt),
24 .GreaterOrEqual => return simpleInfixOp(mod, scope, node.castTag(.GreaterOrEqual).?, .cmp_gte),
25 .LessThan => return simpleInfixOp(mod, scope, node.castTag(.LessThan).?, .cmp_lt),
26 .LessOrEqual => return simpleInfixOp(mod, scope, node.castTag(.LessOrEqual).?, .cmp_lte),
27
1928 .Identifier => return identifier(mod, scope, node.castTag(.Identifier).?),
2029 .Asm => return assembly(mod, scope, node.castTag(.Asm).?),
2130 .StringLiteral => return stringLiteral(mod, scope, node.castTag(.StringLiteral).?),
......@@ -26,13 +35,6 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
2635 .ControlFlowExpression => return controlFlowExpr(mod, scope, node.castTag(.ControlFlowExpression).?),
2736 .If => return ifExpr(mod, scope, node.castTag(.If).?),
2837 .Assign => return assign(mod, scope, node.castTag(.Assign).?),
29 .Add => return add(mod, scope, node.castTag(.Add).?),
30 .BangEqual => return cmp(mod, scope, node.castTag(.BangEqual).?, .neq),
31 .EqualEqual => return cmp(mod, scope, node.castTag(.EqualEqual).?, .eq),
32 .GreaterThan => return cmp(mod, scope, node.castTag(.GreaterThan).?, .gt),
33 .GreaterOrEqual => return cmp(mod, scope, node.castTag(.GreaterOrEqual).?, .gte),
34 .LessThan => return cmp(mod, scope, node.castTag(.LessThan).?, .lt),
35 .LessOrEqual => return cmp(mod, scope, node.castTag(.LessOrEqual).?, .lte),
3638 .Period => return field(mod, scope, node.castTag(.Period).?),
3739 .Deref => return deref(mod, scope, node.castTag(.Deref).?),
3840 .BoolNot => return boolNot(mod, scope, node.castTag(.BoolNot).?),
......@@ -97,14 +99,6 @@ fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!Scop
9799 },
98100 .Keyword_var => {
99101 return mod.failNode(scope, &node.base, "TODO implement local vars", .{});
100 //const src = tree.token_locs[node.name_token].start;
101 //const alloc = mod.addZIRInst(scope, src, zir.Inst.Alloc, .{}, .{});
102 //if (node.getTrailer("type_node")) |type_node| {
103 // const type_inst = try expr(mod, scope, type_node);
104 // return mod.failNode(scope, type_node, "TODO implement typed var locals", .{});
105 //} else {
106 // return mod.failTok(scope, node.mut_token, "TODO implement mutable type-inferred locals", .{});
107 //}
108102 },
109103 else => unreachable,
110104 }
......@@ -114,7 +108,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr
114108 const operand = try expr(mod, scope, node.rhs);
115109 const tree = scope.tree();
116110 const src = tree.token_locs[node.op_token].start;
117 return mod.addZIRInst(scope, src, zir.Inst.BoolNot, .{ .operand = operand }, .{});
111 return mod.addZIRUnOp(scope, src, .boolnot, operand);
118112}
119113
120114fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {
......@@ -169,33 +163,21 @@ fn field(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp) InnerError!
169163 const field_name = try identifierStringInst(mod, scope, node.rhs.castTag(.Identifier).?);
170164
171165 const pointer = try mod.addZIRInst(scope, src, zir.Inst.FieldPtr, .{ .object_ptr = lhs, .field_name = field_name }, .{});
172 return mod.addZIRInst(scope, src, zir.Inst.Deref, .{ .ptr = pointer }, .{});
166 return mod.addZIRUnOp(scope, src, .deref, pointer);
173167}
174168
175169fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
176170 const tree = scope.tree();
177171 const src = tree.token_locs[node.rtoken].start;
178
179172 const lhs = try expr(mod, scope, node.lhs);
180
181 return mod.addZIRInst(scope, src, zir.Inst.Deref, .{ .ptr = lhs }, .{});
182}
183
184fn add(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {
185 const lhs = try expr(mod, scope, infix_node.lhs);
186 const rhs = try expr(mod, scope, infix_node.rhs);
187
188 const tree = scope.tree();
189 const src = tree.token_locs[infix_node.op_token].start;
190
191 return mod.addZIRInst(scope, src, zir.Inst.Add, .{ .lhs = lhs, .rhs = rhs }, .{});
173 return mod.addZIRUnOp(scope, src, .deref, lhs);
192174}
193175
194fn cmp(
176fn simpleInfixOp(
195177 mod: *Module,
196178 scope: *Scope,
197179 infix_node: *ast.Node.SimpleInfixOp,
198 op: std.math.CompareOperator,
180 op_inst_tag: zir.Inst.Tag,
199181) InnerError!*zir.Inst {
200182 const lhs = try expr(mod, scope, infix_node.lhs);
201183 const rhs = try expr(mod, scope, infix_node.rhs);
......@@ -203,11 +185,7 @@ fn cmp(
203185 const tree = scope.tree();
204186 const src = tree.token_locs[infix_node.op_token].start;
205187
206 return mod.addZIRInst(scope, src, zir.Inst.Cmp, .{
207 .lhs = lhs,
208 .op = op,
209 .rhs = rhs,
210 }, .{});
188 return mod.addZIRBinOp(scope, src, op_inst_tag, lhs, rhs);
211189}
212190
213191fn ifExpr(mod: *Module, scope: *Scope, if_node: *ast.Node.If) InnerError!*zir.Inst {
......@@ -306,9 +284,9 @@ fn controlFlowExpr(
306284 const src = tree.token_locs[cfe.ltoken].start;
307285 if (cfe.rhs) |rhs_node| {
308286 const operand = try expr(mod, scope, rhs_node);
309 return mod.addZIRInst(scope, src, zir.Inst.Return, .{ .operand = operand }, .{});
287 return mod.addZIRUnOp(scope, src, .@"return", operand);
310288 } else {
311 return mod.addZIRInst(scope, src, zir.Inst.ReturnVoid, .{}, .{});
289 return mod.addZIRNoOp(scope, src, .returnvoid);
312290 }
313291}
314292
......@@ -519,7 +497,7 @@ fn callExpr(mod: *Module, scope: *Scope, node: *ast.Node.Call) InnerError!*zir.I
519497fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.Unreachable) InnerError!*zir.Inst {
520498 const tree = scope.tree();
521499 const src = tree.token_locs[unreach_node.token].start;
522 return mod.addZIRInst(scope, src, zir.Inst.Unreachable, .{}, .{});
500 return mod.addZIRNoOp(scope, src, .@"unreachable");
523501}
524502
525503fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {
src-self-hosted/zir.zig+137-214
......@@ -79,11 +79,69 @@ pub const Inst = struct {
7979 elemptr,
8080 add,
8181 sub,
82 cmp,
82 cmp_lt,
83 cmp_lte,
84 cmp_eq,
85 cmp_gte,
86 cmp_gt,
87 cmp_neq,
8388 condbr,
8489 isnull,
8590 isnonnull,
8691
92 pub fn Type(tag: Tag) type {
93 return switch (tag) {
94 .arg,
95 .breakpoint,
96 .@"unreachable",
97 .returnvoid,
98 => NoOp,
99
100 .boolnot,
101 .deref,
102 .@"return",
103 .isnull,
104 .isnonnull,
105 => UnOp,
106
107 .add,
108 .sub,
109 .cmp_lt,
110 .cmp_lte,
111 .cmp_eq,
112 .cmp_gte,
113 .cmp_gt,
114 .cmp_neq,
115 => BinOp,
116
117 .block => Block,
118 .@"break" => Break,
119 .breakvoid => BreakVoid,
120 .call => Call,
121 .declref => DeclRef,
122 .declref_str => DeclRefStr,
123 .declval => DeclVal,
124 .declval_in_module => DeclValInModule,
125 .compileerror => CompileError,
126 .@"const" => Const,
127 .str => Str,
128 .int => Int,
129 .inttype => IntType,
130 .ptrtoint => PtrToInt,
131 .fieldptr => FieldPtr,
132 .as => As,
133 .@"asm" => Asm,
134 .@"fn" => Fn,
135 .@"export" => Export,
136 .primitive => Primitive,
137 .fntype => FnType,
138 .intcast => IntCast,
139 .bitcast => BitCast,
140 .elemptr => ElemPtr,
141 .condbr => CondBr,
142 };
143 }
144
87145 /// Returns whether the instruction is one of the control flow "noreturn" types.
88146 /// Function calls do not count.
89147 pub fn isNoReturn(tag: Tag) bool {
......@@ -114,7 +172,12 @@ pub const Inst = struct {
114172 .elemptr,
115173 .add,
116174 .sub,
117 .cmp,
175 .cmp_lt,
176 .cmp_lte,
177 .cmp_eq,
178 .cmp_gte,
179 .cmp_gt,
180 .cmp_neq,
118181 .isnull,
119182 .isnonnull,
120183 .boolnot,
......@@ -132,63 +195,56 @@ pub const Inst = struct {
132195 }
133196 };
134197
135 pub fn TagToType(tag: Tag) type {
136 return switch (tag) {
137 .arg => Arg,
138 .block => Block,
139 .@"break" => Break,
140 .breakpoint => Breakpoint,
141 .breakvoid => BreakVoid,
142 .call => Call,
143 .declref => DeclRef,
144 .declref_str => DeclRefStr,
145 .declval => DeclVal,
146 .declval_in_module => DeclValInModule,
147 .compileerror => CompileError,
148 .@"const" => Const,
149 .boolnot => BoolNot,
150 .str => Str,
151 .int => Int,
152 .inttype => IntType,
153 .ptrtoint => PtrToInt,
154 .fieldptr => FieldPtr,
155 .deref => Deref,
156 .as => As,
157 .@"asm" => Asm,
158 .@"unreachable" => Unreachable,
159 .@"return" => Return,
160 .returnvoid => ReturnVoid,
161 .@"fn" => Fn,
162 .@"export" => Export,
163 .primitive => Primitive,
164 .fntype => FnType,
165 .intcast => IntCast,
166 .bitcast => BitCast,
167 .elemptr => ElemPtr,
168 .add => Add,
169 .sub => Sub,
170 .cmp => Cmp,
171 .condbr => CondBr,
172 .isnull => IsNull,
173 .isnonnull => IsNonNull,
174 };
175 }
176
198 /// Prefer `castTag` to this.
177199 pub fn cast(base: *Inst, comptime T: type) ?*T {
178 if (base.tag != T.base_tag)
179 return null;
200 if (@hasField(T, "base_tag")) {
201 return base.castTag(T.base_tag);
202 }
203 inline for (@typeInfo(Tag).Enum.fields) |field| {
204 const tag = @intToEnum(Tag, field.value);
205 if (base.tag == tag) {
206 if (T == tag.Type()) {
207 return @fieldParentPtr(T, "base", base);
208 }
209 return null;
210 }
211 }
212 unreachable;
213 }
180214
181 return @fieldParentPtr(T, "base", base);
215 pub fn castTag(base: *Inst, comptime tag: Tag) ?*tag.Type() {
216 if (base.tag == tag) {
217 return @fieldParentPtr(tag.Type(), "base", base);
218 }
219 return null;
182220 }
183221
184 pub const Arg = struct {
185 pub const base_tag = Tag.arg;
222 pub const NoOp = struct {
186223 base: Inst,
187224
188225 positionals: struct {},
189226 kw_args: struct {},
190227 };
191228
229 pub const UnOp = struct {
230 base: Inst,
231
232 positionals: struct {
233 operand: *Inst,
234 },
235 kw_args: struct {},
236 };
237
238 pub const BinOp = struct {
239 base: Inst,
240
241 positionals: struct {
242 lhs: *Inst,
243 rhs: *Inst,
244 },
245 kw_args: struct {},
246 };
247
192248 pub const Block = struct {
193249 pub const base_tag = Tag.block;
194250 base: Inst,
......@@ -210,14 +266,6 @@ pub const Inst = struct {
210266 kw_args: struct {},
211267 };
212268
213 pub const Breakpoint = struct {
214 pub const base_tag = Tag.breakpoint;
215 base: Inst,
216
217 positionals: struct {},
218 kw_args: struct {},
219 };
220
221269 pub const BreakVoid = struct {
222270 pub const base_tag = Tag.breakvoid;
223271 base: Inst,
......@@ -301,16 +349,6 @@ pub const Inst = struct {
301349 kw_args: struct {},
302350 };
303351
304 pub const BoolNot = struct {
305 pub const base_tag = Tag.boolnot;
306 base: Inst,
307
308 positionals: struct {
309 operand: *Inst,
310 },
311 kw_args: struct {},
312 };
313
314352 pub const Str = struct {
315353 pub const base_tag = Tag.str;
316354 base: Inst,
......@@ -353,16 +391,6 @@ pub const Inst = struct {
353391 kw_args: struct {},
354392 };
355393
356 pub const Deref = struct {
357 pub const base_tag = Tag.deref;
358 base: Inst,
359
360 positionals: struct {
361 ptr: *Inst,
362 },
363 kw_args: struct {},
364 };
365
366394 pub const As = struct {
367395 pub const base_tag = Tag.as;
368396 pub const builtin_name = "@as";
......@@ -392,32 +420,6 @@ pub const Inst = struct {
392420 },
393421 };
394422
395 pub const Unreachable = struct {
396 pub const base_tag = Tag.@"unreachable";
397 base: Inst,
398
399 positionals: struct {},
400 kw_args: struct {},
401 };
402
403 pub const Return = struct {
404 pub const base_tag = Tag.@"return";
405 base: Inst,
406
407 positionals: struct {
408 operand: *Inst,
409 },
410 kw_args: struct {},
411 };
412
413 pub const ReturnVoid = struct {
414 pub const base_tag = Tag.returnvoid;
415 base: Inst,
416
417 positionals: struct {},
418 kw_args: struct {},
419 };
420
421423 pub const Fn = struct {
422424 pub const base_tag = Tag.@"fn";
423425 base: Inst,
......@@ -587,42 +589,6 @@ pub const Inst = struct {
587589 kw_args: struct {},
588590 };
589591
590 pub const Add = struct {
591 pub const base_tag = Tag.add;
592 base: Inst,
593
594 positionals: struct {
595 lhs: *Inst,
596 rhs: *Inst,
597 },
598 kw_args: struct {},
599 };
600
601 pub const Sub = struct {
602 pub const base_tag = Tag.sub;
603 base: Inst,
604
605 positionals: struct {
606 lhs: *Inst,
607 rhs: *Inst,
608 },
609 kw_args: struct {},
610 };
611
612 /// TODO get rid of the op positional arg and make that data part of
613 /// the base Inst tag.
614 pub const Cmp = struct {
615 pub const base_tag = Tag.cmp;
616 base: Inst,
617
618 positionals: struct {
619 lhs: *Inst,
620 op: std.math.CompareOperator,
621 rhs: *Inst,
622 },
623 kw_args: struct {},
624 };
625
626592 pub const CondBr = struct {
627593 pub const base_tag = Tag.condbr;
628594 base: Inst,
......@@ -634,26 +600,6 @@ pub const Inst = struct {
634600 },
635601 kw_args: struct {},
636602 };
637
638 pub const IsNull = struct {
639 pub const base_tag = Tag.isnull;
640 base: Inst,
641
642 positionals: struct {
643 operand: *Inst,
644 },
645 kw_args: struct {},
646 };
647
648 pub const IsNonNull = struct {
649 pub const base_tag = Tag.isnonnull;
650 base: Inst,
651
652 positionals: struct {
653 operand: *Inst,
654 },
655 kw_args: struct {},
656 };
657603};
658604
659605pub const ErrorMsg = struct {
......@@ -775,7 +721,7 @@ const Writer = struct {
775721 comptime inst_tag: Inst.Tag,
776722 base: *Inst,
777723 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {
778 const SpecificInst = Inst.TagToType(inst_tag);
724 const SpecificInst = inst_tag.Type();
779725 const inst = @fieldParentPtr(SpecificInst, "base", base);
780726 const Positionals = @TypeOf(inst.positionals);
781727 try stream.writeAll("= " ++ @tagName(inst_tag) ++ "(");
......@@ -1102,7 +1048,7 @@ const Parser = struct {
11021048 inline for (@typeInfo(Inst.Tag).Enum.fields) |field| {
11031049 if (mem.eql(u8, field.name, fn_name)) {
11041050 const tag = @field(Inst.Tag, field.name);
1105 return parseInstructionGeneric(self, field.name, Inst.TagToType(tag), body_ctx, name, contents_start);
1051 return parseInstructionGeneric(self, field.name, tag.Type(), tag, body_ctx, name, contents_start);
11061052 }
11071053 }
11081054 return self.fail("unknown instruction '{}'", .{fn_name});
......@@ -1112,6 +1058,7 @@ const Parser = struct {
11121058 self: *Parser,
11131059 comptime fn_name: []const u8,
11141060 comptime InstType: type,
1061 tag: Inst.Tag,
11151062 body_ctx: ?*Body,
11161063 inst_name: []const u8,
11171064 contents_start: usize,
......@@ -1119,7 +1066,7 @@ const Parser = struct {
11191066 const inst_specific = try self.arena.allocator.create(InstType);
11201067 inst_specific.base = .{
11211068 .src = self.i,
1122 .tag = InstType.base_tag,
1069 .tag = tag,
11231070 };
11241071
11251072 if (InstType == Inst.Block) {
......@@ -1615,12 +1562,12 @@ const EmitZIR = struct {
16151562 }
16161563 }
16171564
1618 fn emitNoOp(self: *EmitZIR, src: usize, comptime T: type) Allocator.Error!*Inst {
1619 const new_inst = try self.arena.allocator.create(T);
1565 fn emitNoOp(self: *EmitZIR, src: usize, tag: Inst.Tag) Allocator.Error!*Inst {
1566 const new_inst = try self.arena.allocator.create(Inst.NoOp);
16201567 new_inst.* = .{
16211568 .base = .{
16221569 .src = src,
1623 .tag = T.base_tag,
1570 .tag = tag,
16241571 },
16251572 .positionals = .{},
16261573 .kw_args = .{},
......@@ -1628,41 +1575,18 @@ const EmitZIR = struct {
16281575 return &new_inst.base;
16291576 }
16301577
1631 fn emitCmp(
1632 self: *EmitZIR,
1633 src: usize,
1634 new_body: ZirBody,
1635 old_inst: *ir.Inst.BinOp,
1636 op: std.math.CompareOperator,
1637 ) Allocator.Error!*Inst {
1638 const new_inst = try self.arena.allocator.create(Inst.Cmp);
1639 new_inst.* = .{
1640 .base = .{
1641 .src = src,
1642 .tag = Inst.Cmp.base_tag,
1643 },
1644 .positionals = .{
1645 .lhs = try self.resolveInst(new_body, old_inst.lhs),
1646 .rhs = try self.resolveInst(new_body, old_inst.rhs),
1647 .op = op,
1648 },
1649 .kw_args = .{},
1650 };
1651 return &new_inst.base;
1652 }
1653
16541578 fn emitUnOp(
16551579 self: *EmitZIR,
16561580 src: usize,
16571581 new_body: ZirBody,
16581582 old_inst: *ir.Inst.UnOp,
1659 comptime I: type,
1583 tag: Inst.Tag,
16601584 ) Allocator.Error!*Inst {
1661 const new_inst = try self.arena.allocator.create(I);
1585 const new_inst = try self.arena.allocator.create(Inst.UnOp);
16621586 new_inst.* = .{
16631587 .base = .{
16641588 .src = src,
1665 .tag = I.base_tag,
1589 .tag = tag,
16661590 },
16671591 .positionals = .{
16681592 .operand = try self.resolveInst(new_body, old_inst.operand),
......@@ -1677,13 +1601,13 @@ const EmitZIR = struct {
16771601 src: usize,
16781602 new_body: ZirBody,
16791603 old_inst: *ir.Inst.BinOp,
1680 comptime I: type,
1604 tag: Inst.Tag,
16811605 ) Allocator.Error!*Inst {
1682 const new_inst = try self.arena.allocator.create(I);
1606 const new_inst = try self.arena.allocator.create(Inst.BinOp);
16831607 new_inst.* = .{
16841608 .base = .{
16851609 .src = src,
1686 .tag = I.base_tag,
1610 .tag = tag,
16871611 },
16881612 .positionals = .{
16891613 .lhs = try self.resolveInst(new_body, old_inst.lhs),
......@@ -1708,26 +1632,25 @@ const EmitZIR = struct {
17081632 const new_inst = switch (inst.tag) {
17091633 .constant => unreachable, // excluded from function bodies
17101634
1711 .arg => try self.emitNoOp(inst.src, Inst.Arg),
1712 .breakpoint => try self.emitNoOp(inst.src, Inst.Breakpoint),
1713 .unreach => try self.emitNoOp(inst.src, Inst.Unreachable),
1714 .retvoid => try self.emitNoOp(inst.src, Inst.ReturnVoid),
1715
1716 .not => try self.emitUnOp(inst.src, new_body, inst.castTag(.not).?, Inst.BoolNot),
1717 .ret => try self.emitUnOp(inst.src, new_body, inst.castTag(.ret).?, Inst.Return),
1718 .ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, Inst.PtrToInt),
1719 .isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, Inst.IsNull),
1720 .isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, Inst.IsNonNull),
1721
1722 .add => try self.emitBinOp(inst.src, new_body, inst.castTag(.add).?, Inst.Add),
1723 .sub => try self.emitBinOp(inst.src, new_body, inst.castTag(.sub).?, Inst.Sub),
1724
1725 .cmp_lt => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_lt).?, .lt),
1726 .cmp_lte => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_lte).?, .lte),
1727 .cmp_eq => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_eq).?, .eq),
1728 .cmp_gte => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_gte).?, .gte),
1729 .cmp_gt => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_gt).?, .gt),
1730 .cmp_neq => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_neq).?, .neq),
1635 .arg => try self.emitNoOp(inst.src, .arg),
1636 .breakpoint => try self.emitNoOp(inst.src, .breakpoint),
1637 .unreach => try self.emitNoOp(inst.src, .@"unreachable"),
1638 .retvoid => try self.emitNoOp(inst.src, .returnvoid),
1639
1640 .not => try self.emitUnOp(inst.src, new_body, inst.castTag(.not).?, .boolnot),
1641 .ret => try self.emitUnOp(inst.src, new_body, inst.castTag(.ret).?, .@"return"),
1642 .ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, .ptrtoint),
1643 .isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, .isnull),
1644 .isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, .isnonnull),
1645
1646 .add => try self.emitBinOp(inst.src, new_body, inst.castTag(.add).?, .add),
1647 .sub => try self.emitBinOp(inst.src, new_body, inst.castTag(.sub).?, .sub),
1648 .cmp_lt => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_lt).?, .cmp_lt),
1649 .cmp_lte => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_lte).?, .cmp_lte),
1650 .cmp_eq => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_eq).?, .cmp_eq),
1651 .cmp_gte => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_gte).?, .cmp_gte),
1652 .cmp_gt => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_gt).?, .cmp_gt),
1653 .cmp_neq => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_neq).?, .cmp_neq),
17311654
17321655 .bitcast => blk: {
17331656 const old_inst = inst.castTag(.bitcast).?;
test/stage2/zir.zig+1-1
......@@ -56,7 +56,7 @@ pub fn addCases(ctx: *TestContext) !void {
5656 \\ %result = add(%x0, %x1)
5757 \\
5858 \\ %expected = int(69)
59 \\ %ok = cmp(%result, eq, %expected)
59 \\ %ok = cmp_eq(%result, %expected)
6060 \\ %10 = condbr(%ok, {
6161 \\ %11 = returnvoid()
6262 \\ }, {