| author | |
| committer | |
| log | d5100dc81555f0e8197d5f189b1432070e8d72dd |
| tree | 96de992b22f7cfc4bcb672892c64fb2cdf621913 |
| parent | 90bce11f62aa2f246b9bce5bc49069a3faf7ec9a |
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, |
| 582 | 585 | ||
| 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), |
| 948 | 947 | ||
| 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 }), |
| 322 | 322 | ||
| 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 | } |
| 10003 | 10000 | ||
| 10001 | fn 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 | |||
| 10004 | fn zirBuiltinSrc( | 10011 | fn 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 | } |
| 11891 | 11898 | ||
| 11892 | fn 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 | |||
| 11902 | fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 11899 | fn 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: on | 674 | // zig fmt: on |
| 676 | } | 675 | } |
| 677 | 676 | ||
| ... | @@ -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 | } |
| 1521 | 1520 | ||
| 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 | |||
| 1529 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | 1521 | fn 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 | } |
| 2189 | 2181 | ||
| 2190 | fn airRetAddr(self: *Self) !void { | 2182 | fn 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 | |||
| 2187 | fn 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 | } |
| 2193 | 2191 | ||
| 2194 | fn airFence(self: *Self) !void { | 2192 | fn 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: on | 660 | // zig fmt: on |
| 662 | } | 661 | } |
| 663 | 662 | ||
| ... | @@ -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 | } |
| 1276 | 1275 | ||
| 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 | |||
| 1284 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | 1276 | fn 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 | } |
| 2460 | 2452 | ||
| 2461 | fn airRetAddr(self: *Self) !void { | 2453 | fn 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 | |||
| 2458 | fn 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 | } |
| 2464 | 2462 | ||
| 2465 | fn airFence(self: *Self) !void { | 2463 | fn 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: on | 645 | // 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 | } |
| 1107 | 1106 | ||
| 1108 | fn airFrameAddress(self: *Self, inst: Air.Inst.Index) !void { | ||
| 1109 | _ = self; | ||
| 1110 | _ = inst; | ||
| 1111 | return self.fail("TODO implement codegen airFrameAddress", .{}); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | 1107 | fn 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 | } |
| 1448 | 1441 | ||
| 1449 | fn airRetAddr(self: *Self) !void { | 1442 | fn 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 | |||
| 1447 | fn 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 | } |
| 1452 | 1451 | ||
| 1453 | fn airFence(self: *Self) !void { | 1452 | fn 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, | ||
| 1730 | 1730 | ||
| 1731 | // 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 |
| 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: on | 757 | // zig fmt: on |
| 759 | } | 758 | } |
| 760 | 759 | ||
| ... | @@ -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 | } |
| 1869 | 1868 | ||
| 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 | |||
| 1879 | fn airSlicePtr(self: *Self, inst: Air.Inst.Index) !void { | 1869 | fn 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 | } |
| 3140 | 3130 | ||
| 3141 | fn airRetAddr(self: *Self) !void { | 3131 | fn 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 | |||
| 3136 | fn 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 | } |
| 3144 | 3140 | ||
| 3145 | fn airFence(self: *Self) !void { | 3141 | fn 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), |
| 1589 | 1589 | ||
| 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), |
| 1594 | 1595 | ||
| ... | @@ -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: on | 1761 | // 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 | } |
| 2721 | 2720 | ||
| 2722 | fn airRetAddr(f: *Function) !CValue { | 2721 | fn 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 | } |
| 2727 | 2727 | ||
| 2728 | fn 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 | |||
| 2728 | fn airFence(f: *Function, inst: Air.Inst.Index) !CValue { | 2735 | fn 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 | } |
| 3202 | 3209 | ||
| 3203 | fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue { | ||
| 3204 | _ = inst; | ||
| 3205 | return f.fail("TODO: C backend: implement airFrameAddress", .{}); | ||
| 3206 | } | ||
| 3207 | |||
| 3208 | fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | 3210 | fn 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), |
| 2216 | 2217 | ||
| 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 | } |
| 3343 | 3342 | ||
| 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; |
| 3356 | 3345 | ||
| ... | @@ -4112,12 +4101,25 @@ pub const FuncGen = struct { | ... | @@ -4112,12 +4101,25 @@ pub const FuncGen = struct { |
| 4112 | } | 4101 | } |
| 4113 | 4102 | ||
| 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 | } |
| 4122 | 4124 | ||
| 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), |
| 175 | 176 | ||
| 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), |
| 182 | 182 | ||
| 183 | .not, | 183 | .not, |