Commit a6bc19ea2a
Changed files (1)
src
src/codegen.zig
@@ -1643,61 +1643,64 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
else => return self.fail(inst.base.src, "TODO implement call for {}", .{self.target.cpu.arch}),
}
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
- switch (arch) {
- .x86_64 => {
- for (info.args) |mc_arg, arg_i| {
- const arg = inst.args[arg_i];
- const arg_mcv = try self.resolveInst(inst.args[arg_i]);
- // Here we do not use setRegOrMem even though the logic is similar, because
- // the function call will move the stack pointer, so the offsets are different.
- switch (mc_arg) {
- .none => continue,
- .register => |reg| {
- try self.genSetReg(arg.src, reg, arg_mcv);
- // TODO interact with the register allocator to mark the instruction as moved.
- },
- .stack_offset => {
- // Here we need to emit instructions like this:
- // mov qword ptr [rsp + stack_offset], x
- return self.fail(inst.base.src, "TODO implement calling with parameters in memory", .{});
- },
- .ptr_stack_offset => {
- return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_stack_offset arg", .{});
- },
- .ptr_embedded_in_code => {
- return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_embedded_in_code arg", .{});
- },
- .undef => unreachable,
- .immediate => unreachable,
- .unreach => unreachable,
- .dead => unreachable,
- .embedded_in_code => unreachable,
- .memory => unreachable,
- .compare_flags_signed => unreachable,
- .compare_flags_unsigned => unreachable,
- }
- }
+ for (info.args) |mc_arg, arg_i| {
+ const arg = inst.args[arg_i];
+ const arg_mcv = try self.resolveInst(inst.args[arg_i]);
+ // Here we do not use setRegOrMem even though the logic is similar, because
+ // the function call will move the stack pointer, so the offsets are different.
+ switch (mc_arg) {
+ .none => continue,
+ .register => |reg| {
+ try self.genSetReg(arg.src, reg, arg_mcv);
+ // TODO interact with the register allocator to mark the instruction as moved.
+ },
+ .stack_offset => {
+ // Here we need to emit instructions like this:
+ // mov qword ptr [rsp + stack_offset], x
+ return self.fail(inst.base.src, "TODO implement calling with parameters in memory", .{});
+ },
+ .ptr_stack_offset => {
+ return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_stack_offset arg", .{});
+ },
+ .ptr_embedded_in_code => {
+ return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_embedded_in_code arg", .{});
+ },
+ .undef => unreachable,
+ .immediate => unreachable,
+ .unreach => unreachable,
+ .dead => unreachable,
+ .embedded_in_code => unreachable,
+ .memory => unreachable,
+ .compare_flags_signed => unreachable,
+ .compare_flags_unsigned => unreachable,
+ }
+ }
- if (inst.func.cast(ir.Inst.Constant)) |func_inst| {
- if (func_inst.val.cast(Value.Payload.Function)) |func_val| {
- const func = func_val.func;
- const got = &macho_file.sections.items[macho_file.got_section_index.?];
- const got_addr = got.addr + func.owner_decl.link.macho.offset_table_index * @sizeOf(u64);
+ if (inst.func.cast(ir.Inst.Constant)) |func_inst| {
+ if (func_inst.val.cast(Value.Payload.Function)) |func_val| {
+ const func = func_val.func;
+ const got = &macho_file.sections.items[macho_file.got_section_index.?];
+ const got_addr = got.addr + func.owner_decl.link.macho.offset_table_index * @sizeOf(u64);
+ switch (arch) {
+ .x86_64 => {
// Here, we store the got address in %rax, and then call %rax
// movabsq [addr], %rax
try self.genSetReg(inst.base.src, .rax, .{ .memory = got_addr });
// callq *%rax
try self.code.ensureCapacity(self.code.items.len + 2);
self.code.appendSliceAssumeCapacity(&[2]u8{ 0xff, 0xd0 });
- } else {
- return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
- }
- } else {
- return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
+ },
+ .aarch64 => {
+ try self.genSetReg(inst.base.src, .x30, .{ .memory = got_addr });
+ writeInt(u32, try self.code.addManyAsArray(4), Instruction.blr(.x30).toU32());
+ },
+ else => unreachable, // unsupported architecture on MachO
}
- },
- .aarch64 => return self.fail(inst.base.src, "TODO implement codegen for call when linking with MachO for aarch64 arch", .{}),
- else => unreachable,
+ } else {
+ return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
+ }
+ } else {
+ return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
}
} else {
unreachable;