aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2020-12-09 07:56:49 +0100
committerJakub Konka <kubkon@jakubkonka.com>2020-12-09 17:20:58 +0100
commiteca0727417833b6c60cb2b30ba492ef816f4a4bc (patch)
tree1c6c89a45ae3c7fdd64e2568bfdae970a6848dff /src/codegen.zig
parent21dae538caa5eac71b52be5da59d3a18c05b3a89 (diff)
downloadzig-eca0727417833b6c60cb2b30ba492ef816f4a4bc.tar.gz
zig-eca0727417833b6c60cb2b30ba492ef816f4a4bc.zip
stage2+aarch64: use stp and ldp to navigate MachO jump table
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig55
1 files changed, 29 insertions, 26 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index f1e1d2b8e4..240b400e59 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -2730,13 +2730,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
// For MachO, the binary, with the exception of object files, has to be a PIE.
// Therefore we cannot load an absolute address.
// Instead, we need to make use of PC-relative addressing.
- // TODO This needs to be optimised in the stack usage (perhaps use a shadow stack
- // like described here:
- // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/using-the-stack-in-aarch64-implementing-push-and-pop)
- // TODO As far as branching is concerned, instead of saving the return address
- // in a register, I'm thinking here of immitating x86_64, and having the address
- // passed on the stack.
if (reg.id() == 0) { // x0 is special-cased
+ // TODO This needs to be optimised in the stack usage (perhaps use a shadow stack
+ // like described here:
+ // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/using-the-stack-in-aarch64-implementing-push-and-pop)
// str x28, [sp, #-16]
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x28, Register.sp, .{
.offset = Instruction.Offset.imm_pre_index(-16),
@@ -2755,21 +2752,25 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
// b [label]
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
// mov r, x0
- mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(reg, .x0, Instruction.RegisterShift.none()).toU32());
+ mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(
+ reg,
+ .x0,
+ Instruction.RegisterShift.none(),
+ ).toU32());
// ldr x28, [sp], #16
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{
.rn = Register.sp,
.offset = Instruction.Offset.imm_post_index(16),
}).toU32());
} else {
- // str x28, [sp, #-16]
- mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x28, Register.sp, .{
- .offset = Instruction.Offset.imm_pre_index(-16),
- }).toU32());
- // str x0, [sp, #-16]
- mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x0, Register.sp, .{
- .offset = Instruction.Offset.imm_pre_index(-16),
- }).toU32());
+ // stp x0, x28, [sp, #-16]
+ mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.stp(
+ .x0,
+ .x28,
+ Register.sp,
+ -2,
+ .SignedOffset,
+ ).toU32());
// adr x28, #8
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
if (self.bin_file.cast(link.File.MachO)) |macho_file| {
@@ -2784,17 +2785,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
// b [label]
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
// mov r, x0
- mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(reg, .x0, Instruction.RegisterShift.none()).toU32());
- // ldr x0, [sp], #16
- mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x0, .{
- .rn = Register.sp,
- .offset = Instruction.Offset.imm_post_index(16),
- }).toU32());
- // ldr x28, [sp], #16
- mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{
- .rn = Register.sp,
- .offset = Instruction.Offset.imm_post_index(16),
- }).toU32());
+ mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(
+ reg,
+ .x0,
+ Instruction.RegisterShift.none(),
+ ).toU32());
+ // ldp x0, x28, [sp, #16]
+ mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldp(
+ .x0,
+ .x28,
+ Register.sp,
+ 2,
+ .SignedOffset,
+ ).toU32());
}
} else {
// The value is in memory at a hard-coded address.