| ... | @@ -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 delete | 449 | // the code. Therefore, we can just delete |
| 450 | // the space initially reserved for the | 450 | // the space initially reserved for the |
| 451 | // jump | 451 | // 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}); |
| 1758 | | 1758 | |
| | 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 | } |
| 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 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { | 2024 | fn 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, |