authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-28 13:38:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-28 13:38:33-07:00
logd5100dc81555f0e8197d5f189b1432070e8d72dd
tree96de992b22f7cfc4bcb672892c64fb2cdf621913
parent90bce11f62aa2f246b9bce5bc49069a3faf7ec9a

stage2: fix frame_address AIR instruction

Various places were assuming different union tags. Now it is consistently a no-op instruction, just like the similar instruction ret_addr.

11 files changed, 87 insertions(+), 96 deletions(-)

src/Air.zig+4-5
...@@ -218,6 +218,9 @@ pub const Inst = struct {...@@ -218,6 +218,9 @@ pub const Inst = struct {
218 /// Yields the return address of the current function.218 /// Yields the return address of the current function.
219 /// Uses the `no_op` field.219 /// Uses the `no_op` field.
220 ret_addr,220 ret_addr,
221 /// Implements @frameAddress builtin.
222 /// Uses the `no_op` field.
223 frame_addr,
221 /// Function call.224 /// Function call.
222 /// Result type is the return type of the function being called.225 /// Result type is the return type of the function being called.
223 /// Uses the `pl_op` field with the `Call` payload. operand is the callee.226 /// Uses the `pl_op` field with the `Call` payload. operand is the callee.
...@@ -580,10 +583,6 @@ pub const Inst = struct {...@@ -580,10 +583,6 @@ pub const Inst = struct {
580 /// Uses the `ty_pl` field.583 /// Uses the `ty_pl` field.
581 field_parent_ptr,584 field_parent_ptr,
582585
583 /// Implements @frameAddress builtin.
584 /// Uses the `ty` field.
585 frame_address,
586
587 pub fn fromCmpOp(op: std.math.CompareOperator) Tag {586 pub fn fromCmpOp(op: std.math.CompareOperator) Tag {
588 return switch (op) {587 return switch (op) {
589 .lt => .cmp_lt,588 .lt => .cmp_lt,
...@@ -943,7 +942,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -943,7 +942,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
943 .ptrtoint,942 .ptrtoint,
944 .slice_len,943 .slice_len,
945 .ret_addr,944 .ret_addr,
946 .frame_address,945 .frame_addr,
947 => return Type.initTag(.usize),946 => return Type.initTag(.usize),
948947
949 .bool_to_int => return Type.initTag(.u1),948 .bool_to_int => return Type.initTag(.u1),
src/Liveness.zig+1-1
...@@ -317,7 +317,7 @@ fn analyzeInst(...@@ -317,7 +317,7 @@ fn analyzeInst(
317 .unreach,317 .unreach,
318 .fence,318 .fence,
319 .ret_addr,319 .ret_addr,
320 .frame_address,320 .frame_addr,
321 => return trackOperands(a, new_set, inst, main_tomb, .{ .none, .none, .none }),321 => return trackOperands(a, new_set, inst, main_tomb, .{ .none, .none, .none }),
322322
323 .not,323 .not,
src/Sema.zig+10-13
...@@ -9993,14 +9993,21 @@ fn zirRetAddr(...@@ -9993,14 +9993,21 @@ fn zirRetAddr(
9993 block: *Block,9993 block: *Block,
9994 extended: Zir.Inst.Extended.InstData,9994 extended: Zir.Inst.Extended.InstData,
9995) CompileError!Air.Inst.Ref {9995) CompileError!Air.Inst.Ref {
9996 const tracy = trace(@src());
9997 defer tracy.end();
9998
9999 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };9996 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
10000 try sema.requireRuntimeBlock(block, src);9997 try sema.requireRuntimeBlock(block, src);
10001 return try block.addNoOp(.ret_addr);9998 return try block.addNoOp(.ret_addr);
10002}9999}
1000310000
10001fn zirFrameAddress(
10002 sema: *Sema,
10003 block: *Block,
10004 extended: Zir.Inst.Extended.InstData,
10005) CompileError!Air.Inst.Ref {
10006 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
10007 try sema.requireRuntimeBlock(block, src);
10008 return try block.addNoOp(.frame_addr);
10009}
10010
10004fn zirBuiltinSrc(10011fn zirBuiltinSrc(
10005 sema: *Sema,10012 sema: *Sema,
10006 block: *Block,10013 block: *Block,
...@@ -11889,16 +11896,6 @@ fn zirFrame(...@@ -11889,16 +11896,6 @@ fn zirFrame(
11889 return sema.fail(block, src, "TODO: Sema.zirFrame", .{});11896 return sema.fail(block, src, "TODO: Sema.zirFrame", .{});
11890}11897}
1189111898
11892fn zirFrameAddress(
11893 sema: *Sema,
11894 block: *Block,
11895 extended: Zir.Inst.Extended.InstData,
11896) CompileError!Air.Inst.Ref {
11897 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
11898 try sema.requireFunctionBlock(block, src);
11899 return block.addTy(.frame_address, Type.@"usize");
11900}
11901
11902fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {11899fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
11903 const inst_data = sema.code.instructions.items(.data)[inst].un_node;11900 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
11904 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };11901 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
src/arch/aarch64/CodeGen.zig+10-12
...@@ -579,7 +579,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -579,7 +579,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
579 .block => try self.airBlock(inst),579 .block => try self.airBlock(inst),
580 .br => try self.airBr(inst),580 .br => try self.airBr(inst),
581 .breakpoint => try self.airBreakpoint(),581 .breakpoint => try self.airBreakpoint(),
582 .ret_addr => try self.airRetAddr(),582 .ret_addr => try self.airRetAddr(inst),
583 .frame_addr => try self.airFrameAddress(inst),
583 .fence => try self.airFence(),584 .fence => try self.airFence(),
584 .call => try self.airCall(inst),585 .call => try self.airCall(inst),
585 .cond_br => try self.airCondBr(inst),586 .cond_br => try self.airCondBr(inst),
...@@ -670,8 +671,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -670,8 +671,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
670 .wrap_optional => try self.airWrapOptional(inst),671 .wrap_optional => try self.airWrapOptional(inst),
671 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),672 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
672 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),673 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
673
674 .frame_address => try self.airFrameAddress(inst),
675 // zig fmt: on674 // zig fmt: on
676 }675 }
677676
...@@ -1519,13 +1518,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1519,13 +1518,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
1519 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1518 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1520}1519}
15211520
1522fn 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
1529fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {1521fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
1530 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1522 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1531 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch});1523 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch});
...@@ -2187,8 +2179,14 @@ fn airBreakpoint(self: *Self) !void {...@@ -2187,8 +2179,14 @@ fn airBreakpoint(self: *Self) !void {
2187 return self.finishAirBookkeeping();2179 return self.finishAirBookkeeping();
2188}2180}
21892181
2190fn airRetAddr(self: *Self) !void {2182fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
2191 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});2183 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for aarch64", .{});
2184 return self.finishAir(inst, result, .{ .none, .none, .none });
2185}
2186
2187fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
2188 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for aarch64", .{});
2189 return self.finishAir(inst, result, .{ .none, .none, .none });
2192}2190}
21932191
2194fn airFence(self: *Self) !void {2192fn airFence(self: *Self) !void {
src/arch/arm/CodeGen.zig+10-12
...@@ -565,7 +565,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -565,7 +565,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
565 .block => try self.airBlock(inst),565 .block => try self.airBlock(inst),
566 .br => try self.airBr(inst),566 .br => try self.airBr(inst),
567 .breakpoint => try self.airBreakpoint(),567 .breakpoint => try self.airBreakpoint(),
568 .ret_addr => try self.airRetAddr(),568 .ret_addr => try self.airRetAddr(inst),
569 .frame_addr => try self.airFrameAddress(inst),
569 .fence => try self.airFence(),570 .fence => try self.airFence(),
570 .call => try self.airCall(inst),571 .call => try self.airCall(inst),
571 .cond_br => try self.airCondBr(inst),572 .cond_br => try self.airCondBr(inst),
...@@ -656,8 +657,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -656,8 +657,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
656 .wrap_optional => try self.airWrapOptional(inst),657 .wrap_optional => try self.airWrapOptional(inst),
657 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),658 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
658 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),659 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
659
660 .frame_address => try self.airFrameAddress(inst),
661 // zig fmt: on660 // zig fmt: on
662 }661 }
663662
...@@ -1274,13 +1273,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1274,13 +1273,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
1274 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1273 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1275}1274}
12761275
1277fn 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
1284fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {1276fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
1285 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1277 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1286 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1278 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
...@@ -2458,8 +2450,14 @@ fn airBreakpoint(self: *Self) !void {...@@ -2458,8 +2450,14 @@ fn airBreakpoint(self: *Self) !void {
2458 return self.finishAirBookkeeping();2450 return self.finishAirBookkeeping();
2459}2451}
24602452
2461fn airRetAddr(self: *Self) !void {2453fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
2462 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});2454 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for arm", .{});
2455 return self.finishAir(inst, result, .{ .none, .none, .none });
2456}
2457
2458fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
2459 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for arm", .{});
2460 return self.finishAir(inst, result, .{ .none, .none, .none });
2463}2461}
24642462
2465fn airFence(self: *Self) !void {2463fn airFence(self: *Self) !void {
src/arch/riscv64/CodeGen.zig+10-11
...@@ -550,7 +550,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -550,7 +550,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
550 .block => try self.airBlock(inst),550 .block => try self.airBlock(inst),
551 .br => try self.airBr(inst),551 .br => try self.airBr(inst),
552 .breakpoint => try self.airBreakpoint(),552 .breakpoint => try self.airBreakpoint(),
553 .ret_addr => try self.airRetAddr(),553 .ret_addr => try self.airRetAddr(inst),
554 .frame_addr => try self.airFrameAddress(inst),
554 .fence => try self.airFence(),555 .fence => try self.airFence(),
555 .call => try self.airCall(inst),556 .call => try self.airCall(inst),
556 .cond_br => try self.airCondBr(inst),557 .cond_br => try self.airCondBr(inst),
...@@ -641,8 +642,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -641,8 +642,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
641 .wrap_optional => try self.airWrapOptional(inst),642 .wrap_optional => try self.airWrapOptional(inst),
642 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),643 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
643 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),644 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
644
645 .frame_address => try self.airFrameAddress(inst),
646 // zig fmt: on645 // zig fmt: on
647 }646 }
648 if (std.debug.runtime_safety) {647 if (std.debug.runtime_safety) {
...@@ -1105,12 +1104,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1105,12 +1104,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
1105 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1104 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1106}1105}
11071106
1108fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
1109 _ = self;
1110 _ = inst;
1111 return self.fail("TODO implement codegen airFrameAddress", .{});
1112}
1113
1114fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {1107fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
1115 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1108 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1116 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch});1109 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement slice_ptr for {}", .{self.target.cpu.arch});
...@@ -1446,8 +1439,14 @@ fn airBreakpoint(self: *Self) !void {...@@ -1446,8 +1439,14 @@ fn airBreakpoint(self: *Self) !void {
1446 return self.finishAirBookkeeping();1439 return self.finishAirBookkeeping();
1447}1440}
14481441
1449fn airRetAddr(self: *Self) !void {1442fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
1450 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});1443 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for riscv64", .{});
1444 return self.finishAir(inst, result, .{ .none, .none, .none });
1445}
1446
1447fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
1448 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for riscv64", .{});
1449 return self.finishAir(inst, result, .{ .none, .none, .none });
1451}1450}
14521451
1453fn airFence(self: *Self) !void {1452fn airFence(self: *Self) !void {
src/arch/wasm/CodeGen.zig+1-1
...@@ -1683,6 +1683,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1683,6 +1683,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1683 .assembly,1683 .assembly,
1684 .shl_sat,1684 .shl_sat,
1685 .ret_addr,1685 .ret_addr,
1686 .frame_addr,
1686 .clz,1687 .clz,
1687 .ctz,1688 .ctz,
1688 .popcount,1689 .popcount,
...@@ -1726,7 +1727,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1726,7 +1727,6 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1726 .error_name,1727 .error_name,
1727 .errunion_payload_ptr_set,1728 .errunion_payload_ptr_set,
1728 .field_parent_ptr,1729 .field_parent_ptr,
1729 .frame_address,
17301730
1731 // For these 4, probably best to wait until https://github.com/ziglang/zig/issues/102481731 // For these 4, probably best to wait until https://github.com/ziglang/zig/issues/10248
1732 // 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+10-14
...@@ -662,7 +662,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -662,7 +662,8 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
662 .block => try self.airBlock(inst),662 .block => try self.airBlock(inst),
663 .br => try self.airBr(inst),663 .br => try self.airBr(inst),
664 .breakpoint => try self.airBreakpoint(),664 .breakpoint => try self.airBreakpoint(),
665 .ret_addr => try self.airRetAddr(),665 .ret_addr => try self.airRetAddr(inst),
666 .frame_addr => try self.airFrameAddress(inst),
666 .fence => try self.airFence(),667 .fence => try self.airFence(),
667 .call => try self.airCall(inst),668 .call => try self.airCall(inst),
668 .cond_br => try self.airCondBr(inst),669 .cond_br => try self.airCondBr(inst),
...@@ -753,8 +754,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -753,8 +754,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
753 .wrap_optional => try self.airWrapOptional(inst),754 .wrap_optional => try self.airWrapOptional(inst),
754 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),755 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
755 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),756 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
756
757 .frame_address => try self.airFrameAddress(inst),
758 // zig fmt: on757 // zig fmt: on
759 }758 }
760759
...@@ -1867,15 +1866,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {...@@ -1867,15 +1866,6 @@ fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
1867 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1866 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1868}1867}
18691868
1870fn 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
1879fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {1869fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void {
1880 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1870 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1881 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1871 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
...@@ -3138,8 +3128,14 @@ fn airBreakpoint(self: *Self) !void {...@@ -3138,8 +3128,14 @@ fn airBreakpoint(self: *Self) !void {
3138 return self.finishAirBookkeeping();3128 return self.finishAirBookkeeping();
3139}3129}
31403130
3141fn airRetAddr(self: *Self) !void {3131fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
3142 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});3132 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airRetAddr for x86_64", .{});
3133 return self.finishAir(inst, result, .{ .none, .none, .none });
3134}
3135
3136fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void {
3137 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement airFrameAddress for x86_64", .{});
3138 return self.finishAir(inst, result, .{ .none, .none, .none });
3143}3139}
31443140
3145fn airFence(self: *Self) !void {3141fn airFence(self: *Self) !void {
src/codegen/c.zig+11-9
...@@ -1588,7 +1588,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1588,7 +1588,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1588 .arg => airArg(f),1588 .arg => airArg(f),
15891589
1590 .breakpoint => try airBreakpoint(f),1590 .breakpoint => try airBreakpoint(f),
1591 .ret_addr => try airRetAddr(f),1591 .ret_addr => try airRetAddr(f, inst),
1592 .frame_addr => try airFrameAddress(f, inst),
1592 .unreach => try airUnreach(f),1593 .unreach => try airUnreach(f),
1593 .fence => try airFence(f, inst),1594 .fence => try airFence(f, inst),
15941595
...@@ -1757,8 +1758,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1757,8 +1758,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1757 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),1758 .wrap_errunion_payload => try airWrapErrUnionPay(f, inst),
1758 .wrap_errunion_err => try airWrapErrUnionErr(f, inst),1759 .wrap_errunion_err => try airWrapErrUnionErr(f, inst),
1759 .errunion_payload_ptr_set => try airErrUnionPayloadPtrSet(f, inst),1760 .errunion_payload_ptr_set => try airErrUnionPayloadPtrSet(f, inst),
1760
1761 .frame_address => try airFrameAddress(f, inst),
1762 // zig fmt: on1761 // zig fmt: on
1763 };1762 };
1764 switch (result_value) {1763 switch (result_value) {
...@@ -2719,12 +2718,20 @@ fn airBreakpoint(f: *Function) !CValue {...@@ -2719,12 +2718,20 @@ fn airBreakpoint(f: *Function) !CValue {
2719 return CValue.none;2718 return CValue.none;
2720}2719}
27212720
2722fn airRetAddr(f: *Function) !CValue {2721fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue {
2722 if (f.liveness.isUnused(inst)) return CValue.none;
2723 const local = try f.allocLocal(Type.usize, .Const);2723 const local = try f.allocLocal(Type.usize, .Const);
2724 try f.object.writer().writeAll(" = zig_return_address();\n");2724 try f.object.writer().writeAll(" = zig_return_address();\n");
2725 return local;2725 return local;
2726}2726}
27272727
2728fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
2729 if (f.liveness.isUnused(inst)) return CValue.none;
2730 const local = try f.allocLocal(Type.usize, .Const);
2731 try f.object.writer().writeAll(" = zig_frame_address();\n");
2732 return local;
2733}
2734
2728fn airFence(f: *Function, inst: Air.Inst.Index) !CValue {2735fn airFence(f: *Function, inst: Air.Inst.Index) !CValue {
2729 const atomic_order = f.air.instructions.items(.data)[inst].fence;2736 const atomic_order = f.air.instructions.items(.data)[inst].fence;
2730 const writer = f.object.writer();2737 const writer = f.object.writer();
...@@ -3200,11 +3207,6 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -3200,11 +3207,6 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
3200 return f.fail("TODO: C backend: implement airErrUnionPayloadPtrSet", .{});3207 return f.fail("TODO: C backend: implement airErrUnionPayloadPtrSet", .{});
3201}3208}
32023209
3203fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue {
3204 _ = inst;
3205 return f.fail("TODO: C backend: implement airFrameAddress", .{});
3206}
3207
3208fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {3210fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
3209 if (f.liveness.isUnused(inst))3211 if (f.liveness.isUnused(inst))
3210 return CValue.none;3212 return CValue.none;
src/codegen/llvm.zig+19-17
...@@ -2135,6 +2135,7 @@ pub const FuncGen = struct {...@@ -2135,6 +2135,7 @@ pub const FuncGen = struct {
2135 .switch_br => try self.airSwitchBr(inst),2135 .switch_br => try self.airSwitchBr(inst),
2136 .breakpoint => try self.airBreakpoint(inst),2136 .breakpoint => try self.airBreakpoint(inst),
2137 .ret_addr => try self.airRetAddr(inst),2137 .ret_addr => try self.airRetAddr(inst),
2138 .frame_addr => try self.airFrameAddress(inst),
2138 .call => try self.airCall(inst),2139 .call => try self.airCall(inst),
2139 .cond_br => try self.airCondBr(inst),2140 .cond_br => try self.airCondBr(inst),
2140 .intcast => try self.airIntCast(inst),2141 .intcast => try self.airIntCast(inst),
...@@ -2214,8 +2215,6 @@ pub const FuncGen = struct {...@@ -2214,8 +2215,6 @@ pub const FuncGen = struct {
2214 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),2215 .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst),
2215 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),2216 .wrap_errunion_err => try self.airWrapErrUnionErr(inst),
22162217
2217 .frame_address => try self.airFrameAddress(inst),
2218
2219 .constant => unreachable,2218 .constant => unreachable,
2220 .const_ty => unreachable,2219 .const_ty => unreachable,
2221 .unreach => self.airUnreach(inst),2220 .unreach => self.airUnreach(inst),
...@@ -3341,16 +3340,6 @@ pub const FuncGen = struct {...@@ -3341,16 +3340,6 @@ pub const FuncGen = struct {
3341 return partial;3340 return partial;
3342 }3341 }
33433342
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
3354 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {3343 fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
3355 if (self.liveness.isUnused(inst)) return null;3344 if (self.liveness.isUnused(inst)) return null;
33563345
...@@ -4112,12 +4101,25 @@ pub const FuncGen = struct {...@@ -4112,12 +4101,25 @@ pub const FuncGen = struct {
4112 }4101 }
41134102
4114 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {4103 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
4115 _ = inst;4104 if (self.liveness.isUnused(inst)) return null;
4116 const i32_zero = self.context.intType(32).constNull();4105
4117 const usize_llvm_ty = try self.dg.llvmType(Type.usize);4106 const llvm_i32 = self.context.intType(32);
4118 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});4107 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
4119 const ptr_val = self.builder.buildCall(llvm_fn, &[_]*const llvm.Value{i32_zero}, 1, .Fast, .Auto, "");4108 const params = [_]*const llvm.Value{llvm_i32.constNull()};
4120 return self.builder.buildPtrToInt(ptr_val, usize_llvm_ty, "");4109 const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
4110 const llvm_usize = try self.dg.llvmType(Type.usize);
4111 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
4112 }
4113
4114 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
4115 if (self.liveness.isUnused(inst)) return null;
4116
4117 const llvm_i32 = self.context.intType(32);
4118 const llvm_fn = self.getIntrinsic("llvm.frameaddress", &.{llvm_i32});
4119 const params = [_]*const llvm.Value{llvm_i32.constNull()};
4120 const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
4121 const llvm_usize = try self.dg.llvmType(Type.usize);
4122 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
4121 }4123 }
41224124
4123 fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {4125 fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
src/print_air.zig+1-1
...@@ -171,13 +171,13 @@ const Writer = struct {...@@ -171,13 +171,13 @@ const Writer = struct {
171 .breakpoint,171 .breakpoint,
172 .unreach,172 .unreach,
173 .ret_addr,173 .ret_addr,
174 .frame_addr,
174 => try w.writeNoOp(s, inst),175 => try w.writeNoOp(s, inst),
175176
176 .const_ty,177 .const_ty,
177 .alloc,178 .alloc,
178 .ret_ptr,179 .ret_ptr,
179 .arg,180 .arg,
180 .frame_address,
181 => try w.writeTy(s, inst),181 => try w.writeTy(s, inst),
182182
183 .not,183 .not,