authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-18 20:01:44+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-01-18 20:01:44+01:00
log61b8d42d5cd35a4b57802bb4f394eca2cb935bd1
tree72f9d3a867cfb11d50d186188d4aa21fbe49af32
parent81183365852e7f871500a3f71810ae3b468f0027
parent458011f21fda961055a0fd7d280e33824c63c446
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7808 from joachimschmidt557/stage2-aarch64

Stage2 AArch64: Fix genSetStack

2 files changed, 88 insertions(+), 10 deletions(-)

src/codegen.zig+26-10
......@@ -641,20 +641,33 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
641641 const cc = self.fn_type.fnCallingConvention();
642642 if (cc != .Naked) {
643643 // TODO Finish function prologue and epilogue for aarch64.
644 // Reserve the stack for local variables, etc.
645644
646645 // stp fp, lr, [sp, #-16]!
646 // mov fp, sp
647 // sub sp, sp, #reloc
647648 writeInt(u32, try self.code.addManyAsArray(4), Instruction.stp(
648649 .x29,
649650 .x30,
650651 Register.sp,
651652 Instruction.LoadStorePairOffset.pre_index(-16),
652653 ).toU32());
654 writeInt(u32, try self.code.addManyAsArray(4), Instruction.add(.x29, .xzr, 0, false).toU32());
655 const backpatch_reloc = self.code.items.len;
656 try self.code.resize(backpatch_reloc + 4);
653657
654658 try self.dbgSetPrologueEnd();
655659
656660 try self.genBody(self.mod_fn.body);
657661
662 // Backpatch stack offset
663 const stack_end = self.max_end_stack;
664 const aligned_stack_end = mem.alignForward(stack_end, self.stack_align);
665 if (math.cast(u12, aligned_stack_end)) |size| {
666 writeInt(u32, self.code.items[backpatch_reloc..][0..4], Instruction.sub(.xzr, .xzr, size, false).toU32());
667 } else |_| {
668 return self.failSymbol("TODO AArch64: allow larger stacks", .{});
669 }
670
658671 try self.dbgSetEpilogueBegin();
659672
660673 // exitlude jumps
......@@ -690,6 +703,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
690703 Register.sp,
691704 Instruction.LoadStorePairOffset.post_index(16),
692705 ).toU32());
706 // add sp, sp, #stack_size
707 writeInt(u32, try self.code.addManyAsArray(4), Instruction.add(.xzr, .xzr, @intCast(u12, aligned_stack_end), false).toU32());
693708 // ret lr
694709 writeInt(u32, try self.code.addManyAsArray(4), Instruction.ret(null).toU32());
695710 } else {
......@@ -2685,9 +2700,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
26852700
26862701 switch (abi_size) {
26872702 1, 4 => {
2688 const offset = if (adj_off <= math.maxInt(u12)) blk: {
2689 break :blk Instruction.Offset.imm(@intCast(u12, adj_off));
2690 } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }), 0);
2703 const offset = if (math.cast(u12, adj_off)) |imm| blk: {
2704 break :blk Instruction.Offset.imm(imm);
2705 } else |_| Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }), 0);
26912706 const str = switch (abi_size) {
26922707 1 => Instruction.strb,
26932708 4 => Instruction.str,
......@@ -2848,12 +2863,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
28482863
28492864 switch (abi_size) {
28502865 4, 8 => {
2851 const offset = if (adj_off <= math.maxInt(u12)) blk: {
2852 break :blk Instruction.LoadStoreOffset.imm(@intCast(u12, adj_off));
2853 } else Instruction.LoadStoreOffset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }));
2854 const rn: Register = switch (abi_size) {
2855 4 => .w29,
2856 8 => .x29,
2866 const offset = if (math.cast(i9, adj_off)) |imm|
2867 Instruction.LoadStoreOffset.imm_post_index(-imm)
2868 else |_|
2869 Instruction.LoadStoreOffset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }));
2870 const rn: Register = switch (arch) {
2871 .aarch64, .aarch64_be => .x29,
2872 .aarch64_32 => .w29,
28572873 else => unreachable,
28582874 };
28592875
src/codegen/aarch64.zig+62
......@@ -274,6 +274,16 @@ pub const Instruction = union(enum) {
274274 opc: u2,
275275 sf: u1,
276276 },
277 AddSubtractImmediate: packed struct {
278 rd: u5,
279 rn: u5,
280 imm12: u12,
281 sh: u1,
282 fixed: u6 = 0b100010,
283 s: u1,
284 op: u1,
285 sf: u1,
286 },
277287
278288 pub const Shift = struct {
279289 shift: Type = .lsl,
......@@ -304,6 +314,7 @@ pub const Instruction = union(enum) {
304314 .UnconditionalBranchImmediate => |v| @bitCast(u32, v),
305315 .NoOperation => |v| @bitCast(u32, v),
306316 .LogicalShiftedRegister => |v| @bitCast(u32, v),
317 .AddSubtractImmediate => |v| @bitCast(u32, v),
307318 };
308319 }
309320
......@@ -671,6 +682,31 @@ pub const Instruction = union(enum) {
671682 }
672683 }
673684
685 fn addSubtractImmediate(
686 op: u1,
687 s: u1,
688 rd: Register,
689 rn: Register,
690 imm12: u12,
691 shift: bool,
692 ) Instruction {
693 return Instruction{
694 .AddSubtractImmediate = .{
695 .rd = rd.id(),
696 .rn = rn.id(),
697 .imm12 = imm12,
698 .sh = @boolToInt(shift),
699 .s = s,
700 .op = op,
701 .sf = switch (rd.size()) {
702 32 => 0b0,
703 64 => 0b1,
704 else => unreachable, // unexpected register size
705 },
706 },
707 };
708 }
709
674710 // Helper functions for assembly syntax functions
675711
676712 // Move wide (immediate)
......@@ -850,6 +886,24 @@ pub const Instruction = union(enum) {
850886 pub fn bics(rd: Register, rn: Register, rm: Register, shift: Shift) Instruction {
851887 return logicalShiftedRegister(0b11, 0b1, shift, rd, rn, rm);
852888 }
889
890 // Add/subtract (immediate)
891
892 pub fn add(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
893 return addSubtractImmediate(0b0, 0b0, rd, rn, imm, shift);
894 }
895
896 pub fn adds(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
897 return addSubtractImmediate(0b0, 0b1, rd, rn, imm, shift);
898 }
899
900 pub fn sub(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
901 return addSubtractImmediate(0b1, 0b0, rd, rn, imm, shift);
902 }
903
904 pub fn subs(rd: Register, rn: Register, imm: u12, shift: bool) Instruction {
905 return addSubtractImmediate(0b1, 0b1, rd, rn, imm, shift);
906 }
853907};
854908
855909test "" {
......@@ -979,6 +1033,14 @@ test "serialize instructions" {
9791033 .inst = Instruction.@"and"(.x0, .x4, .x2, .{ .shift = .lsl, .amount = 0x8 }),
9801034 .expected = 0b1_00_01010_00_0_00010_001000_00100_00000,
9811035 },
1036 .{ // add x0, x10, #10
1037 .inst = Instruction.add(.x0, .x10, 10, false),
1038 .expected = 0b1_0_0_100010_0_0000_0000_1010_01010_00000,
1039 },
1040 .{ // subs x0, x5, #11, lsl #12
1041 .inst = Instruction.subs(.x0, .x5, 11, true),
1042 .expected = 0b1_1_1_100010_1_0000_0000_1011_00101_00000,
1043 },
9821044 };
9831045
9841046 for (testcases) |case| {