authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2021-01-16 14:15:40+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-16 12:05:38-08:00
logfbd5fbe729b7d3f085d2d479ed9957decc019332
tree9cc38a723509ba28b64d7c0327e72fe7222e7dea
parentb204ea0349d5a580fc8ba9d8059c520301072072

stage2 AArch64: add very basic return values


2 files changed, 31 insertions(+), 16 deletions(-)

src/codegen.zig+17-3
...@@ -2935,8 +2935,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2935,8 +2935,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2935 ).toU32());2935 ).toU32());
2936 // ldr x28, [sp], #162936 // ldr x28, [sp], #16
2937 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{2937 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{
2938 .rn = Register.sp,2938 .register = .{
2939 .offset = Instruction.LoadStoreOffset.imm_post_index(16),2939 .rn = Register.sp,
2940 .offset = Instruction.LoadStoreOffset.imm_post_index(16),
2941 },
2940 }).toU32());2942 }).toU32());
2941 } else {2943 } else {
2942 // stp x0, x28, [sp, #-16]2944 // stp x0, x28, [sp, #-16]
...@@ -2978,7 +2980,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2978,7 +2980,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2978 // The value is in memory at a hard-coded address.2980 // The value is in memory at a hard-coded address.
2979 // If the type is a pointer, it means the pointer address is at this memory location.2981 // If the type is a pointer, it means the pointer address is at this memory location.
2980 try self.genSetReg(src, reg, .{ .immediate = addr });2982 try self.genSetReg(src, reg, .{ .immediate = addr });
2981 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(reg, .{ .rn = reg }).toU32());2983 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(reg, .{ .register = .{ .rn = reg } }).toU32());
2982 }2984 }
2983 },2985 },
2984 else => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),2986 else => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),
...@@ -3620,6 +3622,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3620,6 +3622,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3620 },3622 },
3621 else => return self.fail(src, "TODO implement function return values for {}", .{cc}),3623 else => return self.fail(src, "TODO implement function return values for {}", .{cc}),
3622 },3624 },
3625 .aarch64 => switch (cc) {
3626 .Naked => unreachable,
3627 .Unspecified, .C => {
3628 const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*));
3629 if (ret_ty_size <= 8) {
3630 result.return_value = .{ .register = c_abi_int_return_regs[0] };
3631 } else {
3632 return self.fail(src, "TODO support more return types for ARM backend", .{});
3633 }
3634 },
3635 else => return self.fail(src, "TODO implement function return values for {}", .{cc}),
3636 },
3623 else => return self.fail(src, "TODO implement codegen return values for {}", .{self.target.cpu.arch}),3637 else => return self.fail(src, "TODO implement codegen return values for {}", .{self.target.cpu.arch}),
3624 }3638 }
3625 return result;3639 return result;
src/codegen/aarch64.zig+14-13
...@@ -64,7 +64,7 @@ pub const callee_preserved_regs = [_]Register{...@@ -64,7 +64,7 @@ pub const callee_preserved_regs = [_]Register{
64};64};
6565
66pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };66pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
67pub const c_abi_int_return_regs = [_]Register{ .x0, .x1 };67pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
6868
69test "Register.id" {69test "Register.id" {
70 testing.expectEqual(@as(u5, 0), Register.x0.id());70 testing.expectEqual(@as(u5, 0), Register.x0.id());
...@@ -699,17 +699,18 @@ pub const Instruction = union(enum) {...@@ -699,17 +699,18 @@ pub const Instruction = union(enum) {
699699
700 // Load or store register700 // Load or store register
701701
702 pub const LdrArgs = struct {702 pub const LdrArgs = union(enum) {
703 rn: ?Register = null,703 register: struct {
704 offset: LoadStoreOffset = LoadStoreOffset.none,704 rn: Register,
705 literal: ?u19 = null,705 offset: LoadStoreOffset = LoadStoreOffset.none,
706 },
707 literal: u19,
706 };708 };
707709
708 pub fn ldr(rt: Register, args: LdrArgs) Instruction {710 pub fn ldr(rt: Register, args: LdrArgs) Instruction {
709 if (args.rn) |rn| {711 switch (args) {
710 return loadStoreRegister(rt, rn, args.offset, true);712 .register => |info| return loadStoreRegister(rt, info.rn, info.offset, true),
711 } else {713 .literal => |literal| return loadLiteral(rt, literal),
712 return loadLiteral(rt, args.literal.?);
713 }714 }
714 }715 }
715716
...@@ -911,19 +912,19 @@ test "serialize instructions" {...@@ -911,19 +912,19 @@ test "serialize instructions" {
911 .expected = 0b1_00101_00_0000_0000_0000_0000_0000_0100,912 .expected = 0b1_00101_00_0000_0000_0000_0000_0000_0100,
912 },913 },
913 .{ // ldr x2, [x1]914 .{ // ldr x2, [x1]
914 .inst = Instruction.ldr(.x2, .{ .rn = .x1 }),915 .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1 } }),
915 .expected = 0b11_111_0_01_01_000000000000_00001_00010,916 .expected = 0b11_111_0_01_01_000000000000_00001_00010,
916 },917 },
917 .{ // ldr x2, [x1, #1]!918 .{ // ldr x2, [x1, #1]!
918 .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_pre_index(1) }),919 .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_pre_index(1) } }),
919 .expected = 0b11_111_0_00_01_0_000000001_11_00001_00010,920 .expected = 0b11_111_0_00_01_0_000000001_11_00001_00010,
920 },921 },
921 .{ // ldr x2, [x1], #-1922 .{ // ldr x2, [x1], #-1
922 .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_post_index(-1) }),923 .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_post_index(-1) } }),
923 .expected = 0b11_111_0_00_01_0_111111111_01_00001_00010,924 .expected = 0b11_111_0_00_01_0_111111111_01_00001_00010,
924 },925 },
925 .{ // ldr x2, [x1], (x3)926 .{ // ldr x2, [x1], (x3)
926 .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.reg(.x3) }),927 .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.reg(.x3) } }),
927 .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010,928 .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010,
928 },929 },
929 .{ // ldr x2, label930 .{ // ldr x2, label