| author | |
| committer | |
| log | 8ee629aa4c7fb0127c71aec0b2c81353c4291ebb |
| tree | 221c6b97638b189d66e328c300d013292e0227f6 |
| parent | 7a1a92478878f591abbadcd5735f03c817c6eb53 |
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 { | ... | @@ -1215,7 +1215,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { |
| 1215 | .return_type = return_type_inst, | 1215 | .return_type = return_type_inst, |
| 1216 | .param_types = param_types, | 1216 | .param_types = param_types, |
| 1217 | }, .{}); | 1217 | }, .{}); |
| 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); |
| 1219 | 1219 | ||
| 1220 | // We need the memory for the Type to go into the arena for the Decl | 1220 | // We need the memory for the Type to go into the arena for the Decl |
| 1221 | var decl_arena = std.heap.ArenaAllocator.init(self.gpa); | 1221 | var decl_arena = std.heap.ArenaAllocator.init(self.gpa); |
| ... | @@ -1256,7 +1256,15 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { | ... | @@ -1256,7 +1256,15 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { |
| 1256 | const name_token = param.name_token.?; | 1256 | const name_token = param.name_token.?; |
| 1257 | const src = tree.token_locs[name_token].start; | 1257 | const src = tree.token_locs[name_token].start; |
| 1258 | const param_name = tree.tokenSlice(name_token); | 1258 | 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 | }; | ||
| 1260 | gen_scope.instructions.items[i] = &arg.base; | 1268 | gen_scope.instructions.items[i] = &arg.base; |
| 1261 | const sub_scope = try gen_scope_arena.allocator.create(Scope.LocalVar); | 1269 | const sub_scope = try gen_scope_arena.allocator.create(Scope.LocalVar); |
| 1262 | sub_scope.* = .{ | 1270 | sub_scope.* = .{ |
| ... | @@ -1276,7 +1284,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { | ... | @@ -1276,7 +1284,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { |
| 1276 | !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn())) | 1284 | !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn())) |
| 1277 | { | 1285 | { |
| 1278 | const src = tree.token_locs[body_block.rbrace].start; | 1286 | 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); |
| 1280 | } | 1288 | } |
| 1281 | 1289 | ||
| 1282 | const fn_zir = try gen_scope_arena.allocator.create(Fn.ZIR); | 1290 | const fn_zir = try gen_scope_arena.allocator.create(Fn.ZIR); |
| ... | @@ -2067,14 +2075,17 @@ fn addCall( | ... | @@ -2067,14 +2075,17 @@ fn addCall( |
| 2067 | return &inst.base; | 2075 | return &inst.base; |
| 2068 | } | 2076 | } |
| 2069 | 2077 | ||
| 2070 | fn newZIRInst( | 2078 | pub fn addZIRInstSpecial( |
| 2071 | gpa: *Allocator, | 2079 | self: *Module, |
| 2080 | scope: *Scope, | ||
| 2072 | src: usize, | 2081 | src: usize, |
| 2073 | comptime T: type, | 2082 | comptime T: type, |
| 2074 | positionals: std.meta.fieldInfo(T, "positionals").field_type, | 2083 | positionals: std.meta.fieldInfo(T, "positionals").field_type, |
| 2075 | kw_args: std.meta.fieldInfo(T, "kw_args").field_type, | 2084 | kw_args: std.meta.fieldInfo(T, "kw_args").field_type, |
| 2076 | ) !*T { | 2085 | ) !*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); | ||
| 2078 | inst.* = .{ | 2089 | inst.* = .{ |
| 2079 | .base = .{ | 2090 | .base = .{ |
| 2080 | .tag = T.base_tag, | 2091 | .tag = T.base_tag, |
| ... | @@ -2083,22 +2094,79 @@ fn newZIRInst( | ... | @@ -2083,22 +2094,79 @@ fn newZIRInst( |
| 2083 | .positionals = positionals, | 2094 | .positionals = positionals, |
| 2084 | .kw_args = kw_args, | 2095 | .kw_args = kw_args, |
| 2085 | }; | 2096 | }; |
| 2097 | gen_zir.instructions.appendAssumeCapacity(&inst.base); | ||
| 2086 | return inst; | 2098 | return inst; |
| 2087 | } | 2099 | } |
| 2088 | 2100 | ||
| 2089 | pub fn addZIRInstSpecial( | 2101 | pub fn addZIRNoOp( |
| 2090 | self: *Module, | 2102 | self: *Module, |
| 2091 | scope: *Scope, | 2103 | scope: *Scope, |
| 2092 | src: usize, | 2104 | src: usize, |
| 2093 | comptime T: type, | 2105 | tag: zir.Inst.Tag, |
| 2094 | positionals: std.meta.fieldInfo(T, "positionals").field_type, | 2106 | ) !*zir.Inst { |
| 2095 | kw_args: std.meta.fieldInfo(T, "kw_args").field_type, | ||
| 2096 | ) !*T { | ||
| 2097 | const gen_zir = scope.getGenZIR(); | 2107 | const gen_zir = scope.getGenZIR(); |
| 2098 | try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1); | 2108 | 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 | }; | ||
| 2100 | gen_zir.instructions.appendAssumeCapacity(&inst.base); | 2118 | gen_zir.instructions.appendAssumeCapacity(&inst.base); |
| 2101 | return inst; | 2119 | return &inst.base; |
| 2120 | } | ||
| 2121 | |||
| 2122 | pub 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 | |||
| 2146 | pub 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; | ||
| 2102 | } | 2170 | } |
| 2103 | 2171 | ||
| 2104 | pub fn addZIRInst( | 2172 | pub fn addZIRInst( |
| ... | @@ -2252,46 +2320,51 @@ fn analyzeInstConst(self: *Module, scope: *Scope, const_inst: *zir.Inst.Const) I | ... | @@ -2252,46 +2320,51 @@ fn analyzeInstConst(self: *Module, scope: *Scope, const_inst: *zir.Inst.Const) I |
| 2252 | 2320 | ||
| 2253 | fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Inst { | 2321 | fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Inst { |
| 2254 | switch (old_inst.tag) { | 2322 | switch (old_inst.tag) { |
| 2255 | .arg => return self.analyzeInstArg(scope, old_inst.cast(zir.Inst.Arg).?), | 2323 | .arg => return self.analyzeInstArg(scope, old_inst.castTag(.arg).?), |
| 2256 | .block => return self.analyzeInstBlock(scope, old_inst.cast(zir.Inst.Block).?), | 2324 | .block => return self.analyzeInstBlock(scope, old_inst.castTag(.block).?), |
| 2257 | .@"break" => return self.analyzeInstBreak(scope, old_inst.cast(zir.Inst.Break).?), | 2325 | .@"break" => return self.analyzeInstBreak(scope, old_inst.castTag(.@"break").?), |
| 2258 | .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.cast(zir.Inst.Breakpoint).?), | 2326 | .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.castTag(.breakpoint).?), |
| 2259 | .breakvoid => return self.analyzeInstBreakVoid(scope, old_inst.cast(zir.Inst.BreakVoid).?), | 2327 | .breakvoid => return self.analyzeInstBreakVoid(scope, old_inst.castTag(.breakvoid).?), |
| 2260 | .call => return self.analyzeInstCall(scope, old_inst.cast(zir.Inst.Call).?), | 2328 | .call => return self.analyzeInstCall(scope, old_inst.castTag(.call).?), |
| 2261 | .compileerror => return self.analyzeInstCompileError(scope, old_inst.cast(zir.Inst.CompileError).?), | 2329 | .compileerror => return self.analyzeInstCompileError(scope, old_inst.castTag(.compileerror).?), |
| 2262 | .@"const" => return self.analyzeInstConst(scope, old_inst.cast(zir.Inst.Const).?), | 2330 | .@"const" => return self.analyzeInstConst(scope, old_inst.castTag(.@"const").?), |
| 2263 | .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?), | 2331 | .declref => return self.analyzeInstDeclRef(scope, old_inst.castTag(.declref).?), |
| 2264 | .declref_str => return self.analyzeInstDeclRefStr(scope, old_inst.cast(zir.Inst.DeclRefStr).?), | 2332 | .declref_str => return self.analyzeInstDeclRefStr(scope, old_inst.castTag(.declref_str).?), |
| 2265 | .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?), | 2333 | .declval => return self.analyzeInstDeclVal(scope, old_inst.castTag(.declval).?), |
| 2266 | .declval_in_module => return self.analyzeInstDeclValInModule(scope, old_inst.cast(zir.Inst.DeclValInModule).?), | 2334 | .declval_in_module => return self.analyzeInstDeclValInModule(scope, old_inst.castTag(.declval_in_module).?), |
| 2267 | .str => return self.analyzeInstStr(scope, old_inst.cast(zir.Inst.Str).?), | 2335 | .str => return self.analyzeInstStr(scope, old_inst.castTag(.str).?), |
| 2268 | .int => { | 2336 | .int => { |
| 2269 | const big_int = old_inst.cast(zir.Inst.Int).?.positionals.int; | 2337 | const big_int = old_inst.castTag(.int).?.positionals.int; |
| 2270 | return self.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int); | 2338 | return self.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int); |
| 2271 | }, | 2339 | }, |
| 2272 | .inttype => return self.analyzeInstIntType(scope, old_inst.cast(zir.Inst.IntType).?), | 2340 | .inttype => return self.analyzeInstIntType(scope, old_inst.castTag(.inttype).?), |
| 2273 | .ptrtoint => return self.analyzeInstPtrToInt(scope, old_inst.cast(zir.Inst.PtrToInt).?), | 2341 | .ptrtoint => return self.analyzeInstPtrToInt(scope, old_inst.castTag(.ptrtoint).?), |
| 2274 | .fieldptr => return self.analyzeInstFieldPtr(scope, old_inst.cast(zir.Inst.FieldPtr).?), | 2342 | .fieldptr => return self.analyzeInstFieldPtr(scope, old_inst.castTag(.fieldptr).?), |
| 2275 | .deref => return self.analyzeInstDeref(scope, old_inst.cast(zir.Inst.Deref).?), | 2343 | .deref => return self.analyzeInstDeref(scope, old_inst.castTag(.deref).?), |
| 2276 | .as => return self.analyzeInstAs(scope, old_inst.cast(zir.Inst.As).?), | 2344 | .as => return self.analyzeInstAs(scope, old_inst.castTag(.as).?), |
| 2277 | .@"asm" => return self.analyzeInstAsm(scope, old_inst.cast(zir.Inst.Asm).?), | 2345 | .@"asm" => return self.analyzeInstAsm(scope, old_inst.castTag(.@"asm").?), |
| 2278 | .@"unreachable" => return self.analyzeInstUnreachable(scope, old_inst.cast(zir.Inst.Unreachable).?), | 2346 | .@"unreachable" => return self.analyzeInstUnreachable(scope, old_inst.castTag(.@"unreachable").?), |
| 2279 | .@"return" => return self.analyzeInstRet(scope, old_inst.cast(zir.Inst.Return).?), | 2347 | .@"return" => return self.analyzeInstRet(scope, old_inst.castTag(.@"return").?), |
| 2280 | .returnvoid => return self.analyzeInstRetVoid(scope, old_inst.cast(zir.Inst.ReturnVoid).?), | 2348 | .returnvoid => return self.analyzeInstRetVoid(scope, old_inst.castTag(.returnvoid).?), |
| 2281 | .@"fn" => return self.analyzeInstFn(scope, old_inst.cast(zir.Inst.Fn).?), | 2349 | .@"fn" => return self.analyzeInstFn(scope, old_inst.castTag(.@"fn").?), |
| 2282 | .@"export" => return self.analyzeInstExport(scope, old_inst.cast(zir.Inst.Export).?), | 2350 | .@"export" => return self.analyzeInstExport(scope, old_inst.castTag(.@"export").?), |
| 2283 | .primitive => return self.analyzeInstPrimitive(scope, old_inst.cast(zir.Inst.Primitive).?), | 2351 | .primitive => return self.analyzeInstPrimitive(scope, old_inst.castTag(.primitive).?), |
| 2284 | .fntype => return self.analyzeInstFnType(scope, old_inst.cast(zir.Inst.FnType).?), | 2352 | .fntype => return self.analyzeInstFnType(scope, old_inst.castTag(.fntype).?), |
| 2285 | .intcast => return self.analyzeInstIntCast(scope, old_inst.cast(zir.Inst.IntCast).?), | 2353 | .intcast => return self.analyzeInstIntCast(scope, old_inst.castTag(.intcast).?), |
| 2286 | .bitcast => return self.analyzeInstBitCast(scope, old_inst.cast(zir.Inst.BitCast).?), | 2354 | .bitcast => return self.analyzeInstBitCast(scope, old_inst.castTag(.bitcast).?), |
| 2287 | .elemptr => return self.analyzeInstElemPtr(scope, old_inst.cast(zir.Inst.ElemPtr).?), | 2355 | .elemptr => return self.analyzeInstElemPtr(scope, old_inst.castTag(.elemptr).?), |
| 2288 | .add => return self.analyzeInstAdd(scope, old_inst.cast(zir.Inst.Add).?), | 2356 | .add => return self.analyzeInstAdd(scope, old_inst.castTag(.add).?), |
| 2289 | .sub => return self.analyzeInstSub(scope, old_inst.cast(zir.Inst.Sub).?), | 2357 | .sub => return self.analyzeInstSub(scope, old_inst.castTag(.sub).?), |
| 2290 | .cmp => return self.analyzeInstCmp(scope, old_inst.cast(zir.Inst.Cmp).?), | 2358 | .cmp_lt => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_lt).?, .lt), |
| 2291 | .condbr => return self.analyzeInstCondBr(scope, old_inst.cast(zir.Inst.CondBr).?), | 2359 | .cmp_lte => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_lte).?, .lte), |
| 2292 | .isnull => return self.analyzeInstIsNull(scope, old_inst.cast(zir.Inst.IsNull).?), | 2360 | .cmp_eq => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_eq).?, .eq), |
| 2293 | .isnonnull => return self.analyzeInstIsNonNull(scope, old_inst.cast(zir.Inst.IsNonNull).?), | 2361 | .cmp_gte => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_gte).?, .gte), |
| 2294 | .boolnot => return self.analyzeInstBoolNot(scope, old_inst.cast(zir.Inst.BoolNot).?), | 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).?), | ||
| 2295 | } | 2368 | } |
| 2296 | } | 2369 | } |
| 2297 | 2370 | ||
| ... | @@ -2372,7 +2445,7 @@ fn analyzeInstCompileError(self: *Module, scope: *Scope, inst: *zir.Inst.Compile | ... | @@ -2372,7 +2445,7 @@ fn analyzeInstCompileError(self: *Module, scope: *Scope, inst: *zir.Inst.Compile |
| 2372 | return self.fail(scope, inst.base.src, "{}", .{inst.positionals.msg}); | 2445 | return self.fail(scope, inst.base.src, "{}", .{inst.positionals.msg}); |
| 2373 | } | 2446 | } |
| 2374 | 2447 | ||
| 2375 | fn analyzeInstArg(self: *Module, scope: *Scope, inst: *zir.Inst.Arg) InnerError!*Inst { | 2448 | fn analyzeInstArg(self: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst { |
| 2376 | const b = try self.requireRuntimeBlock(scope, inst.base.src); | 2449 | const b = try self.requireRuntimeBlock(scope, inst.base.src); |
| 2377 | const fn_ty = b.func.?.owner_decl.typed_value.most_recent.typed_value.ty; | 2450 | const fn_ty = b.func.?.owner_decl.typed_value.most_recent.typed_value.ty; |
| 2378 | const param_index = b.instructions.items.len; | 2451 | const param_index = b.instructions.items.len; |
| ... | @@ -2435,7 +2508,7 @@ fn analyzeInstBlock(self: *Module, scope: *Scope, inst: *zir.Inst.Block) InnerEr | ... | @@ -2435,7 +2508,7 @@ fn analyzeInstBlock(self: *Module, scope: *Scope, inst: *zir.Inst.Block) InnerEr |
| 2435 | return &block_inst.base; | 2508 | return &block_inst.base; |
| 2436 | } | 2509 | } |
| 2437 | 2510 | ||
| 2438 | fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.Breakpoint) InnerError!*Inst { | 2511 | fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst { |
| 2439 | const b = try self.requireRuntimeBlock(scope, inst.base.src); | 2512 | const b = try self.requireRuntimeBlock(scope, inst.base.src); |
| 2440 | return self.addNoOp(b, inst.base.src, Type.initTag(.void), .breakpoint); | 2513 | return self.addNoOp(b, inst.base.src, Type.initTag(.void), .breakpoint); |
| 2441 | } | 2514 | } |
| ... | @@ -2791,11 +2864,11 @@ fn analyzeInstElemPtr(self: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inn | ... | @@ -2791,11 +2864,11 @@ fn analyzeInstElemPtr(self: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inn |
| 2791 | return self.fail(scope, inst.base.src, "TODO implement more analyze elemptr", .{}); | 2864 | return self.fail(scope, inst.base.src, "TODO implement more analyze elemptr", .{}); |
| 2792 | } | 2865 | } |
| 2793 | 2866 | ||
| 2794 | fn analyzeInstSub(self: *Module, scope: *Scope, inst: *zir.Inst.Sub) InnerError!*Inst { | 2867 | fn analyzeInstSub(self: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { |
| 2795 | return self.fail(scope, inst.base.src, "TODO implement analysis of sub", .{}); | 2868 | return self.fail(scope, inst.base.src, "TODO implement analysis of sub", .{}); |
| 2796 | } | 2869 | } |
| 2797 | 2870 | ||
| 2798 | fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError!*Inst { | 2871 | fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst { |
| 2799 | const tracy = trace(@src()); | 2872 | const tracy = trace(@src()); |
| 2800 | defer tracy.end(); | 2873 | defer tracy.end(); |
| 2801 | 2874 | ||
| ... | @@ -2848,9 +2921,9 @@ fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError! | ... | @@ -2848,9 +2921,9 @@ fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError! |
| 2848 | return self.fail(scope, inst.base.src, "TODO analyze add for {} + {}", .{ lhs.ty.zigTypeTag(), rhs.ty.zigTypeTag() }); | 2921 | return self.fail(scope, inst.base.src, "TODO analyze add for {} + {}", .{ lhs.ty.zigTypeTag(), rhs.ty.zigTypeTag() }); |
| 2849 | } | 2922 | } |
| 2850 | 2923 | ||
| 2851 | fn analyzeInstDeref(self: *Module, scope: *Scope, deref: *zir.Inst.Deref) InnerError!*Inst { | 2924 | fn analyzeInstDeref(self: *Module, scope: *Scope, deref: *zir.Inst.UnOp) InnerError!*Inst { |
| 2852 | const ptr = try self.resolveInst(scope, deref.positionals.ptr); | 2925 | const ptr = try self.resolveInst(scope, deref.positionals.operand); |
| 2853 | return self.analyzeDeref(scope, deref.base.src, ptr, deref.positionals.ptr.src); | 2926 | return self.analyzeDeref(scope, deref.base.src, ptr, deref.positionals.operand.src); |
| 2854 | } | 2927 | } |
| 2855 | 2928 | ||
| 2856 | fn analyzeDeref(self: *Module, scope: *Scope, src: usize, ptr: *Inst, ptr_src: usize) InnerError!*Inst { | 2929 | fn 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 | ... | @@ -2907,10 +2980,14 @@ fn analyzeInstAsm(self: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerEr |
| 2907 | return &inst.base; | 2980 | return &inst.base; |
| 2908 | } | 2981 | } |
| 2909 | 2982 | ||
| 2910 | fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError!*Inst { | 2983 | fn analyzeInstCmp( |
| 2984 | self: *Module, | ||
| 2985 | scope: *Scope, | ||
| 2986 | inst: *zir.Inst.BinOp, | ||
| 2987 | op: std.math.CompareOperator, | ||
| 2988 | ) InnerError!*Inst { | ||
| 2911 | const lhs = try self.resolveInst(scope, inst.positionals.lhs); | 2989 | const lhs = try self.resolveInst(scope, inst.positionals.lhs); |
| 2912 | const rhs = try self.resolveInst(scope, inst.positionals.rhs); | 2990 | const rhs = try self.resolveInst(scope, inst.positionals.rhs); |
| 2913 | const op = inst.positionals.op; | ||
| 2914 | 2991 | ||
| 2915 | const is_equality_cmp = switch (op) { | 2992 | const is_equality_cmp = switch (op) { |
| 2916 | .eq, .neq => true, | 2993 | .eq, .neq => true, |
| ... | @@ -2964,7 +3041,7 @@ fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError! | ... | @@ -2964,7 +3041,7 @@ fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError! |
| 2964 | return self.fail(scope, inst.base.src, "TODO implement more cmp analysis", .{}); | 3041 | return self.fail(scope, inst.base.src, "TODO implement more cmp analysis", .{}); |
| 2965 | } | 3042 | } |
| 2966 | 3043 | ||
| 2967 | fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.BoolNot) InnerError!*Inst { | 3044 | fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { |
| 2968 | const uncasted_operand = try self.resolveInst(scope, inst.positionals.operand); | 3045 | const uncasted_operand = try self.resolveInst(scope, inst.positionals.operand); |
| 2969 | const bool_type = Type.initTag(.bool); | 3046 | const bool_type = Type.initTag(.bool); |
| 2970 | const operand = try self.coerce(scope, bool_type, uncasted_operand); | 3047 | 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 | ... | @@ -2975,14 +3052,9 @@ fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.BoolNot) Inn |
| 2975 | return self.addUnOp(b, inst.base.src, bool_type, .not, operand); | 3052 | return self.addUnOp(b, inst.base.src, bool_type, .not, operand); |
| 2976 | } | 3053 | } |
| 2977 | 3054 | ||
| 2978 | fn analyzeInstIsNull(self: *Module, scope: *Scope, inst: *zir.Inst.IsNull) InnerError!*Inst { | 3055 | fn analyzeInstIsNonNull(self: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst { |
| 2979 | const operand = try self.resolveInst(scope, inst.positionals.operand); | ||
| 2980 | return self.analyzeIsNull(scope, inst.base.src, operand, true); | ||
| 2981 | } | ||
| 2982 | |||
| 2983 | fn analyzeInstIsNonNull(self: *Module, scope: *Scope, inst: *zir.Inst.IsNonNull) InnerError!*Inst { | ||
| 2984 | const operand = try self.resolveInst(scope, inst.positionals.operand); | 3056 | 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); |
| 2986 | } | 3058 | } |
| 2987 | 3059 | ||
| 2988 | fn analyzeInstCondBr(self: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst { | 3060 | fn analyzeInstCondBr(self: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst { |
| ... | @@ -3031,7 +3103,7 @@ fn wantSafety(self: *Module, scope: *Scope) bool { | ... | @@ -3031,7 +3103,7 @@ fn wantSafety(self: *Module, scope: *Scope) bool { |
| 3031 | }; | 3103 | }; |
| 3032 | } | 3104 | } |
| 3033 | 3105 | ||
| 3034 | fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.Unreachable) InnerError!*Inst { | 3106 | fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.NoOp) InnerError!*Inst { |
| 3035 | const b = try self.requireRuntimeBlock(scope, unreach.base.src); | 3107 | const b = try self.requireRuntimeBlock(scope, unreach.base.src); |
| 3036 | if (self.wantSafety(scope)) { | 3108 | if (self.wantSafety(scope)) { |
| 3037 | // TODO Once we have a panic function to call, call it here instead of this. | 3109 | // 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 | ... | @@ -3040,13 +3112,13 @@ fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.Unrea |
| 3040 | return self.addNoOp(b, unreach.base.src, Type.initTag(.noreturn), .unreach); | 3112 | return self.addNoOp(b, unreach.base.src, Type.initTag(.noreturn), .unreach); |
| 3041 | } | 3113 | } |
| 3042 | 3114 | ||
| 3043 | fn analyzeInstRet(self: *Module, scope: *Scope, inst: *zir.Inst.Return) InnerError!*Inst { | 3115 | fn analyzeInstRet(self: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { |
| 3044 | const operand = try self.resolveInst(scope, inst.positionals.operand); | 3116 | const operand = try self.resolveInst(scope, inst.positionals.operand); |
| 3045 | const b = try self.requireRuntimeBlock(scope, inst.base.src); | 3117 | const b = try self.requireRuntimeBlock(scope, inst.base.src); |
| 3046 | return self.addUnOp(b, inst.base.src, Type.initTag(.noreturn), .ret, operand); | 3118 | return self.addUnOp(b, inst.base.src, Type.initTag(.noreturn), .ret, operand); |
| 3047 | } | 3119 | } |
| 3048 | 3120 | ||
| 3049 | fn analyzeInstRetVoid(self: *Module, scope: *Scope, inst: *zir.Inst.ReturnVoid) InnerError!*Inst { | 3121 | fn analyzeInstRetVoid(self: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst { |
| 3050 | const b = try self.requireRuntimeBlock(scope, inst.base.src); | 3122 | const b = try self.requireRuntimeBlock(scope, inst.base.src); |
| 3051 | return self.addNoOp(b, inst.base.src, Type.initTag(.noreturn), .retvoid); | 3123 | return self.addNoOp(b, inst.base.src, Type.initTag(.noreturn), .retvoid); |
| 3052 | } | 3124 | } |
src-self-hosted/astgen.zig+18-40| ... | @@ -16,6 +16,15 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst { | ... | @@ -16,6 +16,15 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst { |
| 16 | switch (node.tag) { | 16 | switch (node.tag) { |
| 17 | .VarDecl => unreachable, // Handled in `blockExpr`. | 17 | .VarDecl => unreachable, // Handled in `blockExpr`. |
| 18 | 18 | ||
| 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 | |||
| 19 | .Identifier => return identifier(mod, scope, node.castTag(.Identifier).?), | 28 | .Identifier => return identifier(mod, scope, node.castTag(.Identifier).?), |
| 20 | .Asm => return assembly(mod, scope, node.castTag(.Asm).?), | 29 | .Asm => return assembly(mod, scope, node.castTag(.Asm).?), |
| 21 | .StringLiteral => return stringLiteral(mod, scope, node.castTag(.StringLiteral).?), | 30 | .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 { | ... | @@ -26,13 +35,6 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst { |
| 26 | .ControlFlowExpression => return controlFlowExpr(mod, scope, node.castTag(.ControlFlowExpression).?), | 35 | .ControlFlowExpression => return controlFlowExpr(mod, scope, node.castTag(.ControlFlowExpression).?), |
| 27 | .If => return ifExpr(mod, scope, node.castTag(.If).?), | 36 | .If => return ifExpr(mod, scope, node.castTag(.If).?), |
| 28 | .Assign => return assign(mod, scope, node.castTag(.Assign).?), | 37 | .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), | ||
| 36 | .Period => return field(mod, scope, node.castTag(.Period).?), | 38 | .Period => return field(mod, scope, node.castTag(.Period).?), |
| 37 | .Deref => return deref(mod, scope, node.castTag(.Deref).?), | 39 | .Deref => return deref(mod, scope, node.castTag(.Deref).?), |
| 38 | .BoolNot => return boolNot(mod, scope, node.castTag(.BoolNot).?), | 40 | .BoolNot => return boolNot(mod, scope, node.castTag(.BoolNot).?), |
| ... | @@ -97,14 +99,6 @@ fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!Scop | ... | @@ -97,14 +99,6 @@ fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!Scop |
| 97 | }, | 99 | }, |
| 98 | .Keyword_var => { | 100 | .Keyword_var => { |
| 99 | return mod.failNode(scope, &node.base, "TODO implement local vars", .{}); | 101 | 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 | //} | ||
| 108 | }, | 102 | }, |
| 109 | else => unreachable, | 103 | else => unreachable, |
| 110 | } | 104 | } |
| ... | @@ -114,7 +108,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr | ... | @@ -114,7 +108,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr |
| 114 | const operand = try expr(mod, scope, node.rhs); | 108 | const operand = try expr(mod, scope, node.rhs); |
| 115 | const tree = scope.tree(); | 109 | const tree = scope.tree(); |
| 116 | const src = tree.token_locs[node.op_token].start; | 110 | 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); |
| 118 | } | 112 | } |
| 119 | 113 | ||
| 120 | fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst { | 114 | fn 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! | ... | @@ -169,33 +163,21 @@ fn field(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp) InnerError! |
| 169 | const field_name = try identifierStringInst(mod, scope, node.rhs.castTag(.Identifier).?); | 163 | const field_name = try identifierStringInst(mod, scope, node.rhs.castTag(.Identifier).?); |
| 170 | 164 | ||
| 171 | const pointer = try mod.addZIRInst(scope, src, zir.Inst.FieldPtr, .{ .object_ptr = lhs, .field_name = field_name }, .{}); | 165 | 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); |
| 173 | } | 167 | } |
| 174 | 168 | ||
| 175 | fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { | 169 | fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { |
| 176 | const tree = scope.tree(); | 170 | const tree = scope.tree(); |
| 177 | const src = tree.token_locs[node.rtoken].start; | 171 | const src = tree.token_locs[node.rtoken].start; |
| 178 | |||
| 179 | const lhs = try expr(mod, scope, node.lhs); | 172 | const lhs = try expr(mod, scope, node.lhs); |
| 180 | 173 | return mod.addZIRUnOp(scope, src, .deref, lhs); | |
| 181 | return mod.addZIRInst(scope, src, zir.Inst.Deref, .{ .ptr = lhs }, .{}); | ||
| 182 | } | ||
| 183 | |||
| 184 | fn 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 }, .{}); | ||
| 192 | } | 174 | } |
| 193 | 175 | ||
| 194 | fn cmp( | 176 | fn simpleInfixOp( |
| 195 | mod: *Module, | 177 | mod: *Module, |
| 196 | scope: *Scope, | 178 | scope: *Scope, |
| 197 | infix_node: *ast.Node.SimpleInfixOp, | 179 | infix_node: *ast.Node.SimpleInfixOp, |
| 198 | op: std.math.CompareOperator, | 180 | op_inst_tag: zir.Inst.Tag, |
| 199 | ) InnerError!*zir.Inst { | 181 | ) InnerError!*zir.Inst { |
| 200 | const lhs = try expr(mod, scope, infix_node.lhs); | 182 | const lhs = try expr(mod, scope, infix_node.lhs); |
| 201 | const rhs = try expr(mod, scope, infix_node.rhs); | 183 | const rhs = try expr(mod, scope, infix_node.rhs); |
| ... | @@ -203,11 +185,7 @@ fn cmp( | ... | @@ -203,11 +185,7 @@ fn cmp( |
| 203 | const tree = scope.tree(); | 185 | const tree = scope.tree(); |
| 204 | const src = tree.token_locs[infix_node.op_token].start; | 186 | const src = tree.token_locs[infix_node.op_token].start; |
| 205 | 187 | ||
| 206 | return mod.addZIRInst(scope, src, zir.Inst.Cmp, .{ | 188 | return mod.addZIRBinOp(scope, src, op_inst_tag, lhs, rhs); |
| 207 | .lhs = lhs, | ||
| 208 | .op = op, | ||
| 209 | .rhs = rhs, | ||
| 210 | }, .{}); | ||
| 211 | } | 189 | } |
| 212 | 190 | ||
| 213 | fn ifExpr(mod: *Module, scope: *Scope, if_node: *ast.Node.If) InnerError!*zir.Inst { | 191 | fn ifExpr(mod: *Module, scope: *Scope, if_node: *ast.Node.If) InnerError!*zir.Inst { |
| ... | @@ -306,9 +284,9 @@ fn controlFlowExpr( | ... | @@ -306,9 +284,9 @@ fn controlFlowExpr( |
| 306 | const src = tree.token_locs[cfe.ltoken].start; | 284 | const src = tree.token_locs[cfe.ltoken].start; |
| 307 | if (cfe.rhs) |rhs_node| { | 285 | if (cfe.rhs) |rhs_node| { |
| 308 | const operand = try expr(mod, scope, rhs_node); | 286 | 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); |
| 310 | } else { | 288 | } else { |
| 311 | return mod.addZIRInst(scope, src, zir.Inst.ReturnVoid, .{}, .{}); | 289 | return mod.addZIRNoOp(scope, src, .returnvoid); |
| 312 | } | 290 | } |
| 313 | } | 291 | } |
| 314 | 292 | ||
| ... | @@ -519,7 +497,7 @@ fn callExpr(mod: *Module, scope: *Scope, node: *ast.Node.Call) InnerError!*zir.I | ... | @@ -519,7 +497,7 @@ fn callExpr(mod: *Module, scope: *Scope, node: *ast.Node.Call) InnerError!*zir.I |
| 519 | fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.Unreachable) InnerError!*zir.Inst { | 497 | fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.Unreachable) InnerError!*zir.Inst { |
| 520 | const tree = scope.tree(); | 498 | const tree = scope.tree(); |
| 521 | const src = tree.token_locs[unreach_node.token].start; | 499 | 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"); |
| 523 | } | 501 | } |
| 524 | 502 | ||
| 525 | fn getSimplePrimitiveValue(name: []const u8) ?TypedValue { | 503 | fn getSimplePrimitiveValue(name: []const u8) ?TypedValue { |
src-self-hosted/zir.zig+137-214| ... | @@ -79,11 +79,69 @@ pub const Inst = struct { | ... | @@ -79,11 +79,69 @@ pub const Inst = struct { |
| 79 | elemptr, | 79 | elemptr, |
| 80 | add, | 80 | add, |
| 81 | sub, | 81 | sub, |
| 82 | cmp, | 82 | cmp_lt, |
| 83 | cmp_lte, | ||
| 84 | cmp_eq, | ||
| 85 | cmp_gte, | ||
| 86 | cmp_gt, | ||
| 87 | cmp_neq, | ||
| 83 | condbr, | 88 | condbr, |
| 84 | isnull, | 89 | isnull, |
| 85 | isnonnull, | 90 | isnonnull, |
| 86 | 91 | ||
| 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 | |||
| 87 | /// Returns whether the instruction is one of the control flow "noreturn" types. | 145 | /// Returns whether the instruction is one of the control flow "noreturn" types. |
| 88 | /// Function calls do not count. | 146 | /// Function calls do not count. |
| 89 | pub fn isNoReturn(tag: Tag) bool { | 147 | pub fn isNoReturn(tag: Tag) bool { |
| ... | @@ -114,7 +172,12 @@ pub const Inst = struct { | ... | @@ -114,7 +172,12 @@ pub const Inst = struct { |
| 114 | .elemptr, | 172 | .elemptr, |
| 115 | .add, | 173 | .add, |
| 116 | .sub, | 174 | .sub, |
| 117 | .cmp, | 175 | .cmp_lt, |
| 176 | .cmp_lte, | ||
| 177 | .cmp_eq, | ||
| 178 | .cmp_gte, | ||
| 179 | .cmp_gt, | ||
| 180 | .cmp_neq, | ||
| 118 | .isnull, | 181 | .isnull, |
| 119 | .isnonnull, | 182 | .isnonnull, |
| 120 | .boolnot, | 183 | .boolnot, |
| ... | @@ -132,63 +195,56 @@ pub const Inst = struct { | ... | @@ -132,63 +195,56 @@ pub const Inst = struct { |
| 132 | } | 195 | } |
| 133 | }; | 196 | }; |
| 134 | 197 | ||
| 135 | pub fn TagToType(tag: Tag) type { | 198 | /// Prefer `castTag` to this. |
| 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 | |||
| 177 | pub fn cast(base: *Inst, comptime T: type) ?*T { | 199 | pub fn cast(base: *Inst, comptime T: type) ?*T { |
| 178 | if (base.tag != T.base_tag) | 200 | if (@hasField(T, "base_tag")) { |
| 179 | return null; | 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 | } | ||
| 180 | 214 | ||
| 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; | ||
| 182 | } | 220 | } |
| 183 | 221 | ||
| 184 | pub const Arg = struct { | 222 | pub const NoOp = struct { |
| 185 | pub const base_tag = Tag.arg; | ||
| 186 | base: Inst, | 223 | base: Inst, |
| 187 | 224 | ||
| 188 | positionals: struct {}, | 225 | positionals: struct {}, |
| 189 | kw_args: struct {}, | 226 | kw_args: struct {}, |
| 190 | }; | 227 | }; |
| 191 | 228 | ||
| 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 | |||
| 192 | pub const Block = struct { | 248 | pub const Block = struct { |
| 193 | pub const base_tag = Tag.block; | 249 | pub const base_tag = Tag.block; |
| 194 | base: Inst, | 250 | base: Inst, |
| ... | @@ -210,14 +266,6 @@ pub const Inst = struct { | ... | @@ -210,14 +266,6 @@ pub const Inst = struct { |
| 210 | kw_args: struct {}, | 266 | kw_args: struct {}, |
| 211 | }; | 267 | }; |
| 212 | 268 | ||
| 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 | |||
| 221 | pub const BreakVoid = struct { | 269 | pub const BreakVoid = struct { |
| 222 | pub const base_tag = Tag.breakvoid; | 270 | pub const base_tag = Tag.breakvoid; |
| 223 | base: Inst, | 271 | base: Inst, |
| ... | @@ -301,16 +349,6 @@ pub const Inst = struct { | ... | @@ -301,16 +349,6 @@ pub const Inst = struct { |
| 301 | kw_args: struct {}, | 349 | kw_args: struct {}, |
| 302 | }; | 350 | }; |
| 303 | 351 | ||
| 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 | |||
| 314 | pub const Str = struct { | 352 | pub const Str = struct { |
| 315 | pub const base_tag = Tag.str; | 353 | pub const base_tag = Tag.str; |
| 316 | base: Inst, | 354 | base: Inst, |
| ... | @@ -353,16 +391,6 @@ pub const Inst = struct { | ... | @@ -353,16 +391,6 @@ pub const Inst = struct { |
| 353 | kw_args: struct {}, | 391 | kw_args: struct {}, |
| 354 | }; | 392 | }; |
| 355 | 393 | ||
| 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 | |||
| 366 | pub const As = struct { | 394 | pub const As = struct { |
| 367 | pub const base_tag = Tag.as; | 395 | pub const base_tag = Tag.as; |
| 368 | pub const builtin_name = "@as"; | 396 | pub const builtin_name = "@as"; |
| ... | @@ -392,32 +420,6 @@ pub const Inst = struct { | ... | @@ -392,32 +420,6 @@ pub const Inst = struct { |
| 392 | }, | 420 | }, |
| 393 | }; | 421 | }; |
| 394 | 422 | ||
| 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 | |||
| 421 | pub const Fn = struct { | 423 | pub const Fn = struct { |
| 422 | pub const base_tag = Tag.@"fn"; | 424 | pub const base_tag = Tag.@"fn"; |
| 423 | base: Inst, | 425 | base: Inst, |
| ... | @@ -587,42 +589,6 @@ pub const Inst = struct { | ... | @@ -587,42 +589,6 @@ pub const Inst = struct { |
| 587 | kw_args: struct {}, | 589 | kw_args: struct {}, |
| 588 | }; | 590 | }; |
| 589 | 591 | ||
| 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 | |||
| 626 | pub const CondBr = struct { | 592 | pub const CondBr = struct { |
| 627 | pub const base_tag = Tag.condbr; | 593 | pub const base_tag = Tag.condbr; |
| 628 | base: Inst, | 594 | base: Inst, |
| ... | @@ -634,26 +600,6 @@ pub const Inst = struct { | ... | @@ -634,26 +600,6 @@ pub const Inst = struct { |
| 634 | }, | 600 | }, |
| 635 | kw_args: struct {}, | 601 | kw_args: struct {}, |
| 636 | }; | 602 | }; |
| 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 | }; | ||
| 657 | }; | 603 | }; |
| 658 | 604 | ||
| 659 | pub const ErrorMsg = struct { | 605 | pub const ErrorMsg = struct { |
| ... | @@ -775,7 +721,7 @@ const Writer = struct { | ... | @@ -775,7 +721,7 @@ const Writer = struct { |
| 775 | comptime inst_tag: Inst.Tag, | 721 | comptime inst_tag: Inst.Tag, |
| 776 | base: *Inst, | 722 | base: *Inst, |
| 777 | ) (@TypeOf(stream).Error || error{OutOfMemory})!void { | 723 | ) (@TypeOf(stream).Error || error{OutOfMemory})!void { |
| 778 | const SpecificInst = Inst.TagToType(inst_tag); | 724 | const SpecificInst = inst_tag.Type(); |
| 779 | const inst = @fieldParentPtr(SpecificInst, "base", base); | 725 | const inst = @fieldParentPtr(SpecificInst, "base", base); |
| 780 | const Positionals = @TypeOf(inst.positionals); | 726 | const Positionals = @TypeOf(inst.positionals); |
| 781 | try stream.writeAll("= " ++ @tagName(inst_tag) ++ "("); | 727 | try stream.writeAll("= " ++ @tagName(inst_tag) ++ "("); |
| ... | @@ -1102,7 +1048,7 @@ const Parser = struct { | ... | @@ -1102,7 +1048,7 @@ const Parser = struct { |
| 1102 | inline for (@typeInfo(Inst.Tag).Enum.fields) |field| { | 1048 | inline for (@typeInfo(Inst.Tag).Enum.fields) |field| { |
| 1103 | if (mem.eql(u8, field.name, fn_name)) { | 1049 | if (mem.eql(u8, field.name, fn_name)) { |
| 1104 | const tag = @field(Inst.Tag, field.name); | 1050 | 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); |
| 1106 | } | 1052 | } |
| 1107 | } | 1053 | } |
| 1108 | return self.fail("unknown instruction '{}'", .{fn_name}); | 1054 | return self.fail("unknown instruction '{}'", .{fn_name}); |
| ... | @@ -1112,6 +1058,7 @@ const Parser = struct { | ... | @@ -1112,6 +1058,7 @@ const Parser = struct { |
| 1112 | self: *Parser, | 1058 | self: *Parser, |
| 1113 | comptime fn_name: []const u8, | 1059 | comptime fn_name: []const u8, |
| 1114 | comptime InstType: type, | 1060 | comptime InstType: type, |
| 1061 | tag: Inst.Tag, | ||
| 1115 | body_ctx: ?*Body, | 1062 | body_ctx: ?*Body, |
| 1116 | inst_name: []const u8, | 1063 | inst_name: []const u8, |
| 1117 | contents_start: usize, | 1064 | contents_start: usize, |
| ... | @@ -1119,7 +1066,7 @@ const Parser = struct { | ... | @@ -1119,7 +1066,7 @@ const Parser = struct { |
| 1119 | const inst_specific = try self.arena.allocator.create(InstType); | 1066 | const inst_specific = try self.arena.allocator.create(InstType); |
| 1120 | inst_specific.base = .{ | 1067 | inst_specific.base = .{ |
| 1121 | .src = self.i, | 1068 | .src = self.i, |
| 1122 | .tag = InstType.base_tag, | 1069 | .tag = tag, |
| 1123 | }; | 1070 | }; |
| 1124 | 1071 | ||
| 1125 | if (InstType == Inst.Block) { | 1072 | if (InstType == Inst.Block) { |
| ... | @@ -1615,12 +1562,12 @@ const EmitZIR = struct { | ... | @@ -1615,12 +1562,12 @@ const EmitZIR = struct { |
| 1615 | } | 1562 | } |
| 1616 | } | 1563 | } |
| 1617 | 1564 | ||
| 1618 | fn emitNoOp(self: *EmitZIR, src: usize, comptime T: type) Allocator.Error!*Inst { | 1565 | fn emitNoOp(self: *EmitZIR, src: usize, tag: Inst.Tag) Allocator.Error!*Inst { |
| 1619 | const new_inst = try self.arena.allocator.create(T); | 1566 | const new_inst = try self.arena.allocator.create(Inst.NoOp); |
| 1620 | new_inst.* = .{ | 1567 | new_inst.* = .{ |
| 1621 | .base = .{ | 1568 | .base = .{ |
| 1622 | .src = src, | 1569 | .src = src, |
| 1623 | .tag = T.base_tag, | 1570 | .tag = tag, |
| 1624 | }, | 1571 | }, |
| 1625 | .positionals = .{}, | 1572 | .positionals = .{}, |
| 1626 | .kw_args = .{}, | 1573 | .kw_args = .{}, |
| ... | @@ -1628,41 +1575,18 @@ const EmitZIR = struct { | ... | @@ -1628,41 +1575,18 @@ const EmitZIR = struct { |
| 1628 | return &new_inst.base; | 1575 | return &new_inst.base; |
| 1629 | } | 1576 | } |
| 1630 | 1577 | ||
| 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 | |||
| 1654 | fn emitUnOp( | 1578 | fn emitUnOp( |
| 1655 | self: *EmitZIR, | 1579 | self: *EmitZIR, |
| 1656 | src: usize, | 1580 | src: usize, |
| 1657 | new_body: ZirBody, | 1581 | new_body: ZirBody, |
| 1658 | old_inst: *ir.Inst.UnOp, | 1582 | old_inst: *ir.Inst.UnOp, |
| 1659 | comptime I: type, | 1583 | tag: Inst.Tag, |
| 1660 | ) Allocator.Error!*Inst { | 1584 | ) Allocator.Error!*Inst { |
| 1661 | const new_inst = try self.arena.allocator.create(I); | 1585 | const new_inst = try self.arena.allocator.create(Inst.UnOp); |
| 1662 | new_inst.* = .{ | 1586 | new_inst.* = .{ |
| 1663 | .base = .{ | 1587 | .base = .{ |
| 1664 | .src = src, | 1588 | .src = src, |
| 1665 | .tag = I.base_tag, | 1589 | .tag = tag, |
| 1666 | }, | 1590 | }, |
| 1667 | .positionals = .{ | 1591 | .positionals = .{ |
| 1668 | .operand = try self.resolveInst(new_body, old_inst.operand), | 1592 | .operand = try self.resolveInst(new_body, old_inst.operand), |
| ... | @@ -1677,13 +1601,13 @@ const EmitZIR = struct { | ... | @@ -1677,13 +1601,13 @@ const EmitZIR = struct { |
| 1677 | src: usize, | 1601 | src: usize, |
| 1678 | new_body: ZirBody, | 1602 | new_body: ZirBody, |
| 1679 | old_inst: *ir.Inst.BinOp, | 1603 | old_inst: *ir.Inst.BinOp, |
| 1680 | comptime I: type, | 1604 | tag: Inst.Tag, |
| 1681 | ) Allocator.Error!*Inst { | 1605 | ) Allocator.Error!*Inst { |
| 1682 | const new_inst = try self.arena.allocator.create(I); | 1606 | const new_inst = try self.arena.allocator.create(Inst.BinOp); |
| 1683 | new_inst.* = .{ | 1607 | new_inst.* = .{ |
| 1684 | .base = .{ | 1608 | .base = .{ |
| 1685 | .src = src, | 1609 | .src = src, |
| 1686 | .tag = I.base_tag, | 1610 | .tag = tag, |
| 1687 | }, | 1611 | }, |
| 1688 | .positionals = .{ | 1612 | .positionals = .{ |
| 1689 | .lhs = try self.resolveInst(new_body, old_inst.lhs), | 1613 | .lhs = try self.resolveInst(new_body, old_inst.lhs), |
| ... | @@ -1708,26 +1632,25 @@ const EmitZIR = struct { | ... | @@ -1708,26 +1632,25 @@ const EmitZIR = struct { |
| 1708 | const new_inst = switch (inst.tag) { | 1632 | const new_inst = switch (inst.tag) { |
| 1709 | .constant => unreachable, // excluded from function bodies | 1633 | .constant => unreachable, // excluded from function bodies |
| 1710 | 1634 | ||
| 1711 | .arg => try self.emitNoOp(inst.src, Inst.Arg), | 1635 | .arg => try self.emitNoOp(inst.src, .arg), |
| 1712 | .breakpoint => try self.emitNoOp(inst.src, Inst.Breakpoint), | 1636 | .breakpoint => try self.emitNoOp(inst.src, .breakpoint), |
| 1713 | .unreach => try self.emitNoOp(inst.src, Inst.Unreachable), | 1637 | .unreach => try self.emitNoOp(inst.src, .@"unreachable"), |
| 1714 | .retvoid => try self.emitNoOp(inst.src, Inst.ReturnVoid), | 1638 | .retvoid => try self.emitNoOp(inst.src, .returnvoid), |
| 1715 | 1639 | ||
| 1716 | .not => try self.emitUnOp(inst.src, new_body, inst.castTag(.not).?, Inst.BoolNot), | 1640 | .not => try self.emitUnOp(inst.src, new_body, inst.castTag(.not).?, .boolnot), |
| 1717 | .ret => try self.emitUnOp(inst.src, new_body, inst.castTag(.ret).?, Inst.Return), | 1641 | .ret => try self.emitUnOp(inst.src, new_body, inst.castTag(.ret).?, .@"return"), |
| 1718 | .ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, Inst.PtrToInt), | 1642 | .ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, .ptrtoint), |
| 1719 | .isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, Inst.IsNull), | 1643 | .isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, .isnull), |
| 1720 | .isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, Inst.IsNonNull), | 1644 | .isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, .isnonnull), |
| 1721 | 1645 | ||
| 1722 | .add => try self.emitBinOp(inst.src, new_body, inst.castTag(.add).?, Inst.Add), | 1646 | .add => try self.emitBinOp(inst.src, new_body, inst.castTag(.add).?, .add), |
| 1723 | .sub => try self.emitBinOp(inst.src, new_body, inst.castTag(.sub).?, Inst.Sub), | 1647 | .sub => try self.emitBinOp(inst.src, new_body, inst.castTag(.sub).?, .sub), |
| 1724 | 1648 | .cmp_lt => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_lt).?, .cmp_lt), | |
| 1725 | .cmp_lt => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_lt).?, .lt), | 1649 | .cmp_lte => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_lte).?, .cmp_lte), |
| 1726 | .cmp_lte => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_lte).?, .lte), | 1650 | .cmp_eq => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_eq).?, .cmp_eq), |
| 1727 | .cmp_eq => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_eq).?, .eq), | 1651 | .cmp_gte => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_gte).?, .cmp_gte), |
| 1728 | .cmp_gte => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_gte).?, .gte), | 1652 | .cmp_gt => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_gt).?, .cmp_gt), |
| 1729 | .cmp_gt => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_gt).?, .gt), | 1653 | .cmp_neq => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_neq).?, .cmp_neq), |
| 1730 | .cmp_neq => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_neq).?, .neq), | ||
| 1731 | 1654 | ||
| 1732 | .bitcast => blk: { | 1655 | .bitcast => blk: { |
| 1733 | const old_inst = inst.castTag(.bitcast).?; | 1656 | const old_inst = inst.castTag(.bitcast).?; |
test/stage2/zir.zig+1-1| ... | @@ -56,7 +56,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -56,7 +56,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 56 | \\ %result = add(%x0, %x1) | 56 | \\ %result = add(%x0, %x1) |
| 57 | \\ | 57 | \\ |
| 58 | \\ %expected = int(69) | 58 | \\ %expected = int(69) |
| 59 | \\ %ok = cmp(%result, eq, %expected) | 59 | \\ %ok = cmp_eq(%result, %expected) |
| 60 | \\ %10 = condbr(%ok, { | 60 | \\ %10 = condbr(%ok, { |
| 61 | \\ %11 = returnvoid() | 61 | \\ %11 = returnvoid() |
| 62 | \\ }, { | 62 | \\ }, { |