| author | |
| committer | |
| log | 5769c963e0748088ba2636e870cbc6f887d10454 |
| tree | 1fee68ec22c0e7fcdc7666f4fd2e683eb241fb09 |
| parent | 07c204393ff18b5503d9995fecabdbac154d385e |
4 files changed, 121 insertions(+), 94 deletions(-)
src/Module.zig+26| ... | @@ -1667,6 +1667,9 @@ pub const SrcLoc = struct { | ... | @@ -1667,6 +1667,9 @@ pub const SrcLoc = struct { |
| 1667 | .node_offset_asm_ret_ty, | 1667 | .node_offset_asm_ret_ty, |
| 1668 | .node_offset_if_cond, | 1668 | .node_offset_if_cond, |
| 1669 | .node_offset_anyframe_type, | 1669 | .node_offset_anyframe_type, |
| 1670 | .node_offset_bin_op, | ||
| 1671 | .node_offset_bin_lhs, | ||
| 1672 | .node_offset_bin_rhs, | ||
| 1670 | => src_loc.container.decl.container.file_scope, | 1673 | => src_loc.container.decl.container.file_scope, |
| 1671 | }; | 1674 | }; |
| 1672 | } | 1675 | } |
| ... | @@ -1722,6 +1725,9 @@ pub const SrcLoc = struct { | ... | @@ -1722,6 +1725,9 @@ pub const SrcLoc = struct { |
| 1722 | .node_offset_asm_ret_ty => @panic("TODO"), | 1725 | .node_offset_asm_ret_ty => @panic("TODO"), |
| 1723 | .node_offset_if_cond => @panic("TODO"), | 1726 | .node_offset_if_cond => @panic("TODO"), |
| 1724 | .node_offset_anyframe_type => @panic("TODO"), | 1727 | .node_offset_anyframe_type => @panic("TODO"), |
| 1728 | .node_offset_bin_op => @panic("TODO"), | ||
| 1729 | .node_offset_bin_lhs => @panic("TODO"), | ||
| 1730 | .node_offset_bin_rhs => @panic("TODO"), | ||
| 1725 | } | 1731 | } |
| 1726 | } | 1732 | } |
| 1727 | }; | 1733 | }; |
| ... | @@ -1846,6 +1852,20 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -1846,6 +1852,20 @@ pub const LazySrcLoc = union(enum) { |
| 1846 | /// to the type expression. | 1852 | /// to the type expression. |
| 1847 | /// The Decl is determined contextually. | 1853 | /// The Decl is determined contextually. |
| 1848 | node_offset_anyframe_type: i32, | 1854 | node_offset_anyframe_type: i32, |
| 1855 | /// The source location points to a binary expression, such as `a + b`, found | ||
| 1856 | /// by taking this AST node index offset from the containing Decl AST node. | ||
| 1857 | /// The Decl is determined contextually. | ||
| 1858 | node_offset_bin_op: i32, | ||
| 1859 | /// The source location points to the LHS of a binary expression, found | ||
| 1860 | /// by taking this AST node index offset from the containing Decl AST node, | ||
| 1861 | /// which points to a binary expression AST node. Next, nagivate to the LHS. | ||
| 1862 | /// The Decl is determined contextually. | ||
| 1863 | node_offset_bin_lhs: i32, | ||
| 1864 | /// The source location points to the RHS of a binary expression, found | ||
| 1865 | /// by taking this AST node index offset from the containing Decl AST node, | ||
| 1866 | /// which points to a binary expression AST node. Next, nagivate to the RHS. | ||
| 1867 | /// The Decl is determined contextually. | ||
| 1868 | node_offset_bin_rhs: i32, | ||
| 1849 | 1869 | ||
| 1850 | /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope. | 1870 | /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope. |
| 1851 | pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc { | 1871 | pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc { |
| ... | @@ -1877,6 +1897,9 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -1877,6 +1897,9 @@ pub const LazySrcLoc = union(enum) { |
| 1877 | .node_offset_asm_ret_ty, | 1897 | .node_offset_asm_ret_ty, |
| 1878 | .node_offset_if_cond, | 1898 | .node_offset_if_cond, |
| 1879 | .node_offset_anyframe_type, | 1899 | .node_offset_anyframe_type, |
| 1900 | .node_offset_bin_op, | ||
| 1901 | .node_offset_bin_lhs, | ||
| 1902 | .node_offset_bin_rhs, | ||
| 1880 | => .{ | 1903 | => .{ |
| 1881 | .container = .{ .decl = scope.srcDecl().? }, | 1904 | .container = .{ .decl = scope.srcDecl().? }, |
| 1882 | .lazy = lazy, | 1905 | .lazy = lazy, |
| ... | @@ -1914,6 +1937,9 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -1914,6 +1937,9 @@ pub const LazySrcLoc = union(enum) { |
| 1914 | .node_offset_asm_ret_ty, | 1937 | .node_offset_asm_ret_ty, |
| 1915 | .node_offset_if_cond, | 1938 | .node_offset_if_cond, |
| 1916 | .node_offset_anyframe_type, | 1939 | .node_offset_anyframe_type, |
| 1940 | .node_offset_bin_op, | ||
| 1941 | .node_offset_bin_lhs, | ||
| 1942 | .node_offset_bin_rhs, | ||
| 1917 | => .{ | 1943 | => .{ |
| 1918 | .container = .{ .decl = decl }, | 1944 | .container = .{ .decl = decl }, |
| 1919 | .lazy = lazy, | 1945 | .lazy = lazy, |
src/Sema.zig+46-59| ... | @@ -2419,17 +2419,18 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr | ... | @@ -2419,17 +2419,18 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr |
| 2419 | const tracy = trace(@src()); | 2419 | const tracy = trace(@src()); |
| 2420 | defer tracy.end(); | 2420 | defer tracy.end(); |
| 2421 | 2421 | ||
| 2422 | if (true) @panic("TODO rework with zir-memory-layout in mind"); | 2422 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 2423 | 2423 | const src: LazySrcLoc = .{ .node_offset_bin_op = inst_data.src_node }; | |
| 2424 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; | 2424 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 2425 | const src: LazySrcLoc = .todo; | 2425 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 2426 | const lhs = try sema.resolveInst(bin_inst.lhs); | 2426 | const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data; |
| 2427 | const rhs = try sema.resolveInst(bin_inst.rhs); | 2427 | const lhs = try sema.resolveInst(extra.lhs); |
| 2428 | const rhs = try sema.resolveInst(extra.rhs); | ||
| 2428 | 2429 | ||
| 2429 | const instructions = &[_]*Inst{ lhs, rhs }; | 2430 | const instructions = &[_]*Inst{ lhs, rhs }; |
| 2430 | const resolved_type = try sema.resolvePeerTypes(block, instructions); | 2431 | const resolved_type = try sema.resolvePeerTypes(block, instructions); |
| 2431 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs.src); | 2432 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 2432 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs.src); | 2433 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 2433 | 2434 | ||
| 2434 | const scalar_type = if (resolved_type.zigTypeTag() == .Vector) | 2435 | const scalar_type = if (resolved_type.zigTypeTag() == .Vector) |
| 2435 | resolved_type.elemType() | 2436 | resolved_type.elemType() |
| ... | @@ -2455,8 +2456,9 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr | ... | @@ -2455,8 +2456,9 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr |
| 2455 | 2456 | ||
| 2456 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; | 2457 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 2457 | const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat; | 2458 | const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat; |
| 2459 | const zir_tags = block.sema.code.instructions.items(.tag); | ||
| 2458 | 2460 | ||
| 2459 | if (!is_int and !(is_float and floatOpAllowed(inst.base.tag))) { | 2461 | if (!is_int and !(is_float and floatOpAllowed(zir_tags[inst]))) { |
| 2460 | return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) }); | 2462 | return sema.mod.fail(&block.base, src, "invalid operands to binary expression: '{s}' and '{s}'", .{ @tagName(lhs.ty.zigTypeTag()), @tagName(rhs.ty.zigTypeTag()) }); |
| 2461 | } | 2463 | } |
| 2462 | 2464 | ||
| ... | @@ -2468,71 +2470,56 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr | ... | @@ -2468,71 +2470,56 @@ fn zirArithmetic(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr |
| 2468 | .val = Value.initTag(.undef), | 2470 | .val = Value.initTag(.undef), |
| 2469 | }); | 2471 | }); |
| 2470 | } | 2472 | } |
| 2471 | return sema.analyzeInstComptimeOp(block, scalar_type, inst, lhs_val, rhs_val); | 2473 | // incase rhs is 0, simply return lhs without doing any calculations |
| 2474 | // TODO Once division is implemented we should throw an error when dividing by 0. | ||
| 2475 | if (rhs_val.compareWithZero(.eq)) { | ||
| 2476 | return sema.mod.constInst(sema.arena, src, .{ | ||
| 2477 | .ty = scalar_type, | ||
| 2478 | .val = lhs_val, | ||
| 2479 | }); | ||
| 2480 | } | ||
| 2481 | |||
| 2482 | const value = switch (zir_tags[inst]) { | ||
| 2483 | .add => blk: { | ||
| 2484 | const val = if (is_int) | ||
| 2485 | try Module.intAdd(sema.arena, lhs_val, rhs_val) | ||
| 2486 | else | ||
| 2487 | try Module.floatAdd(sema.arena, scalar_type, src, lhs_val, rhs_val); | ||
| 2488 | break :blk val; | ||
| 2489 | }, | ||
| 2490 | .sub => blk: { | ||
| 2491 | const val = if (is_int) | ||
| 2492 | try Module.intSub(sema.arena, lhs_val, rhs_val) | ||
| 2493 | else | ||
| 2494 | try Module.floatSub(sema.arena, scalar_type, src, lhs_val, rhs_val); | ||
| 2495 | break :blk val; | ||
| 2496 | }, | ||
| 2497 | else => return sema.mod.fail(&block.base, src, "TODO Implement arithmetic operand '{s}'", .{@tagName(zir_tags[inst])}), | ||
| 2498 | }; | ||
| 2499 | |||
| 2500 | log.debug("{s}({}, {}) result: {}", .{ @tagName(zir_tags[inst]), lhs_val, rhs_val, value }); | ||
| 2501 | |||
| 2502 | return sema.mod.constInst(sema.arena, src, .{ | ||
| 2503 | .ty = scalar_type, | ||
| 2504 | .val = value, | ||
| 2505 | }); | ||
| 2472 | } | 2506 | } |
| 2473 | } | 2507 | } |
| 2474 | 2508 | ||
| 2475 | try sema.requireRuntimeBlock(block, src); | 2509 | try sema.requireRuntimeBlock(block, src); |
| 2476 | const ir_tag: Inst.Tag = switch (inst.base.tag) { | 2510 | const ir_tag: Inst.Tag = switch (zir_tags[inst]) { |
| 2477 | .add => .add, | 2511 | .add => .add, |
| 2478 | .addwrap => .addwrap, | 2512 | .addwrap => .addwrap, |
| 2479 | .sub => .sub, | 2513 | .sub => .sub, |
| 2480 | .subwrap => .subwrap, | 2514 | .subwrap => .subwrap, |
| 2481 | .mul => .mul, | 2515 | .mul => .mul, |
| 2482 | .mulwrap => .mulwrap, | 2516 | .mulwrap => .mulwrap, |
| 2483 | else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(inst.base.tag)}), | 2517 | else => return sema.mod.fail(&block.base, src, "TODO implement arithmetic for operand '{s}''", .{@tagName(zir_tags[inst])}), |
| 2484 | }; | 2518 | }; |
| 2485 | 2519 | ||
| 2486 | return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs); | 2520 | return block.addBinOp(src, scalar_type, ir_tag, casted_lhs, casted_rhs); |
| 2487 | } | 2521 | } |
| 2488 | 2522 | ||
| 2489 | /// Analyzes operands that are known at comptime | ||
| 2490 | fn analyzeInstComptimeOp( | ||
| 2491 | sema: *Sema, | ||
| 2492 | block: *Scope.Block, | ||
| 2493 | res_type: Type, | ||
| 2494 | inst: zir.Inst.Index, | ||
| 2495 | lhs_val: Value, | ||
| 2496 | rhs_val: Value, | ||
| 2497 | ) InnerError!*Inst { | ||
| 2498 | if (true) @panic("TODO rework analyzeInstComptimeOp for zir-memory-layout"); | ||
| 2499 | |||
| 2500 | // incase rhs is 0, simply return lhs without doing any calculations | ||
| 2501 | // TODO Once division is implemented we should throw an error when dividing by 0. | ||
| 2502 | if (rhs_val.compareWithZero(.eq)) { | ||
| 2503 | return sema.mod.constInst(sema.arena, inst.base.src, .{ | ||
| 2504 | .ty = res_type, | ||
| 2505 | .val = lhs_val, | ||
| 2506 | }); | ||
| 2507 | } | ||
| 2508 | const is_int = res_type.isInt() or res_type.zigTypeTag() == .ComptimeInt; | ||
| 2509 | |||
| 2510 | const value = switch (inst.base.tag) { | ||
| 2511 | .add => blk: { | ||
| 2512 | const val = if (is_int) | ||
| 2513 | try Module.intAdd(sema.arena, lhs_val, rhs_val) | ||
| 2514 | else | ||
| 2515 | try Module.floatAdd(sema.arena, res_type, inst.base.src, lhs_val, rhs_val); | ||
| 2516 | break :blk val; | ||
| 2517 | }, | ||
| 2518 | .sub => blk: { | ||
| 2519 | const val = if (is_int) | ||
| 2520 | try Module.intSub(sema.arena, lhs_val, rhs_val) | ||
| 2521 | else | ||
| 2522 | try Module.floatSub(sema.arena, res_type, inst.base.src, lhs_val, rhs_val); | ||
| 2523 | break :blk val; | ||
| 2524 | }, | ||
| 2525 | else => return sema.mod.fail(&block.base, inst.base.src, "TODO Implement arithmetic operand '{s}'", .{@tagName(inst.base.tag)}), | ||
| 2526 | }; | ||
| 2527 | |||
| 2528 | log.debug("{s}({}, {}) result: {}", .{ @tagName(inst.base.tag), lhs_val, rhs_val, value }); | ||
| 2529 | |||
| 2530 | return sema.mod.constInst(sema.arena, inst.base.src, .{ | ||
| 2531 | .ty = res_type, | ||
| 2532 | .val = value, | ||
| 2533 | }); | ||
| 2534 | } | ||
| 2535 | |||
| 2536 | fn zirDerefNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 2523 | fn zirDerefNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { |
| 2537 | const tracy = trace(@src()); | 2524 | const tracy = trace(@src()); |
| 2538 | defer tracy.end(); | 2525 | defer tracy.end(); |
src/astgen.zig+15-14| ... | @@ -3000,19 +3000,18 @@ fn as( | ... | @@ -3000,19 +3000,18 @@ fn as( |
| 3000 | lhs: ast.Node.Index, | 3000 | lhs: ast.Node.Index, |
| 3001 | rhs: ast.Node.Index, | 3001 | rhs: ast.Node.Index, |
| 3002 | ) InnerError!zir.Inst.Ref { | 3002 | ) InnerError!zir.Inst.Ref { |
| 3003 | if (true) @panic("TODO update for zir-memory-layout"); | ||
| 3004 | const dest_type = try typeExpr(mod, scope, lhs); | 3003 | const dest_type = try typeExpr(mod, scope, lhs); |
| 3005 | switch (rl) { | 3004 | switch (rl) { |
| 3006 | .none, .discard, .ref, .ty => { | 3005 | .none, .discard, .ref, .ty => { |
| 3007 | const result = try expr(mod, scope, .{ .ty = dest_type }, rhs); | 3006 | const result = try expr(mod, scope, .{ .ty = dest_type }, rhs); |
| 3008 | return rvalue(mod, scope, rl, result); | 3007 | return rvalue(mod, scope, rl, result, node); |
| 3009 | }, | 3008 | }, |
| 3010 | 3009 | ||
| 3011 | .ptr => |result_ptr| { | 3010 | .ptr => |result_ptr| { |
| 3012 | return asRlPtr(mod, scope, rl, src, result_ptr, rhs, dest_type); | 3011 | return asRlPtr(mod, scope, rl, result_ptr, rhs, dest_type); |
| 3013 | }, | 3012 | }, |
| 3014 | .block_ptr => |block_scope| { | 3013 | .block_ptr => |block_scope| { |
| 3015 | return asRlPtr(mod, scope, rl, src, block_scope.rl_ptr.?, rhs, dest_type); | 3014 | return asRlPtr(mod, scope, rl, block_scope.rl_ptr, rhs, dest_type); |
| 3016 | }, | 3015 | }, |
| 3017 | 3016 | ||
| 3018 | .bitcasted_ptr => |bitcasted_ptr| { | 3017 | .bitcasted_ptr => |bitcasted_ptr| { |
| ... | @@ -3030,7 +3029,6 @@ fn asRlPtr( | ... | @@ -3030,7 +3029,6 @@ fn asRlPtr( |
| 3030 | mod: *Module, | 3029 | mod: *Module, |
| 3031 | scope: *Scope, | 3030 | scope: *Scope, |
| 3032 | rl: ResultLoc, | 3031 | rl: ResultLoc, |
| 3033 | src: usize, | ||
| 3034 | result_ptr: zir.Inst.Ref, | 3032 | result_ptr: zir.Inst.Ref, |
| 3035 | operand_node: ast.Node.Index, | 3033 | operand_node: ast.Node.Index, |
| 3036 | dest_type: zir.Inst.Ref, | 3034 | dest_type: zir.Inst.Ref, |
| ... | @@ -3038,32 +3036,35 @@ fn asRlPtr( | ... | @@ -3038,32 +3036,35 @@ fn asRlPtr( |
| 3038 | // Detect whether this expr() call goes into rvalue() to store the result into the | 3036 | // Detect whether this expr() call goes into rvalue() to store the result into the |
| 3039 | // result location. If it does, elide the coerce_result_ptr instruction | 3037 | // result location. If it does, elide the coerce_result_ptr instruction |
| 3040 | // as well as the store instruction, instead passing the result as an rvalue. | 3038 | // as well as the store instruction, instead passing the result as an rvalue. |
| 3039 | const parent_gz = scope.getGenZir(); | ||
| 3040 | |||
| 3041 | var as_scope: Scope.GenZir = .{ | 3041 | var as_scope: Scope.GenZir = .{ |
| 3042 | .parent = scope, | 3042 | .parent = scope, |
| 3043 | .decl = scope.ownerDecl().?, | 3043 | .zir_code = parent_gz.zir_code, |
| 3044 | .arena = scope.arena(), | ||
| 3045 | .force_comptime = scope.isComptime(), | 3044 | .force_comptime = scope.isComptime(), |
| 3046 | .instructions = .{}, | 3045 | .instructions = .{}, |
| 3047 | }; | 3046 | }; |
| 3048 | defer as_scope.instructions.deinit(mod.gpa); | 3047 | defer as_scope.instructions.deinit(mod.gpa); |
| 3049 | 3048 | ||
| 3050 | as_scope.rl_ptr = try addZIRBinOp(mod, &as_scope.base, src, .coerce_result_ptr, dest_type, result_ptr); | 3049 | as_scope.rl_ptr = try as_scope.addBin(.coerce_result_ptr, dest_type, result_ptr); |
| 3051 | const result = try expr(mod, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node); | 3050 | const result = try expr(mod, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node); |
| 3052 | const parent_zir = &scope.getGenZir().instructions; | 3051 | const parent_zir = &parent_gz.instructions; |
| 3053 | if (as_scope.rvalue_rl_count == 1) { | 3052 | if (as_scope.rvalue_rl_count == 1) { |
| 3054 | // Busted! This expression didn't actually need a pointer. | 3053 | // Busted! This expression didn't actually need a pointer. |
| 3054 | const zir_tags = parent_gz.zir_code.instructions.items(.tag); | ||
| 3055 | const zir_datas = parent_gz.zir_code.instructions.items(.data); | ||
| 3055 | const expected_len = parent_zir.items.len + as_scope.instructions.items.len - 2; | 3056 | const expected_len = parent_zir.items.len + as_scope.instructions.items.len - 2; |
| 3056 | try parent_zir.ensureCapacity(mod.gpa, expected_len); | 3057 | try parent_zir.ensureCapacity(mod.gpa, expected_len); |
| 3057 | for (as_scope.instructions.items) |src_inst| { | 3058 | for (as_scope.instructions.items) |src_inst| { |
| 3058 | if (src_inst == as_scope.rl_ptr.?) continue; | 3059 | if (src_inst == as_scope.rl_ptr) continue; |
| 3059 | if (src_inst.castTag(.store_to_block_ptr)) |store| { | 3060 | if (zir_tags[src_inst] == .store_to_block_ptr) { |
| 3060 | if (store.positionals.lhs == as_scope.rl_ptr.?) continue; | 3061 | if (zir_datas[src_inst].bin.lhs == as_scope.rl_ptr) continue; |
| 3061 | } | 3062 | } |
| 3062 | parent_zir.appendAssumeCapacity(src_inst); | 3063 | parent_zir.appendAssumeCapacity(src_inst); |
| 3063 | } | 3064 | } |
| 3064 | assert(parent_zir.items.len == expected_len); | 3065 | assert(parent_zir.items.len == expected_len); |
| 3065 | const casted_result = try addZIRBinOp(mod, scope, dest_type.src, .as, dest_type, result); | 3066 | const casted_result = try parent_gz.addBin(.as, dest_type, result); |
| 3066 | return rvalue(mod, scope, rl, casted_result); | 3067 | return rvalue(mod, scope, rl, casted_result, operand_node); |
| 3067 | } else { | 3068 | } else { |
| 3068 | try parent_zir.appendSlice(mod.gpa, as_scope.instructions.items); | 3069 | try parent_zir.appendSlice(mod.gpa, as_scope.instructions.items); |
| 3069 | return result; | 3070 | return result; |
src/zir.zig+34-21| ... | @@ -524,6 +524,7 @@ pub const Inst = struct { | ... | @@ -524,6 +524,7 @@ pub const Inst = struct { |
| 524 | cmp_neq, | 524 | cmp_neq, |
| 525 | /// Coerces a result location pointer to a new element type. It is evaluated "backwards"- | 525 | /// Coerces a result location pointer to a new element type. It is evaluated "backwards"- |
| 526 | /// as type coercion from the new element type to the old element type. | 526 | /// as type coercion from the new element type to the old element type. |
| 527 | /// Uses the `bin` union field. | ||
| 527 | /// LHS is destination element type, RHS is result pointer. | 528 | /// LHS is destination element type, RHS is result pointer. |
| 528 | coerce_result_ptr, | 529 | coerce_result_ptr, |
| 529 | /// Emit an error message and fail compilation. | 530 | /// Emit an error message and fail compilation. |
| ... | @@ -1327,33 +1328,12 @@ const Writer = struct { | ... | @@ -1327,33 +1328,12 @@ const Writer = struct { |
| 1327 | const tag = tags[inst]; | 1328 | const tag = tags[inst]; |
| 1328 | try stream.print("= {s}(", .{@tagName(tags[inst])}); | 1329 | try stream.print("= {s}(", .{@tagName(tags[inst])}); |
| 1329 | switch (tag) { | 1330 | switch (tag) { |
| 1330 | .add, | ||
| 1331 | .addwrap, | ||
| 1332 | .array_cat, | ||
| 1333 | .array_mul, | ||
| 1334 | .mul, | ||
| 1335 | .mulwrap, | ||
| 1336 | .sub, | ||
| 1337 | .subwrap, | ||
| 1338 | .array_type, | 1331 | .array_type, |
| 1339 | .bit_and, | 1332 | .bit_and, |
| 1340 | .bit_or, | 1333 | .bit_or, |
| 1341 | .as, | 1334 | .as, |
| 1342 | .bool_and, | ||
| 1343 | .bool_or, | ||
| 1344 | .@"break", | 1335 | .@"break", |
| 1345 | .cmp_lt, | ||
| 1346 | .cmp_lte, | ||
| 1347 | .cmp_eq, | ||
| 1348 | .cmp_gte, | ||
| 1349 | .cmp_gt, | ||
| 1350 | .cmp_neq, | ||
| 1351 | .coerce_result_ptr, | 1336 | .coerce_result_ptr, |
| 1352 | .div, | ||
| 1353 | .mod_rem, | ||
| 1354 | .shl, | ||
| 1355 | .shr, | ||
| 1356 | .xor, | ||
| 1357 | .elem_ptr, | 1337 | .elem_ptr, |
| 1358 | .elem_val, | 1338 | .elem_val, |
| 1359 | .intcast, | 1339 | .intcast, |
| ... | @@ -1447,6 +1427,29 @@ const Writer = struct { | ... | @@ -1447,6 +1427,29 @@ const Writer = struct { |
| 1447 | .suspend_block, | 1427 | .suspend_block, |
| 1448 | => try self.writePlNode(stream, inst), | 1428 | => try self.writePlNode(stream, inst), |
| 1449 | 1429 | ||
| 1430 | .add, | ||
| 1431 | .addwrap, | ||
| 1432 | .array_cat, | ||
| 1433 | .array_mul, | ||
| 1434 | .mul, | ||
| 1435 | .mulwrap, | ||
| 1436 | .sub, | ||
| 1437 | .subwrap, | ||
| 1438 | .bool_and, | ||
| 1439 | .bool_or, | ||
| 1440 | .cmp_lt, | ||
| 1441 | .cmp_lte, | ||
| 1442 | .cmp_eq, | ||
| 1443 | .cmp_gte, | ||
| 1444 | .cmp_gt, | ||
| 1445 | .cmp_neq, | ||
| 1446 | .div, | ||
| 1447 | .mod_rem, | ||
| 1448 | .shl, | ||
| 1449 | .shr, | ||
| 1450 | .xor, | ||
| 1451 | => try self.writePlNodeBin(stream, inst), | ||
| 1452 | |||
| 1450 | .as_node => try self.writeAs(stream, inst), | 1453 | .as_node => try self.writeAs(stream, inst), |
| 1451 | 1454 | ||
| 1452 | .breakpoint, | 1455 | .breakpoint, |
| ... | @@ -1589,6 +1592,16 @@ const Writer = struct { | ... | @@ -1589,6 +1592,16 @@ const Writer = struct { |
| 1589 | try self.writeSrc(stream, inst_data.src()); | 1592 | try self.writeSrc(stream, inst_data.src()); |
| 1590 | } | 1593 | } |
| 1591 | 1594 | ||
| 1595 | fn writePlNodeBin(self: *Writer, stream: anytype, inst: Inst.Index) !void { | ||
| 1596 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | ||
| 1597 | const extra = self.code.extraData(Inst.Bin, inst_data.payload_index).data; | ||
| 1598 | try self.writeInstRef(stream, extra.lhs); | ||
| 1599 | try stream.writeAll(", "); | ||
| 1600 | try self.writeInstRef(stream, extra.rhs); | ||
| 1601 | try stream.writeAll(") "); | ||
| 1602 | try self.writeSrc(stream, inst_data.src()); | ||
| 1603 | } | ||
| 1604 | |||
| 1592 | fn writeAs(self: *Writer, stream: anytype, inst: Inst.Index) !void { | 1605 | fn writeAs(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 1593 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | 1606 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 1594 | const extra = self.code.extraData(Inst.As, inst_data.payload_index).data; | 1607 | const extra = self.code.extraData(Inst.As, inst_data.payload_index).data; |