stage2 macho: add orr and orn instructions
This commit is contained in:
@@ -2588,17 +2588,64 @@ 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.
|
||||
// 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)
|
||||
// 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
|
||||
// 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());
|
||||
// adr x28, #8
|
||||
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
|
||||
try self.mod_fn.owner_decl.link.macho.addPieFixup(self.bin_file.allocator, .{
|
||||
.address = addr,
|
||||
.start = self.code.items.len,
|
||||
.len = 4,
|
||||
});
|
||||
// bl [label]
|
||||
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.bl(0).toU32());
|
||||
// } else {
|
||||
// unreachable; // TODO
|
||||
// }
|
||||
// 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 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());
|
||||
// adr x28, #8
|
||||
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
|
||||
try self.mod_fn.owner_decl.link.macho.addPieFixup(self.bin_file.allocator, .{
|
||||
.address = addr,
|
||||
.start = self.code.items.len,
|
||||
.len = 4,
|
||||
});
|
||||
// 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());
|
||||
}
|
||||
} else {
|
||||
// The value is in memory at a hard-coded address.
|
||||
// If the type is a pointer, it means the pointer address is at this memory location.
|
||||
|
||||
Reference in New Issue
Block a user