authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-12-18 06:11:46+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-12-21 01:41:51+01:00
logddd2ef822f99979d3ea61583a91ab236942e6367
treea95dc4847af72a411d1a638e10b0fc056d67e511
parent2f7e98c129ca3c86fe20c043078bcc7f2fe477d6

stage2: @returnAddress()


10 files changed, 46 insertions(+), 1 deletions(-)

src/Air.zig+4
...@@ -195,6 +195,9 @@ pub const Inst = struct {...@@ -195,6 +195,9 @@ pub const Inst = struct {
195 /// Lowers to a hardware trap instruction, or the next best thing.195 /// Lowers to a hardware trap instruction, or the next best thing.
196 /// Result type is always void.196 /// Result type is always void.
197 breakpoint,197 breakpoint,
198 /// Yields the return address of the current function.
199 /// Uses the `no_op` field.
200 ret_addr,
198 /// Function call.201 /// Function call.
199 /// Result type is the return type of the function being called.202 /// Result type is the return type of the function being called.
200 /// Uses the `pl_op` field with the `Call` payload. operand is the callee.203 /// Uses the `pl_op` field with the `Call` payload. operand is the callee.
...@@ -785,6 +788,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -785,6 +788,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
785788
786 .ptrtoint,789 .ptrtoint,
787 .slice_len,790 .slice_len,
791 .ret_addr,
788 => return Type.initTag(.usize),792 => return Type.initTag(.usize),
789793
790 .bool_to_int => return Type.initTag(.u1),794 .bool_to_int => return Type.initTag(.u1),
src/Liveness.zig+1
...@@ -281,6 +281,7 @@ fn analyzeInst(...@@ -281,6 +281,7 @@ fn analyzeInst(
281 .dbg_stmt,281 .dbg_stmt,
282 .unreach,282 .unreach,
283 .fence,283 .fence,
284 .ret_addr,
284 => return trackOperands(a, new_set, inst, main_tomb, .{ .none, .none, .none }),285 => return trackOperands(a, new_set, inst, main_tomb, .{ .none, .none, .none }),
285286
286 .not,287 .not,
src/Sema.zig+5-1
...@@ -8739,8 +8739,12 @@ fn zirRetAddr(...@@ -8739,8 +8739,12 @@ fn zirRetAddr(
8739 block: *Block,8739 block: *Block,
8740 extended: Zir.Inst.Extended.InstData,8740 extended: Zir.Inst.Extended.InstData,
8741) CompileError!Air.Inst.Ref {8741) CompileError!Air.Inst.Ref {
8742 const tracy = trace(@src());
8743 defer tracy.end();
8744
8742 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };8745 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
8743 return sema.fail(block, src, "TODO: implement Sema.zirRetAddr", .{});8746 try sema.requireRuntimeBlock(block, src);
8747 return try block.addNoOp(.ret_addr);
8744}8748}
87458749
8746fn zirBuiltinSrc(8750fn zirBuiltinSrc(
src/arch/aarch64/CodeGen.zig+5
...@@ -547,6 +547,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -547,6 +547,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
547 .block => try self.airBlock(inst),547 .block => try self.airBlock(inst),
548 .br => try self.airBr(inst),548 .br => try self.airBr(inst),
549 .breakpoint => try self.airBreakpoint(),549 .breakpoint => try self.airBreakpoint(),
550 .ret_addr => try self.airRetAddr(),
550 .fence => try self.airFence(),551 .fence => try self.airFence(),
551 .call => try self.airCall(inst),552 .call => try self.airCall(inst),
552 .cond_br => try self.airCondBr(inst),553 .cond_br => try self.airCondBr(inst),
...@@ -1416,6 +1417,10 @@ fn airBreakpoint(self: *Self) !void {...@@ -1416,6 +1417,10 @@ fn airBreakpoint(self: *Self) !void {
1416 return self.finishAirBookkeeping();1417 return self.finishAirBookkeeping();
1417}1418}
14181419
1420fn airRetAddr(self: *Self) !void {
1421 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
1422}
1423
1419fn airFence(self: *Self) !void {1424fn airFence(self: *Self) !void {
1420 return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});1425 return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});
1421 //return self.finishAirBookkeeping();1426 //return self.finishAirBookkeeping();
src/arch/arm/CodeGen.zig+5
...@@ -545,6 +545,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -545,6 +545,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
545 .block => try self.airBlock(inst),545 .block => try self.airBlock(inst),
546 .br => try self.airBr(inst),546 .br => try self.airBr(inst),
547 .breakpoint => try self.airBreakpoint(),547 .breakpoint => try self.airBreakpoint(),
548 .ret_addr => try self.airRetAddr(),
548 .fence => try self.airFence(),549 .fence => try self.airFence(),
549 .call => try self.airCall(inst),550 .call => try self.airCall(inst),
550 .cond_br => try self.airCondBr(inst),551 .cond_br => try self.airCondBr(inst),
...@@ -1850,6 +1851,10 @@ fn airBreakpoint(self: *Self) !void {...@@ -1850,6 +1851,10 @@ fn airBreakpoint(self: *Self) !void {
1850 return self.finishAirBookkeeping();1851 return self.finishAirBookkeeping();
1851}1852}
18521853
1854fn airRetAddr(self: *Self) !void {
1855 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
1856}
1857
1853fn airFence(self: *Self) !void {1858fn airFence(self: *Self) !void {
1854 return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});1859 return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});
1855 //return self.finishAirBookkeeping();1860 //return self.finishAirBookkeeping();
src/arch/riscv64/CodeGen.zig+5
...@@ -526,6 +526,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -526,6 +526,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
526 .block => try self.airBlock(inst),526 .block => try self.airBlock(inst),
527 .br => try self.airBr(inst),527 .br => try self.airBr(inst),
528 .breakpoint => try self.airBreakpoint(),528 .breakpoint => try self.airBreakpoint(),
529 .ret_addr => try self.airRetAddr(),
529 .fence => try self.airFence(),530 .fence => try self.airFence(),
530 .call => try self.airCall(inst),531 .call => try self.airCall(inst),
531 .cond_br => try self.airCondBr(inst),532 .cond_br => try self.airCondBr(inst),
...@@ -1354,6 +1355,10 @@ fn airBreakpoint(self: *Self) !void {...@@ -1354,6 +1355,10 @@ fn airBreakpoint(self: *Self) !void {
1354 return self.finishAirBookkeeping();1355 return self.finishAirBookkeeping();
1355}1356}
13561357
1358fn airRetAddr(self: *Self) !void {
1359 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
1360}
1361
1357fn airFence(self: *Self) !void {1362fn airFence(self: *Self) !void {
1358 return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});1363 return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});
1359 //return self.finishAirBookkeeping();1364 //return self.finishAirBookkeeping();
src/arch/x86_64/CodeGen.zig+5
...@@ -579,6 +579,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -579,6 +579,7 @@ 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 .fence => try self.airFence(),583 .fence => try self.airFence(),
583 .call => try self.airCall(inst),584 .call => try self.airCall(inst),
584 .cond_br => try self.airCondBr(inst),585 .cond_br => try self.airCondBr(inst),
...@@ -1839,6 +1840,10 @@ fn airBreakpoint(self: *Self) !void {...@@ -1839,6 +1840,10 @@ fn airBreakpoint(self: *Self) !void {
1839 return self.finishAirBookkeeping();1840 return self.finishAirBookkeeping();
1840}1841}
18411842
1843fn airRetAddr(self: *Self) !void {
1844 return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
1845}
1846
1842fn airFence(self: *Self) !void {1847fn airFence(self: *Self) !void {
1843 return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});1848 return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});
1844 //return self.finishAirBookkeeping();1849 //return self.finishAirBookkeeping();
src/codegen/c.zig+5
...@@ -1125,6 +1125,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1125,6 +1125,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1125 .arg => airArg(f),1125 .arg => airArg(f),
11261126
1127 .breakpoint => try airBreakpoint(f),1127 .breakpoint => try airBreakpoint(f),
1128 .ret_addr => try airRetAddr(f),
1128 .unreach => try airUnreach(f),1129 .unreach => try airUnreach(f),
1129 .fence => try airFence(f, inst),1130 .fence => try airFence(f, inst),
11301131
...@@ -2191,6 +2192,10 @@ fn airBreakpoint(f: *Function) !CValue {...@@ -2191,6 +2192,10 @@ fn airBreakpoint(f: *Function) !CValue {
2191 return CValue.none;2192 return CValue.none;
2192}2193}
21932194
2195fn airRetAddr(f: *Function) !CValue {
2196 return f.fail("TODO implement codegen for airRetAddr", .{});
2197}
2198
2194fn airFence(f: *Function, inst: Air.Inst.Index) !CValue {2199fn airFence(f: *Function, inst: Air.Inst.Index) !CValue {
2195 const atomic_order = f.air.instructions.items(.data)[inst].fence;2200 const atomic_order = f.air.instructions.items(.data)[inst].fence;
2196 const writer = f.object.writer();2201 const writer = f.object.writer();
src/codegen/llvm.zig+10
...@@ -1747,6 +1747,7 @@ pub const FuncGen = struct {...@@ -1747,6 +1747,7 @@ pub const FuncGen = struct {
1747 .br => try self.airBr(inst),1747 .br => try self.airBr(inst),
1748 .switch_br => try self.airSwitchBr(inst),1748 .switch_br => try self.airSwitchBr(inst),
1749 .breakpoint => try self.airBreakpoint(inst),1749 .breakpoint => try self.airBreakpoint(inst),
1750 .ret_addr => try self.airRetAddr(inst),
1750 .call => try self.airCall(inst),1751 .call => try self.airCall(inst),
1751 .cond_br => try self.airCondBr(inst),1752 .cond_br => try self.airCondBr(inst),
1752 .intcast => try self.airIntCast(inst),1753 .intcast => try self.airIntCast(inst),
...@@ -3550,6 +3551,15 @@ pub const FuncGen = struct {...@@ -3550,6 +3551,15 @@ pub const FuncGen = struct {
3550 return null;3551 return null;
3551 }3552 }
35523553
3554 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
3555 _ = inst;
3556 const i32_zero = self.context.intType(32).constNull();
3557 const usize_llvm_ty = try self.dg.llvmType(Type.usize);
3558 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
3559 const ptr_val = self.builder.buildCall(llvm_fn, &[_]*const llvm.Value{i32_zero}, 1, .Fast, .Auto, "");
3560 return self.builder.buildPtrToInt(ptr_val, usize_llvm_ty, "");
3561 }
3562
3553 fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {3563 fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
3554 const atomic_order = self.air.instructions.items(.data)[inst].fence;3564 const atomic_order = self.air.instructions.items(.data)[inst].fence;
3555 const llvm_memory_order = toLlvmAtomicOrdering(atomic_order);3565 const llvm_memory_order = toLlvmAtomicOrdering(atomic_order);
src/print_air.zig+1
...@@ -159,6 +159,7 @@ const Writer = struct {...@@ -159,6 +159,7 @@ const Writer = struct {
159159
160 .breakpoint,160 .breakpoint,
161 .unreach,161 .unreach,
162 .ret_addr,
162 => try w.writeNoOp(s, inst),163 => try w.writeNoOp(s, inst),
163164
164 .const_ty,165 .const_ty,