diff --git a/src/codegen.zig b/src/codegen.zig index bfb1540e40..7c67a9191b 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -2935,8 +2935,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { ).toU32()); // ldr x28, [sp], #16 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{ - .rn = Register.sp, - .offset = Instruction.LoadStoreOffset.imm_post_index(16), + .register = .{ + .rn = Register.sp, + .offset = Instruction.LoadStoreOffset.imm_post_index(16), + }, }).toU32()); } else { // stp x0, x28, [sp, #-16] @@ -2978,7 +2980,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { // 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. try self.genSetReg(src, reg, .{ .immediate = addr }); - mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(reg, .{ .rn = reg }).toU32()); + mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(reg, .{ .register = .{ .rn = reg } }).toU32()); } }, else => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}), @@ -3620,6 +3622,18 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { }, else => return self.fail(src, "TODO implement function return values for {}", .{cc}), }, + .aarch64 => switch (cc) { + .Naked => unreachable, + .Unspecified, .C => { + const ret_ty_size = @intCast(u32, ret_ty.abiSize(self.target.*)); + if (ret_ty_size <= 8) { + result.return_value = .{ .register = c_abi_int_return_regs[0] }; + } else { + return self.fail(src, "TODO support more return types for ARM backend", .{}); + } + }, + else => return self.fail(src, "TODO implement function return values for {}", .{cc}), + }, else => return self.fail(src, "TODO implement codegen return values for {}", .{self.target.cpu.arch}), } return result; diff --git a/src/codegen/aarch64.zig b/src/codegen/aarch64.zig index 50cdf6a262..5fba1ea7e1 100644 --- a/src/codegen/aarch64.zig +++ b/src/codegen/aarch64.zig @@ -64,7 +64,7 @@ pub const callee_preserved_regs = [_]Register{ }; pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 }; -pub const c_abi_int_return_regs = [_]Register{ .x0, .x1 }; +pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 }; test "Register.id" { testing.expectEqual(@as(u5, 0), Register.x0.id()); @@ -699,17 +699,18 @@ pub const Instruction = union(enum) { // Load or store register - pub const LdrArgs = struct { - rn: ?Register = null, - offset: LoadStoreOffset = LoadStoreOffset.none, - literal: ?u19 = null, + pub const LdrArgs = union(enum) { + register: struct { + rn: Register, + offset: LoadStoreOffset = LoadStoreOffset.none, + }, + literal: u19, }; pub fn ldr(rt: Register, args: LdrArgs) Instruction { - if (args.rn) |rn| { - return loadStoreRegister(rt, rn, args.offset, true); - } else { - return loadLiteral(rt, args.literal.?); + switch (args) { + .register => |info| return loadStoreRegister(rt, info.rn, info.offset, true), + .literal => |literal| return loadLiteral(rt, literal), } } @@ -911,19 +912,19 @@ test "serialize instructions" { .expected = 0b1_00101_00_0000_0000_0000_0000_0000_0100, }, .{ // ldr x2, [x1] - .inst = Instruction.ldr(.x2, .{ .rn = .x1 }), + .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1 } }), .expected = 0b11_111_0_01_01_000000000000_00001_00010, }, .{ // ldr x2, [x1, #1]! - .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_pre_index(1) }), + .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_pre_index(1) } }), .expected = 0b11_111_0_00_01_0_000000001_11_00001_00010, }, .{ // ldr x2, [x1], #-1 - .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_post_index(-1) }), + .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.imm_post_index(-1) } }), .expected = 0b11_111_0_00_01_0_111111111_01_00001_00010, }, .{ // ldr x2, [x1], (x3) - .inst = Instruction.ldr(.x2, .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.reg(.x3) }), + .inst = Instruction.ldr(.x2, .{ .register = .{ .rn = .x1, .offset = Instruction.LoadStoreOffset.reg(.x3) } }), .expected = 0b11_111_0_00_01_1_00011_011_0_10_00001_00010, }, .{ // ldr x2, label