| author | |
| committer | |
| log | 90bce11f62aa2f246b9bce5bc49069a3faf7ec9a |
| tree | 1489691423543c9d3d5c65dcefa7c8cd6ae59354 |
| parent | 2682b41da54e9b652dc570140d52f85418d6b89d |
11 files changed, 75 insertions(+), 7 deletions(-)
src/Air.zig+5| ... | @@ -580,6 +580,10 @@ pub const Inst = struct { | ... | @@ -580,6 +580,10 @@ pub const Inst = struct { |
| 580 | /// Uses the `ty_pl` field. | 580 | /// Uses the `ty_pl` field. |
| 581 | field_parent_ptr, | 581 | field_parent_ptr, |
| 582 | 582 | ||
| 583 | /// Implements @frameAddress builtin. | ||
| 584 | /// Uses the `ty` field. | ||
| 585 | frame_address, | ||
| 586 | |||
| 583 | pub fn fromCmpOp(op: std.math.CompareOperator) Tag { | 587 | pub fn fromCmpOp(op: std.math.CompareOperator) Tag { |
| 584 | return switch (op) { | 588 | return switch (op) { |
| 585 | .lt => .cmp_lt, | 589 | .lt => .cmp_lt, |
| ... | @@ -939,6 +943,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { | ... | @@ -939,6 +943,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 939 | .ptrtoint, | 943 | .ptrtoint, |
| 940 | .slice_len, | 944 | .slice_len, |
| 941 | .ret_addr, | 945 | .ret_addr, |
| 946 | .frame_address, | ||
| 942 | => return Type.initTag(.usize), | 947 | => return Type.initTag(.usize), |
| 943 | 948 | ||
| 944 | .bool_to_int => return Type.initTag(.u1), | 949 | .bool_to_int => return Type.initTag(.u1), |
src/Liveness.zig+1| ... | @@ -317,6 +317,7 @@ fn analyzeInst( | ... | @@ -317,6 +317,7 @@ fn analyzeInst( |
| 317 | .unreach, | 317 | .unreach, |
| 318 | .fence, | 318 | .fence, |
| 319 | .ret_addr, | 319 | .ret_addr, |
| 320 | .frame_address, | ||
| 320 | => return trackOperands(a, new_set, inst, main_tomb, .{ .none, .none, .none }), | 321 | => return trackOperands(a, new_set, inst, main_tomb, .{ .none, .none, .none }), |
| 321 | 322 | ||
| 322 | .not, | 323 | .not, |
src/Sema.zig+11-7| ... | @@ -8078,9 +8078,10 @@ fn analyzeTupleCat( | ... | @@ -8078,9 +8078,10 @@ fn analyzeTupleCat( |
| 8078 | if (dest_fields == 0) { | 8078 | if (dest_fields == 0) { |
| 8079 | return sema.addConstant(Type.initTag(.empty_struct_literal), Value.initTag(.empty_struct_value)); | 8079 | return sema.addConstant(Type.initTag(.empty_struct_literal), Value.initTag(.empty_struct_value)); |
| 8080 | } | 8080 | } |
| 8081 | const final_len = try sema.usizeCast(block, rhs_src, dest_fields); | ||
| 8081 | 8082 | ||
| 8082 | const types = try sema.arena.alloc(Type, dest_fields); | 8083 | const types = try sema.arena.alloc(Type, final_len); |
| 8083 | const values = try sema.arena.alloc(Value, dest_fields); | 8084 | const values = try sema.arena.alloc(Value, final_len); |
| 8084 | 8085 | ||
| 8085 | const opt_runtime_src = rs: { | 8086 | const opt_runtime_src = rs: { |
| 8086 | var runtime_src: ?LazySrcLoc = null; | 8087 | var runtime_src: ?LazySrcLoc = null; |
| ... | @@ -8116,7 +8117,7 @@ fn analyzeTupleCat( | ... | @@ -8116,7 +8117,7 @@ fn analyzeTupleCat( |
| 8116 | 8117 | ||
| 8117 | try sema.requireRuntimeBlock(block, runtime_src); | 8118 | try sema.requireRuntimeBlock(block, runtime_src); |
| 8118 | 8119 | ||
| 8119 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_fields); | 8120 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len); |
| 8120 | for (lhs_tuple.types) |_, i| { | 8121 | for (lhs_tuple.types) |_, i| { |
| 8121 | const operand_src = lhs_src; // TODO better source location | 8122 | const operand_src = lhs_src; // TODO better source location |
| 8122 | element_refs[i] = try sema.tupleFieldValByIndex(block, operand_src, lhs, @intCast(u32, i), lhs_ty); | 8123 | element_refs[i] = try sema.tupleFieldValByIndex(block, operand_src, lhs, @intCast(u32, i), lhs_ty); |
| ... | @@ -8261,9 +8262,10 @@ fn analyzeTupleMul( | ... | @@ -8261,9 +8262,10 @@ fn analyzeTupleMul( |
| 8261 | if (final_len_u64 == 0) { | 8262 | if (final_len_u64 == 0) { |
| 8262 | return sema.addConstant(Type.initTag(.empty_struct_literal), Value.initTag(.empty_struct_value)); | 8263 | return sema.addConstant(Type.initTag(.empty_struct_literal), Value.initTag(.empty_struct_value)); |
| 8263 | } | 8264 | } |
| 8265 | const final_len = try sema.usizeCast(block, rhs_src, final_len_u64); | ||
| 8264 | 8266 | ||
| 8265 | const types = try sema.arena.alloc(Type, final_len_u64); | 8267 | const types = try sema.arena.alloc(Type, final_len); |
| 8266 | const values = try sema.arena.alloc(Value, final_len_u64); | 8268 | const values = try sema.arena.alloc(Value, final_len); |
| 8267 | 8269 | ||
| 8268 | const opt_runtime_src = rs: { | 8270 | const opt_runtime_src = rs: { |
| 8269 | var runtime_src: ?LazySrcLoc = null; | 8271 | var runtime_src: ?LazySrcLoc = null; |
| ... | @@ -8295,7 +8297,7 @@ fn analyzeTupleMul( | ... | @@ -8295,7 +8297,7 @@ fn analyzeTupleMul( |
| 8295 | 8297 | ||
| 8296 | try sema.requireRuntimeBlock(block, runtime_src); | 8298 | try sema.requireRuntimeBlock(block, runtime_src); |
| 8297 | 8299 | ||
| 8298 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len_u64); | 8300 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len); |
| 8299 | for (operand_tuple.types) |_, i| { | 8301 | for (operand_tuple.types) |_, i| { |
| 8300 | const operand_src = lhs_src; // TODO better source location | 8302 | const operand_src = lhs_src; // TODO better source location |
| 8301 | element_refs[i] = try sema.tupleFieldValByIndex(block, operand_src, operand, @intCast(u32, i), operand_ty); | 8303 | element_refs[i] = try sema.tupleFieldValByIndex(block, operand_src, operand, @intCast(u32, i), operand_ty); |
| ... | @@ -11893,7 +11895,8 @@ fn zirFrameAddress( | ... | @@ -11893,7 +11895,8 @@ fn zirFrameAddress( |
| 11893 | extended: Zir.Inst.Extended.InstData, | 11895 | extended: Zir.Inst.Extended.InstData, |
| 11894 | ) CompileError!Air.Inst.Ref { | 11896 | ) CompileError!Air.Inst.Ref { |
| 11895 | const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; | 11897 | const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; |
| 11896 | return sema.fail(block, src, "TODO: Sema.zirFrameAddress", .{}); | 11898 | try sema.requireFunctionBlock(block, src); |
| 11899 | return block.addTy(.frame_address, Type.@"usize"); | ||
| 11897 | } | 11900 | } |
| 11898 | 11901 | ||
| 11899 | fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 11902 | fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -19257,6 +19260,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr | ... | @@ -19257,6 +19260,7 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr |
| 19257 | /// Used to convert a u64 value to a usize value, emitting a compile error if the number | 19260 | /// Used to convert a u64 value to a usize value, emitting a compile error if the number |
| 19258 | /// is too big to fit. | 19261 | /// is too big to fit. |
| 19259 | fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError!usize { | 19262 | fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError!usize { |
| 19263 | if (@bitSizeOf(u64) <= @bitSizeOf(usize)) return int; | ||
| 19260 | return std.math.cast(usize, int) catch |err| switch (err) { | 19264 | return std.math.cast(usize, int) catch |err| switch (err) { |
| 19261 | error.Overflow => return sema.fail(block, src, "expression produces integer value {d} which is too big for this compiler implementation to handle", .{int}), | 19265 | error.Overflow => return sema.fail(block, src, "expression produces integer value {d} which is too big for this compiler implementation to handle", .{int}), |
| 19262 | }; | 19266 | }; |
src/arch/aarch64/CodeGen.zig+9| ... | @@ -670,6 +670,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -670,6 +670,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 670 | .wrap_optional => try self.airWrapOptional(inst), | 670 | .wrap_optional => try self.airWrapOptional(inst), |
| 671 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), | 671 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 672 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), | 672 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 673 | |||
| 674 | .frame_address => try self.airFrameAddress(inst), | ||
| 673 | // zig fmt: on | 675 | // zig fmt: on |
| 674 | } | 676 | } |
| 675 | 677 | ||
| ... | @@ -1517,6 +1519,13 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1517,6 +1519,13 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 1517 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1519 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1518 | } | 1520 | } |
| 1519 | 1521 | ||
| 1522 | fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { | ||
| 1523 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | ||
| 1524 | const extra = self.air.extraData(Air.StructField, ty_pl.payload).data; | ||
| 1525 | _ = extra; | ||
| 1526 | return self.fail("TODO implement codegen airFrameAddress", .{}); | ||
| 1527 | } | ||
| 1528 | |||
| 1520 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | 1529 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1521 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1530 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1522 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch}); | 1531 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch}); |
src/arch/arm/CodeGen.zig+9| ... | @@ -656,6 +656,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -656,6 +656,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 656 | .wrap_optional => try self.airWrapOptional(inst), | 656 | .wrap_optional => try self.airWrapOptional(inst), |
| 657 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), | 657 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 658 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), | 658 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 659 | |||
| 660 | .frame_address => try self.airFrameAddress(inst), | ||
| 659 | // zig fmt: on | 661 | // zig fmt: on |
| 660 | } | 662 | } |
| 661 | 663 | ||
| ... | @@ -1272,6 +1274,13 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1272,6 +1274,13 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 1272 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1274 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1273 | } | 1275 | } |
| 1274 | 1276 | ||
| 1277 | fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { | ||
| 1278 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | ||
| 1279 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | ||
| 1280 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress", .{}); | ||
| 1281 | return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none }); | ||
| 1282 | } | ||
| 1283 | |||
| 1275 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | 1284 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1276 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1285 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1277 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1286 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
src/arch/riscv64/CodeGen.zig+8| ... | @@ -641,6 +641,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -641,6 +641,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 641 | .wrap_optional => try self.airWrapOptional(inst), | 641 | .wrap_optional => try self.airWrapOptional(inst), |
| 642 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), | 642 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 643 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), | 643 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 644 | |||
| 645 | .frame_address => try self.airFrameAddress(inst), | ||
| 644 | // zig fmt: on | 646 | // zig fmt: on |
| 645 | } | 647 | } |
| 646 | if (std.debug.runtime_safety) { | 648 | if (std.debug.runtime_safety) { |
| ... | @@ -1103,6 +1105,12 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1103,6 +1105,12 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 1103 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1105 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1104 | } | 1106 | } |
| 1105 | 1107 | ||
| 1108 | fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { | ||
| 1109 | _ = self; | ||
| 1110 | _ = inst; | ||
| 1111 | return self.fail("TODO implement codegen airFrameAddress", .{}); | ||
| 1112 | } | ||
| 1113 | |||
| 1106 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | 1114 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1107 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1115 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1108 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch}); | 1116 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch}); |
src/arch/wasm/CodeGen.zig+1| ... | @@ -1726,6 +1726,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1726,6 +1726,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1726 | .error_name, | 1726 | .error_name, |
| 1727 | .errunion_payload_ptr_set, | 1727 | .errunion_payload_ptr_set, |
| 1728 | .field_parent_ptr, | 1728 | .field_parent_ptr, |
| 1729 | .frame_address, | ||
| 1729 | 1730 | ||
| 1730 | // For these 4, probably best to wait until https://github.com/ziglang/zig/issues/10248 | 1731 | // For these 4, probably best to wait until https://github.com/ziglang/zig/issues/10248 |
| 1731 | // is implemented in the frontend before implementing them here in the wasm backend. | 1732 | // is implemented in the frontend before implementing them here in the wasm backend. |
src/arch/x86_64/CodeGen.zig+11| ... | @@ -753,6 +753,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -753,6 +753,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 753 | .wrap_optional => try self.airWrapOptional(inst), | 753 | .wrap_optional => try self.airWrapOptional(inst), |
| 754 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), | 754 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 755 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), | 755 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 756 | |||
| 757 | .frame_address => try self.airFrameAddress(inst), | ||
| 756 | // zig fmt: on | 758 | // zig fmt: on |
| 757 | } | 759 | } |
| 758 | 760 | ||
| ... | @@ -1865,6 +1867,15 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1865,6 +1867,15 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void { |
| 1865 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 1867 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1866 | } | 1868 | } |
| 1867 | 1869 | ||
| 1870 | fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { | ||
| 1871 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | ||
| 1872 | const result: MCValue = if (self.liveness.isUnused(inst)) | ||
| 1873 | .dead | ||
| 1874 | else | ||
| 1875 | return self.fail("TODO implement airFrameAddress for {}", .{self.target.cpu.arch}); | ||
| 1876 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | ||
| 1877 | } | ||
| 1878 | |||
| 1868 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | 1879 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { |
| 1869 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 1880 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 1870 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { | 1881 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
src/codegen/c.zig+7| ... | @@ -1757,6 +1757,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1757,6 +1757,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1757 | .wrap_errunion_payload => try airWrapErrUnionPay(f, inst), | 1757 | .wrap_errunion_payload => try airWrapErrUnionPay(f, inst), |
| 1758 | .wrap_errunion_err => try airWrapErrUnionErr(f, inst), | 1758 | .wrap_errunion_err => try airWrapErrUnionErr(f, inst), |
| 1759 | .errunion_payload_ptr_set => try airErrUnionPayloadPtrSet(f, inst), | 1759 | .errunion_payload_ptr_set => try airErrUnionPayloadPtrSet(f, inst), |
| 1760 | |||
| 1761 | .frame_address => try airFrameAddress(f, inst), | ||
| 1760 | // zig fmt: on | 1762 | // zig fmt: on |
| 1761 | }; | 1763 | }; |
| 1762 | switch (result_value) { | 1764 | switch (result_value) { |
| ... | @@ -3198,6 +3200,11 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3198,6 +3200,11 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3198 | return f.fail("TODO: C backend: implement airErrUnionPayloadPtrSet", .{}); | 3200 | return f.fail("TODO: C backend: implement airErrUnionPayloadPtrSet", .{}); |
| 3199 | } | 3201 | } |
| 3200 | 3202 | ||
| 3203 | fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue { | ||
| 3204 | _ = inst; | ||
| 3205 | return f.fail("TODO: C backend: implement airFrameAddress", .{}); | ||
| 3206 | } | ||
| 3207 | |||
| 3201 | fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | 3208 | fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3202 | if (f.liveness.isUnused(inst)) | 3209 | if (f.liveness.isUnused(inst)) |
| 3203 | return CValue.none; | 3210 | return CValue.none; |
src/codegen/llvm.zig+12| ... | @@ -2214,6 +2214,8 @@ pub const FuncGen = struct { | ... | @@ -2214,6 +2214,8 @@ pub const FuncGen = struct { |
| 2214 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), | 2214 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 2215 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), | 2215 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 2216 | 2216 | ||
| 2217 | .frame_address => try self.airFrameAddress(inst), | ||
| 2218 | |||
| 2217 | .constant => unreachable, | 2219 | .constant => unreachable, |
| 2218 | .const_ty => unreachable, | 2220 | .const_ty => unreachable, |
| 2219 | .unreach => self.airUnreach(inst), | 2221 | .unreach => self.airUnreach(inst), |
| ... | @@ -3339,6 +3341,16 @@ pub const FuncGen = struct { | ... | @@ -3339,6 +3341,16 @@ pub const FuncGen = struct { |
| 3339 | return partial; | 3341 | return partial; |
| 3340 | } | 3342 | } |
| 3341 | 3343 | ||
| 3344 | fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | ||
| 3345 | if (self.liveness.isUnused(inst)) return null; | ||
| 3346 | |||
| 3347 | const llvm_i32 = try self.dg.llvmType(Type.initTag(.i32)); | ||
| 3348 | const llvm_fn = self.getIntrinsic("llvm.frameaddress", &.{llvm_i32}); | ||
| 3349 | const ptr_val = self.builder.buildCall(llvm_fn, &[_]*const llvm.Value{llvm_i32.constNull()}, 1, .Fast, .Auto, ""); | ||
| 3350 | const llvm_usize = try self.dg.llvmType(Type.usize); | ||
| 3351 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); | ||
| 3352 | } | ||
| 3353 | |||
| 3342 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 3354 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| 3343 | if (self.liveness.isUnused(inst)) return null; | 3355 | if (self.liveness.isUnused(inst)) return null; |
| 3344 | 3356 |
src/print_air.zig+1| ... | @@ -177,6 +177,7 @@ const Writer = struct { | ... | @@ -177,6 +177,7 @@ const Writer = struct { |
| 177 | .alloc, | 177 | .alloc, |
| 178 | .ret_ptr, | 178 | .ret_ptr, |
| 179 | .arg, | 179 | .arg, |
| 180 | .frame_address, | ||
| 180 | => try w.writeTy(s, inst), | 181 | => try w.writeTy(s, inst), |
| 181 | 182 | ||
| 182 | .not, | 183 | .not, |