| ... | ... | @@ -449,7 +449,7 @@ fn gen(self: *Self) !void { |
| 449 | 449 | // the code. Therefore, we can just delete |
| 450 | 450 | // the space initially reserved for the |
| 451 | 451 | // jump |
| 452 | | self.mir_instructions.len -= 1; |
| 452 | self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.items[0]); |
| 453 | 453 | } else for (self.exitlude_jump_relocs.items) |jmp_reloc| { |
| 454 | 454 | self.mir_instructions.set(jmp_reloc, .{ |
| 455 | 455 | .tag = .b, |
| ... | ... | @@ -1756,23 +1756,17 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo |
| 1756 | 1756 | self.register_manager.freezeRegs(&.{addr_reg}); |
| 1757 | 1757 | defer self.register_manager.unfreezeRegs(&.{addr_reg}); |
| 1758 | 1758 | |
| 1759 | const abi_size = elem_ty.abiSize(self.target.*); |
| 1759 | 1760 | switch (dst_mcv) { |
| 1760 | 1761 | .dead => unreachable, |
| 1761 | 1762 | .undef => unreachable, |
| 1762 | 1763 | .compare_flags_signed, .compare_flags_unsigned => unreachable, |
| 1763 | 1764 | .embedded_in_code => unreachable, |
| 1764 | 1765 | .register => |dst_reg| { |
| 1765 | | _ = try self.addInst(.{ |
| 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 | | }); |
| 1766 | try self.genLdrRegister(dst_reg, addr_reg, abi_size); |
| 1773 | 1767 | }, |
| 1774 | 1768 | .stack_offset => |off| { |
| 1775 | | if (elem_ty.abiSize(self.target.*) <= 8) { |
| 1769 | if (abi_size <= 8) { |
| 1776 | 1770 | const tmp_reg = try self.register_manager.allocReg(null); |
| 1777 | 1771 | self.register_manager.freezeRegs(&.{tmp_reg}); |
| 1778 | 1772 | defer self.register_manager.unfreezeRegs(&.{tmp_reg}); |
| ... | ... | @@ -1933,6 +1927,100 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1933 | 1927 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1934 | 1928 | } |
| 1935 | 1929 | |
| 1930 | fn 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 | |
| 1977 | fn 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 | |
| 1936 | 2024 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 1937 | 2025 | switch (ptr) { |
| 1938 | 2026 | .none => unreachable, |
| ... | ... | @@ -1953,8 +2041,28 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1953 | 2041 | .embedded_in_code => { |
| 1954 | 2042 | return self.fail("TODO implement storing to MCValue.embedded_in_code", .{}); |
| 1955 | 2043 | }, |
| 1956 | | .register => { |
| 1957 | | return self.fail("TODO implement storing to MCValue.register", .{}); |
| 2044 | .register => |addr_reg| { |
| 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 | 2067 | .memory, |
| 1960 | 2068 | .stack_offset, |