authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-19 19:37:49+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-21 22:44:40+01:00
loga9154a7eaf3e126ade91732df3ee14f3988b08f5
treea935ac94a163ee68fe1041d5c946319a3396b053
parentd8da9a01fcfebf14a9f262cabf36f1c0767d2e2b
signaturelock-open Commit is signed but in an unrecognized format.

stage2 AArch64: implement storing to memory


2 files changed, 121 insertions(+), 13 deletions(-)

src/arch/aarch64/CodeGen.zig+120-12
...@@ -449,7 +449,7 @@ fn gen(self: *Self) !void {...@@ -449,7 +449,7 @@ fn gen(self: *Self) !void {
449 // the code. Therefore, we can just delete449 // the code. Therefore, we can just delete
450 // the space initially reserved for the450 // the space initially reserved for the
451 // jump451 // jump
452 self.mir_instructions.len -= 1;452 self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.items[0]);
453 } else for (self.exitlude_jump_relocs.items) |jmp_reloc| {453 } else for (self.exitlude_jump_relocs.items) |jmp_reloc| {
454 self.mir_instructions.set(jmp_reloc, .{454 self.mir_instructions.set(jmp_reloc, .{
455 .tag = .b,455 .tag = .b,
...@@ -1756,23 +1756,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo...@@ -1756,23 +1756,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
1756 self.register_manager.freezeRegs(&.{addr_reg});1756 self.register_manager.freezeRegs(&.{addr_reg});
1757 defer self.register_manager.unfreezeRegs(&.{addr_reg});1757 defer self.register_manager.unfreezeRegs(&.{addr_reg});
17581758
1759 const abi_size = elem_ty.abiSize(self.target.*);
1759 switch (dst_mcv) {1760 switch (dst_mcv) {
1760 .dead => unreachable,1761 .dead => unreachable,
1761 .undef => unreachable,1762 .undef => unreachable,
1762 .compare_flags_signed, .compare_flags_unsigned => unreachable,1763 .compare_flags_signed, .compare_flags_unsigned => unreachable,
1763 .embedded_in_code => unreachable,1764 .embedded_in_code => unreachable,
1764 .register => |dst_reg| {1765 .register => |dst_reg| {
1765 _ = try self.addInst(.{1766 try self.genLdrRegister(dst_reg, addr_reg, abi_size);
1766 .tag = .ldr_immediate,
1767 .data = .{ .load_store_register_immediate = .{
1768 .rt = dst_reg,
1769 .rn = addr_reg,
1770 .offset = Instruction.LoadStoreOffset.none.immediate,
1771 } },
1772 });
1773 },1767 },
1774 .stack_offset => |off| {1768 .stack_offset => |off| {
1775 if (elem_ty.abiSize(self.target.*) <= 8) {1769 if (abi_size <= 8) {
1776 const tmp_reg = try self.register_manager.allocReg(null);1770 const tmp_reg = try self.register_manager.allocReg(null);
1777 self.register_manager.freezeRegs(&.{tmp_reg});1771 self.register_manager.freezeRegs(&.{tmp_reg});
1778 defer self.register_manager.unfreezeRegs(&.{tmp_reg});1772 defer self.register_manager.unfreezeRegs(&.{tmp_reg});
...@@ -1933,6 +1927,100 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -1933,6 +1927,100 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1933 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });1927 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
1934}1928}
19351929
1930fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, abi_size: u64) !void {
1931 switch (abi_size) {
1932 1 => {
1933 _ = try self.addInst(.{
1934 .tag = .ldrb_immediate,
1935 .data = .{ .load_store_register_immediate = .{
1936 .rt = value_reg.to32(),
1937 .rn = addr_reg,
1938 .offset = Instruction.LoadStoreOffset.none.immediate,
1939 } },
1940 });
1941 },
1942 2 => {
1943 _ = try self.addInst(.{
1944 .tag = .ldrh_immediate,
1945 .data = .{ .load_store_register_immediate = .{
1946 .rt = value_reg.to32(),
1947 .rn = addr_reg,
1948 .offset = Instruction.LoadStoreOffset.none.immediate,
1949 } },
1950 });
1951 },
1952 4 => {
1953 _ = try self.addInst(.{
1954 .tag = .ldr_immediate,
1955 .data = .{ .load_store_register_immediate = .{
1956 .rt = value_reg.to32(),
1957 .rn = addr_reg,
1958 .offset = Instruction.LoadStoreOffset.none.immediate,
1959 } },
1960 });
1961 },
1962 8 => {
1963 _ = try self.addInst(.{
1964 .tag = .ldr_immediate,
1965 .data = .{ .load_store_register_immediate = .{
1966 .rt = value_reg.to64(),
1967 .rn = addr_reg,
1968 .offset = Instruction.LoadStoreOffset.none.immediate,
1969 } },
1970 });
1971 },
1972 3, 5, 6, 7 => return self.fail("TODO: genLdrRegister for more abi_sizes", .{}),
1973 else => unreachable,
1974 }
1975}
1976
1977fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, abi_size: u64) !void {
1978 switch (abi_size) {
1979 1 => {
1980 _ = try self.addInst(.{
1981 .tag = .strb_immediate,
1982 .data = .{ .load_store_register_immediate = .{
1983 .rt = value_reg.to32(),
1984 .rn = addr_reg,
1985 .offset = Instruction.LoadStoreOffset.none.immediate,
1986 } },
1987 });
1988 },
1989 2 => {
1990 _ = try self.addInst(.{
1991 .tag = .strh_immediate,
1992 .data = .{ .load_store_register_immediate = .{
1993 .rt = value_reg.to32(),
1994 .rn = addr_reg,
1995 .offset = Instruction.LoadStoreOffset.none.immediate,
1996 } },
1997 });
1998 },
1999 4 => {
2000 _ = try self.addInst(.{
2001 .tag = .str_immediate,
2002 .data = .{ .load_store_register_immediate = .{
2003 .rt = value_reg.to32(),
2004 .rn = addr_reg,
2005 .offset = Instruction.LoadStoreOffset.none.immediate,
2006 } },
2007 });
2008 },
2009 8 => {
2010 _ = try self.addInst(.{
2011 .tag = .str_immediate,
2012 .data = .{ .load_store_register_immediate = .{
2013 .rt = value_reg.to64(),
2014 .rn = addr_reg,
2015 .offset = Instruction.LoadStoreOffset.none.immediate,
2016 } },
2017 });
2018 },
2019 3, 5, 6, 7 => return self.fail("TODO: genStrRegister for more abi_sizes", .{}),
2020 else => unreachable,
2021 }
2022}
2023
1936fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {2024fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
1937 switch (ptr) {2025 switch (ptr) {
1938 .none => unreachable,2026 .none => unreachable,
...@@ -1953,8 +2041,28 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -1953,8 +2041,28 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
1953 .embedded_in_code => {2041 .embedded_in_code => {
1954 return self.fail("TODO implement storing to MCValue.embedded_in_code", .{});2042 return self.fail("TODO implement storing to MCValue.embedded_in_code", .{});
1955 },2043 },
1956 .register => {2044 .register => |addr_reg| {
1957 return self.fail("TODO implement storing to MCValue.register", .{});2045 self.register_manager.freezeRegs(&.{addr_reg});
2046 defer self.register_manager.unfreezeRegs(&.{addr_reg});
2047
2048 const abi_size = value_ty.abiSize(self.target.*);
2049 switch (value) {
2050 .register => |value_reg| {
2051 try self.genStrRegister(value_reg, addr_reg, abi_size);
2052 },
2053 else => {
2054 if (abi_size <= 8) {
2055 const tmp_reg = try self.register_manager.allocReg(null);
2056 self.register_manager.freezeRegs(&.{tmp_reg});
2057 defer self.register_manager.unfreezeRegs(&.{tmp_reg});
2058
2059 try self.genSetReg(value_ty, tmp_reg, value);
2060 try self.store(ptr, .{ .register = tmp_reg }, ptr_ty, value_ty);
2061 } else {
2062 return self.fail("TODO implement memcpy", .{});
2063 }
2064 },
2065 }
1958 },2066 },
1959 .memory,2067 .memory,
1960 .stack_offset,2068 .stack_offset,
test/behavior/basic.zig+1-1
...@@ -48,7 +48,7 @@ const g1: i32 = 1233 + 1;...@@ -48,7 +48,7 @@ const g1: i32 = 1233 + 1;
48var g2: i32 = 0;48var g2: i32 = 0;
4949
50test "global variables" {50test "global variables" {
51 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;51 if (builtin.zig_backend == .stage2_aarch64 and builtin.os.tag == .macos) return error.SkipZigTest;
52 try expect(g2 == 0);52 try expect(g2 == 0);
53 g2 = g1;53 g2 = g1;
54 try expect(g2 == 1234);54 try expect(g2 == 1234);