mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2 ARM: implement airCall for function pointers
This commit is contained in:
parent
b100e2ec2a
commit
f8163f7eaf
@ -2238,10 +2238,16 @@ fn airFence(self: *Self) !void {
|
||||
|
||||
fn airCall(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
const fn_ty = self.air.typeOf(pl_op.operand);
|
||||
const callee = pl_op.operand;
|
||||
const extra = self.air.extraData(Air.Call, pl_op.payload);
|
||||
const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]);
|
||||
const ty = self.air.typeOf(callee);
|
||||
|
||||
const fn_ty = switch (ty.zigTypeTag()) {
|
||||
.Fn => ty,
|
||||
.Pointer => ty.childType(),
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
var info = try self.resolveCallingConventionValues(fn_ty);
|
||||
defer info.deinit(self);
|
||||
@ -2310,39 +2316,42 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
|
||||
unreachable;
|
||||
|
||||
try self.genSetReg(Type.initTag(.usize), .lr, .{ .memory = got_addr });
|
||||
|
||||
// TODO: add Instruction.supportedOn
|
||||
// function for ARM
|
||||
if (Target.arm.featureSetHas(self.target.cpu.features, .has_v5t)) {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .blx,
|
||||
.cond = .al,
|
||||
.data = .{ .reg = .lr },
|
||||
});
|
||||
} else {
|
||||
return self.fail("TODO fix blx emulatio for ARM <v5", .{});
|
||||
// _ = try self.addInst(.{
|
||||
// .tag = .mov,
|
||||
// .cond = .al,
|
||||
// .data = .{ .rr_op = .{
|
||||
// .rd = .lr,
|
||||
// .rn = .r0,
|
||||
// .op = Instruction.Operand.reg(.pc, Instruction.Operand.Shift.none),
|
||||
// } },
|
||||
// });
|
||||
// _ = try self.addInst(.{
|
||||
// .tag = .bx,
|
||||
// .cond = .al,
|
||||
// .data = .{ .reg = .lr },
|
||||
// });
|
||||
}
|
||||
} 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 {
|
||||
return self.fail("TODO implement calling runtime known function pointer", .{});
|
||||
assert(ty.zigTypeTag() == .Pointer);
|
||||
const mcv = try self.resolveInst(callee);
|
||||
|
||||
try self.genSetReg(Type.initTag(.usize), .lr, mcv);
|
||||
}
|
||||
|
||||
// TODO: add Instruction.supportedOn
|
||||
// function for ARM
|
||||
if (Target.arm.featureSetHas(self.target.cpu.features, .has_v5t)) {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .blx,
|
||||
.cond = .al,
|
||||
.data = .{ .reg = .lr },
|
||||
});
|
||||
} else {
|
||||
return self.fail("TODO fix blx emulation for ARM <v5", .{});
|
||||
// _ = try self.addInst(.{
|
||||
// .tag = .mov,
|
||||
// .cond = .al,
|
||||
// .data = .{ .rr_op = .{
|
||||
// .rd = .lr,
|
||||
// .rn = .r0,
|
||||
// .op = Instruction.Operand.reg(.pc, Instruction.Operand.Shift.none),
|
||||
// } },
|
||||
// });
|
||||
// _ = try self.addInst(.{
|
||||
// .tag = .bx,
|
||||
// .cond = .al,
|
||||
// .data = .{ .reg = .lr },
|
||||
// });
|
||||
}
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
unreachable; // unsupported architecture for MachO
|
||||
|
||||
@ -704,4 +704,52 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
"",
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
var case = ctx.exe("function pointers", linux_arm);
|
||||
case.addCompareOutput(
|
||||
\\const PrintFn = fn () void;
|
||||
\\
|
||||
\\pub fn main() void {
|
||||
\\ var printFn: PrintFn = stopSayingThat;
|
||||
\\ var i: u32 = 0;
|
||||
\\ while (i < 4) : (i += 1) printFn();
|
||||
\\
|
||||
\\ printFn = moveEveryZig;
|
||||
\\ printFn();
|
||||
\\}
|
||||
\\
|
||||
\\fn stopSayingThat() void {
|
||||
\\ asm volatile ("svc #0"
|
||||
\\ :
|
||||
\\ : [number] "{r7}" (4),
|
||||
\\ [arg1] "{r0}" (1),
|
||||
\\ [arg2] "{r1}" (@ptrToInt("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n")),
|
||||
\\ [arg3] "{r2}" ("Hello, my name is Inigo Montoya; you killed my father, prepare to die.\n".len),
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ return;
|
||||
\\}
|
||||
\\
|
||||
\\fn moveEveryZig() void {
|
||||
\\ asm volatile ("svc #0"
|
||||
\\ :
|
||||
\\ : [number] "{r7}" (4),
|
||||
\\ [arg1] "{r0}" (1),
|
||||
\\ [arg2] "{r1}" (@ptrToInt("All your codebase are belong to us\n")),
|
||||
\\ [arg3] "{r2}" ("All your codebase are belong to us\n".len),
|
||||
\\ : "memory"
|
||||
\\ );
|
||||
\\ return;
|
||||
\\}
|
||||
,
|
||||
\\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
|
||||
\\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
|
||||
\\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
|
||||
\\Hello, my name is Inigo Montoya; you killed my father, prepare to die.
|
||||
\\All your codebase are belong to us
|
||||
\\
|
||||
,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user