Commit 041bc71bc8
Changed files (2)
src
arch
aarch64
x86_64
src/arch/aarch64/CodeGen.zig
@@ -4302,32 +4302,19 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
// on linking.
const mod = self.bin_file.options.module.?;
if (self.air.value(callee)) |func_value| {
- if (self.bin_file.cast(link.File.Elf)) |elf_file| {
- if (func_value.castTag(.function)) |func_payload| {
- const func = func_payload.data;
+ if (func_value.castTag(.function)) |func_payload| {
+ const func = func_payload.data;
+ const fn_owner_decl = mod.declPtr(func.owner_decl);
+
+ if (self.bin_file.cast(link.File.Elf)) |elf_file| {
const ptr_bits = self.target.cpu.arch.ptrBitWidth();
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
- const fn_owner_decl = mod.declPtr(func.owner_decl);
const got_addr = blk: {
const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
break :blk @intCast(u32, got.p_vaddr + fn_owner_decl.link.elf.offset_table_index * ptr_bytes);
};
-
try self.genSetReg(Type.initTag(.usize), .x30, .{ .memory = got_addr });
-
- _ = try self.addInst(.{
- .tag = .blr,
- .data = .{ .reg = .x30 },
- });
- } else if (func_value.castTag(.extern_fn)) |_| {
- return self.fail("TODO implement calling extern functions", .{});
- } else {
- return self.fail("TODO implement calling bitcasted functions", .{});
- }
- } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
- if (func_value.castTag(.function)) |func_payload| {
- const func = func_payload.data;
- const fn_owner_decl = mod.declPtr(func.owner_decl);
+ } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
try fn_owner_decl.link.macho.ensureInitialized(macho_file);
try self.genSetReg(Type.initTag(.u64), .x30, .{
.linker_load = .{
@@ -4335,22 +4322,39 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
.sym_index = fn_owner_decl.link.macho.getSymbolIndex().?,
},
});
- // blr x30
- _ = try self.addInst(.{
- .tag = .blr,
- .data = .{ .reg = .x30 },
+ } else if (self.bin_file.cast(link.File.Coff)) |_| {
+ try self.genSetReg(Type.initTag(.u64), .x30, .{
+ .linker_load = .{
+ .type = .got,
+ .sym_index = fn_owner_decl.link.coff.sym_index,
+ },
});
- } else if (func_value.castTag(.extern_fn)) |func_payload| {
- const extern_fn = func_payload.data;
- const decl_name = mod.declPtr(extern_fn.owner_decl).name;
- if (extern_fn.lib_name) |lib_name| {
- log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
- decl_name,
- lib_name,
- });
- }
- const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
+ } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
+ try p9.seeDecl(func.owner_decl);
+ const ptr_bits = self.target.cpu.arch.ptrBitWidth();
+ const ptr_bytes: u64 = @divExact(ptr_bits, 8);
+ const got_addr = p9.bases.data;
+ const got_index = fn_owner_decl.link.plan9.got_index.?;
+ const fn_got_addr = got_addr + got_index * ptr_bytes;
+ try self.genSetReg(Type.initTag(.usize), .x30, .{ .memory = fn_got_addr });
+ } else unreachable;
+
+ _ = try self.addInst(.{
+ .tag = .blr,
+ .data = .{ .reg = .x30 },
+ });
+ } else if (func_value.castTag(.extern_fn)) |func_payload| {
+ const extern_fn = func_payload.data;
+ const decl_name = mod.declPtr(extern_fn.owner_decl).name;
+ if (extern_fn.lib_name) |lib_name| {
+ log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
+ decl_name,
+ lib_name,
+ });
+ }
+ if (self.bin_file.cast(link.File.MachO)) |macho_file| {
+ const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
_ = try self.addInst(.{
.tag = .call_extern,
.data = .{
@@ -4360,33 +4364,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
},
},
});
- } else {
- return self.fail("TODO implement calling bitcasted functions", .{});
- }
- } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
- if (func_value.castTag(.function)) |func_payload| {
- const func = func_payload.data;
- const fn_owner_decl = mod.declPtr(func.owner_decl);
- try self.genSetReg(Type.initTag(.u64), .x30, .{
- .linker_load = .{
- .type = .got,
- .sym_index = fn_owner_decl.link.coff.sym_index,
- },
- });
- // blr x30
- _ = try self.addInst(.{
- .tag = .blr,
- .data = .{ .reg = .x30 },
- });
- } else if (func_value.castTag(.extern_fn)) |func_payload| {
- const extern_fn = func_payload.data;
- const decl_name = mod.declPtr(extern_fn.owner_decl).name;
- if (extern_fn.lib_name) |lib_name| {
- log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
- decl_name,
- lib_name,
- });
- }
+ } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
try self.genSetReg(Type.initTag(.u64), .x30, .{
.linker_load = .{
@@ -4394,35 +4372,16 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
.sym_index = sym_index,
},
});
- // blr x30
_ = try self.addInst(.{
.tag = .blr,
.data = .{ .reg = .x30 },
});
} else {
- return self.fail("TODO implement calling bitcasted functions", .{});
- }
- } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
- if (func_value.castTag(.function)) |func_payload| {
- try p9.seeDecl(func_payload.data.owner_decl);
- const ptr_bits = self.target.cpu.arch.ptrBitWidth();
- const ptr_bytes: u64 = @divExact(ptr_bits, 8);
- const got_addr = p9.bases.data;
- const got_index = mod.declPtr(func_payload.data.owner_decl).link.plan9.got_index.?;
- const fn_got_addr = got_addr + got_index * ptr_bytes;
-
- try self.genSetReg(Type.initTag(.usize), .x30, .{ .memory = fn_got_addr });
-
- _ = try self.addInst(.{
- .tag = .blr,
- .data = .{ .reg = .x30 },
- });
- } else if (func_value.castTag(.extern_fn)) |_| {
return self.fail("TODO implement calling extern functions", .{});
- } else {
- return self.fail("TODO implement calling bitcasted functions", .{});
}
- } else unreachable;
+ } else {
+ return self.fail("TODO implement calling bitcasted functions", .{});
+ }
} else {
assert(ty.zigTypeTag() == .Pointer);
const mcv = try self.resolveInst(callee);
src/arch/x86_64/CodeGen.zig
@@ -3992,13 +3992,14 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
// Due to incremental compilation, how function calls are generated depends
// on linking.
const mod = self.bin_file.options.module.?;
- if (self.bin_file.cast(link.File.Elf)) |elf_file| {
- if (self.air.value(callee)) |func_value| {
- if (func_value.castTag(.function)) |func_payload| {
- const func = func_payload.data;
+ if (self.air.value(callee)) |func_value| {
+ if (func_value.castTag(.function)) |func_payload| {
+ const func = func_payload.data;
+ const fn_owner_decl = mod.declPtr(func.owner_decl);
+
+ if (self.bin_file.cast(link.File.Elf)) |elf_file| {
const ptr_bits = self.target.cpu.arch.ptrBitWidth();
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
- const fn_owner_decl = mod.declPtr(func.owner_decl);
const got_addr = blk: {
const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
break :blk @intCast(u32, got.p_vaddr + fn_owner_decl.link.elf.offset_table_index * ptr_bytes);
@@ -4008,29 +4009,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
.ops = Mir.Inst.Ops.encode(.{ .flags = 0b01 }),
.data = .{ .imm = @truncate(u32, got_addr) },
});
- } else if (func_value.castTag(.extern_fn)) |_| {
- return self.fail("TODO implement calling extern functions", .{});
- } else {
- return self.fail("TODO implement calling bitcasted functions", .{});
- }
- } else {
- assert(ty.zigTypeTag() == .Pointer);
- const mcv = try self.resolveInst(callee);
- try self.genSetReg(Type.initTag(.usize), .rax, mcv);
- _ = try self.addInst(.{
- .tag = .call,
- .ops = Mir.Inst.Ops.encode(.{
- .reg1 = .rax,
- .flags = 0b01,
- }),
- .data = undefined,
- });
- }
- } else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
- if (self.air.value(callee)) |func_value| {
- if (func_value.castTag(.function)) |func_payload| {
- const func = func_payload.data;
- const fn_owner_decl = mod.declPtr(func.owner_decl);
+ } else if (self.bin_file.cast(link.File.Coff)) |_| {
try self.genSetReg(Type.initTag(.usize), .rax, .{
.linker_load = .{
.type = .got,
@@ -4045,19 +4024,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
}),
.data = undefined,
});
- } else if (func_value.castTag(.extern_fn)) |func_payload| {
- const extern_fn = func_payload.data;
- const decl_name = mod.declPtr(extern_fn.owner_decl).name;
- if (extern_fn.lib_name) |lib_name| {
- log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
- decl_name,
- lib_name,
- });
- }
- const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
+ } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
+ try fn_owner_decl.link.macho.ensureInitialized(macho_file);
+ const sym_index = fn_owner_decl.link.macho.getSymbolIndex().?;
try self.genSetReg(Type.initTag(.usize), .rax, .{
.linker_load = .{
- .type = .import,
+ .type = .got,
.sym_index = sym_index,
},
});
@@ -4069,36 +4041,37 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
}),
.data = undefined,
});
- } else {
- return self.fail("TODO implement calling bitcasted functions", .{});
+ } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
+ try p9.seeDecl(func.owner_decl);
+ const ptr_bits = self.target.cpu.arch.ptrBitWidth();
+ const ptr_bytes: u64 = @divExact(ptr_bits, 8);
+ const got_addr = p9.bases.data;
+ const got_index = fn_owner_decl.link.plan9.got_index.?;
+ const fn_got_addr = got_addr + got_index * ptr_bytes;
+ _ = try self.addInst(.{
+ .tag = .call,
+ .ops = Mir.Inst.Ops.encode(.{ .flags = 0b01 }),
+ .data = .{ .imm = @intCast(u32, fn_got_addr) },
+ });
+ } else unreachable;
+ } else if (func_value.castTag(.extern_fn)) |func_payload| {
+ const extern_fn = func_payload.data;
+ const decl_name = mod.declPtr(extern_fn.owner_decl).name;
+ if (extern_fn.lib_name) |lib_name| {
+ log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
+ decl_name,
+ lib_name,
+ });
}
- } else {
- assert(ty.zigTypeTag() == .Pointer);
- const mcv = try self.resolveInst(callee);
- try self.genSetReg(Type.initTag(.usize), .rax, mcv);
- _ = try self.addInst(.{
- .tag = .call,
- .ops = Mir.Inst.Ops.encode(.{
- .reg1 = .rax,
- .flags = 0b01,
- }),
- .data = undefined,
- });
- }
- } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
- if (self.air.value(callee)) |func_value| {
- if (func_value.castTag(.function)) |func_payload| {
- const func = func_payload.data;
- const fn_owner_decl = mod.declPtr(func.owner_decl);
- try fn_owner_decl.link.macho.ensureInitialized(macho_file);
- const sym_index = fn_owner_decl.link.macho.getSymbolIndex().?;
+
+ if (self.bin_file.cast(link.File.Coff)) |coff_file| {
+ const sym_index = try coff_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
try self.genSetReg(Type.initTag(.usize), .rax, .{
.linker_load = .{
- .type = .got,
+ .type = .import,
.sym_index = sym_index,
},
});
- // callq *%rax
_ = try self.addInst(.{
.tag = .call,
.ops = Mir.Inst.Ops.encode(.{
@@ -4107,15 +4080,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
}),
.data = undefined,
});
- } else if (func_value.castTag(.extern_fn)) |func_payload| {
- const extern_fn = func_payload.data;
- const decl_name = mod.declPtr(extern_fn.owner_decl).name;
- if (extern_fn.lib_name) |lib_name| {
- log.debug("TODO enforce that '{s}' is expected in '{s}' library", .{
- decl_name,
- lib_name,
- });
- }
+ } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
_ = try self.addInst(.{
.tag = .call_extern,
@@ -4128,50 +4093,24 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
},
});
} else {
- return self.fail("TODO implement calling bitcasted functions", .{});
+ return self.fail("TODO implement calling extern functions", .{});
}
} else {
- assert(ty.zigTypeTag() == .Pointer);
- const mcv = try self.resolveInst(callee);
- try self.genSetReg(Type.initTag(.usize), .rax, mcv);
- _ = try self.addInst(.{
- .tag = .call,
- .ops = Mir.Inst.Ops.encode(.{
- .reg1 = .rax,
- .flags = 0b01,
- }),
- .data = undefined,
- });
- }
- } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
- if (self.air.value(callee)) |func_value| {
- if (func_value.castTag(.function)) |func_payload| {
- try p9.seeDecl(func_payload.data.owner_decl);
- const ptr_bits = self.target.cpu.arch.ptrBitWidth();
- const ptr_bytes: u64 = @divExact(ptr_bits, 8);
- const got_addr = p9.bases.data;
- const got_index = mod.declPtr(func_payload.data.owner_decl).link.plan9.got_index.?;
- const fn_got_addr = got_addr + got_index * ptr_bytes;
- _ = try self.addInst(.{
- .tag = .call,
- .ops = Mir.Inst.Ops.encode(.{ .flags = 0b01 }),
- .data = .{ .imm = @intCast(u32, fn_got_addr) },
- });
- } else return self.fail("TODO implement calling extern fn on plan9", .{});
- } else {
- assert(ty.zigTypeTag() == .Pointer);
- const mcv = try self.resolveInst(callee);
- try self.genSetReg(Type.initTag(.usize), .rax, mcv);
- _ = try self.addInst(.{
- .tag = .call,
- .ops = Mir.Inst.Ops.encode(.{
- .reg1 = .rax,
- .flags = 0b01,
- }),
- .data = undefined,
- });
+ return self.fail("TODO implement calling bitcasted functions", .{});
}
- } else unreachable;
+ } else {
+ assert(ty.zigTypeTag() == .Pointer);
+ const mcv = try self.resolveInst(callee);
+ try self.genSetReg(Type.initTag(.usize), .rax, mcv);
+ _ = try self.addInst(.{
+ .tag = .call,
+ .ops = Mir.Inst.Ops.encode(.{
+ .reg1 = .rax,
+ .flags = 0b01,
+ }),
+ .data = undefined,
+ });
+ }
if (info.stack_byte_count > 0) {
// Readjust the stack