mirror of
https://github.com/ziglang/zig.git
synced 2026-02-04 05:33:39 +00:00
stage2: @returnAddress()
This commit is contained in:
parent
2f7e98c129
commit
ddd2ef822f
@ -195,6 +195,9 @@ pub const Inst = struct {
|
||||
/// Lowers to a hardware trap instruction, or the next best thing.
|
||||
/// Result type is always void.
|
||||
breakpoint,
|
||||
/// Yields the return address of the current function.
|
||||
/// Uses the `no_op` field.
|
||||
ret_addr,
|
||||
/// Function call.
|
||||
/// Result type is the return type of the function being called.
|
||||
/// 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 {
|
||||
|
||||
.ptrtoint,
|
||||
.slice_len,
|
||||
.ret_addr,
|
||||
=> return Type.initTag(.usize),
|
||||
|
||||
.bool_to_int => return Type.initTag(.u1),
|
||||
|
||||
@ -281,6 +281,7 @@ fn analyzeInst(
|
||||
.dbg_stmt,
|
||||
.unreach,
|
||||
.fence,
|
||||
.ret_addr,
|
||||
=> return trackOperands(a, new_set, inst, main_tomb, .{ .none, .none, .none }),
|
||||
|
||||
.not,
|
||||
|
||||
@ -8739,8 +8739,12 @@ fn zirRetAddr(
|
||||
block: *Block,
|
||||
extended: Zir.Inst.Extended.InstData,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
|
||||
return sema.fail(block, src, "TODO: implement Sema.zirRetAddr", .{});
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
return try block.addNoOp(.ret_addr);
|
||||
}
|
||||
|
||||
fn zirBuiltinSrc(
|
||||
|
||||
@ -547,6 +547,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.block => try self.airBlock(inst),
|
||||
.br => try self.airBr(inst),
|
||||
.breakpoint => try self.airBreakpoint(),
|
||||
.ret_addr => try self.airRetAddr(),
|
||||
.fence => try self.airFence(),
|
||||
.call => try self.airCall(inst),
|
||||
.cond_br => try self.airCondBr(inst),
|
||||
@ -1416,6 +1417,10 @@ fn airBreakpoint(self: *Self) !void {
|
||||
return self.finishAirBookkeeping();
|
||||
}
|
||||
|
||||
fn airRetAddr(self: *Self) !void {
|
||||
return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
|
||||
}
|
||||
|
||||
fn airFence(self: *Self) !void {
|
||||
return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});
|
||||
//return self.finishAirBookkeeping();
|
||||
|
||||
@ -545,6 +545,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.block => try self.airBlock(inst),
|
||||
.br => try self.airBr(inst),
|
||||
.breakpoint => try self.airBreakpoint(),
|
||||
.ret_addr => try self.airRetAddr(),
|
||||
.fence => try self.airFence(),
|
||||
.call => try self.airCall(inst),
|
||||
.cond_br => try self.airCondBr(inst),
|
||||
@ -1850,6 +1851,10 @@ fn airBreakpoint(self: *Self) !void {
|
||||
return self.finishAirBookkeeping();
|
||||
}
|
||||
|
||||
fn airRetAddr(self: *Self) !void {
|
||||
return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
|
||||
}
|
||||
|
||||
fn airFence(self: *Self) !void {
|
||||
return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});
|
||||
//return self.finishAirBookkeeping();
|
||||
|
||||
@ -526,6 +526,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.block => try self.airBlock(inst),
|
||||
.br => try self.airBr(inst),
|
||||
.breakpoint => try self.airBreakpoint(),
|
||||
.ret_addr => try self.airRetAddr(),
|
||||
.fence => try self.airFence(),
|
||||
.call => try self.airCall(inst),
|
||||
.cond_br => try self.airCondBr(inst),
|
||||
@ -1354,6 +1355,10 @@ fn airBreakpoint(self: *Self) !void {
|
||||
return self.finishAirBookkeeping();
|
||||
}
|
||||
|
||||
fn airRetAddr(self: *Self) !void {
|
||||
return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
|
||||
}
|
||||
|
||||
fn airFence(self: *Self) !void {
|
||||
return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});
|
||||
//return self.finishAirBookkeeping();
|
||||
|
||||
@ -579,6 +579,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.block => try self.airBlock(inst),
|
||||
.br => try self.airBr(inst),
|
||||
.breakpoint => try self.airBreakpoint(),
|
||||
.ret_addr => try self.airRetAddr(),
|
||||
.fence => try self.airFence(),
|
||||
.call => try self.airCall(inst),
|
||||
.cond_br => try self.airCondBr(inst),
|
||||
@ -1839,6 +1840,10 @@ fn airBreakpoint(self: *Self) !void {
|
||||
return self.finishAirBookkeeping();
|
||||
}
|
||||
|
||||
fn airRetAddr(self: *Self) !void {
|
||||
return self.fail("TODO implement airRetAddr for {}", .{self.target.cpu.arch});
|
||||
}
|
||||
|
||||
fn airFence(self: *Self) !void {
|
||||
return self.fail("TODO implement fence() for {}", .{self.target.cpu.arch});
|
||||
//return self.finishAirBookkeeping();
|
||||
|
||||
@ -1125,6 +1125,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
|
||||
.arg => airArg(f),
|
||||
|
||||
.breakpoint => try airBreakpoint(f),
|
||||
.ret_addr => try airRetAddr(f),
|
||||
.unreach => try airUnreach(f),
|
||||
.fence => try airFence(f, inst),
|
||||
|
||||
@ -2191,6 +2192,10 @@ fn airBreakpoint(f: *Function) !CValue {
|
||||
return CValue.none;
|
||||
}
|
||||
|
||||
fn airRetAddr(f: *Function) !CValue {
|
||||
return f.fail("TODO implement codegen for airRetAddr", .{});
|
||||
}
|
||||
|
||||
fn airFence(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
const atomic_order = f.air.instructions.items(.data)[inst].fence;
|
||||
const writer = f.object.writer();
|
||||
|
||||
@ -1747,6 +1747,7 @@ pub const FuncGen = struct {
|
||||
.br => try self.airBr(inst),
|
||||
.switch_br => try self.airSwitchBr(inst),
|
||||
.breakpoint => try self.airBreakpoint(inst),
|
||||
.ret_addr => try self.airRetAddr(inst),
|
||||
.call => try self.airCall(inst),
|
||||
.cond_br => try self.airCondBr(inst),
|
||||
.intcast => try self.airIntCast(inst),
|
||||
@ -3550,6 +3551,15 @@ pub const FuncGen = struct {
|
||||
return null;
|
||||
}
|
||||
|
||||
fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
|
||||
_ = inst;
|
||||
const i32_zero = self.context.intType(32).constNull();
|
||||
const usize_llvm_ty = try self.dg.llvmType(Type.usize);
|
||||
const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
|
||||
const ptr_val = self.builder.buildCall(llvm_fn, &[_]*const llvm.Value{i32_zero}, 1, .Fast, .Auto, "");
|
||||
return self.builder.buildPtrToInt(ptr_val, usize_llvm_ty, "");
|
||||
}
|
||||
|
||||
fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
|
||||
const atomic_order = self.air.instructions.items(.data)[inst].fence;
|
||||
const llvm_memory_order = toLlvmAtomicOrdering(atomic_order);
|
||||
|
||||
@ -159,6 +159,7 @@ const Writer = struct {
|
||||
|
||||
.breakpoint,
|
||||
.unreach,
|
||||
.ret_addr,
|
||||
=> try w.writeNoOp(s, inst),
|
||||
|
||||
.const_ty,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user