| ... | ... | @@ -1604,6 +1604,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1604 | 1604 | .stack_offset => |off| { |
| 1605 | 1605 | break :inner off; |
| 1606 | 1606 | }, |
| 1607 | .memory, |
| 1608 | .got_load, |
| 1609 | .direct_load, |
| 1610 | => { |
| 1611 | break :blk try self.loadMemPtrIntoRegister(Type.usize, array); |
| 1612 | }, |
| 1607 | 1613 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), |
| 1608 | 1614 | } |
| 1609 | 1615 | }; |
| ... | ... | @@ -1845,6 +1851,42 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1845 | 1851 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| 1846 | 1852 | } |
| 1847 | 1853 | |
| 1854 | fn loadMemPtrIntoRegister(self: *Self, ptr_ty: Type, ptr: MCValue) InnerError!Register { |
| 1855 | switch (ptr) { |
| 1856 | .got_load, |
| 1857 | .direct_load, |
| 1858 | => |sym_index| { |
| 1859 | const flags: u2 = switch (ptr) { |
| 1860 | .got_load => 0b00, |
| 1861 | .direct_load => 0b01, |
| 1862 | else => unreachable, |
| 1863 | }; |
| 1864 | const reg = try self.register_manager.allocReg(null); |
| 1865 | _ = try self.addInst(.{ |
| 1866 | .tag = .lea_pie, |
| 1867 | .ops = (Mir.Ops{ |
| 1868 | .reg1 = reg.to64(), |
| 1869 | .flags = flags, |
| 1870 | }).encode(), |
| 1871 | .data = .{ |
| 1872 | .load_reloc = .{ |
| 1873 | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, |
| 1874 | .sym_index = sym_index, |
| 1875 | }, |
| 1876 | }, |
| 1877 | }); |
| 1878 | return reg.to64(); |
| 1879 | }, |
| 1880 | .memory => |addr| { |
| 1881 | // TODO: in case the address fits in an imm32 we can use [ds:imm32] |
| 1882 | // instead of wasting an instruction copying the address to a register |
| 1883 | const reg = try self.copyToTmpRegister(ptr_ty, .{ .immediate = addr }); |
| 1884 | return reg.to64(); |
| 1885 | }, |
| 1886 | else => unreachable, |
| 1887 | } |
| 1888 | } |
| 1889 | |
| 1848 | 1890 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 1849 | 1891 | _ = ptr_ty; |
| 1850 | 1892 | const abi_size = value_ty.abiSize(self.target.*); |
| ... | ... | @@ -1955,41 +1997,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1955 | 1997 | value.freezeIfRegister(&self.register_manager); |
| 1956 | 1998 | defer value.unfreezeIfRegister(&self.register_manager); |
| 1957 | 1999 | |
| 1958 | | const addr_reg: Register = blk: { |
| 1959 | | switch (ptr) { |
| 1960 | | .got_load, |
| 1961 | | .direct_load, |
| 1962 | | => |sym_index| { |
| 1963 | | const flags: u2 = switch (ptr) { |
| 1964 | | .got_load => 0b00, |
| 1965 | | .direct_load => 0b01, |
| 1966 | | else => unreachable, |
| 1967 | | }; |
| 1968 | | const addr_reg = try self.register_manager.allocReg(null); |
| 1969 | | _ = try self.addInst(.{ |
| 1970 | | .tag = .lea_pie, |
| 1971 | | .ops = (Mir.Ops{ |
| 1972 | | .reg1 = addr_reg.to64(), |
| 1973 | | .flags = flags, |
| 1974 | | }).encode(), |
| 1975 | | .data = .{ |
| 1976 | | .load_reloc = .{ |
| 1977 | | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, |
| 1978 | | .sym_index = sym_index, |
| 1979 | | }, |
| 1980 | | }, |
| 1981 | | }); |
| 1982 | | break :blk addr_reg; |
| 1983 | | }, |
| 1984 | | .memory => |addr| { |
| 1985 | | // TODO: in case the address fits in an imm32 we can use [ds:imm32] |
| 1986 | | // instead of wasting an instruction copying the address to a register |
| 1987 | | const addr_reg = try self.copyToTmpRegister(ptr_ty, .{ .immediate = addr }); |
| 1988 | | break :blk addr_reg; |
| 1989 | | }, |
| 1990 | | else => unreachable, |
| 1991 | | } |
| 1992 | | }; |
| 2000 | const addr_reg = try self.loadMemPtrIntoRegister(ptr_ty, ptr); |
| 1993 | 2001 | |
| 1994 | 2002 | // to get the actual address of the value we want to modify we have to go through the GOT |
| 1995 | 2003 | // mov reg, [reg] |
| ... | ... | @@ -3831,33 +3839,11 @@ fn genInlineMemcpy(self: *Self, stack_offset: i32, stack_reg: Register, ty: Type |
| 3831 | 3839 | |
| 3832 | 3840 | const addr_reg: Register = blk: { |
| 3833 | 3841 | switch (val) { |
| 3834 | | .memory => |addr| { |
| 3835 | | const reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = addr }); |
| 3836 | | break :blk reg; |
| 3837 | | }, |
| 3842 | .memory, |
| 3838 | 3843 | .direct_load, |
| 3839 | 3844 | .got_load, |
| 3840 | | => |sym_index| { |
| 3841 | | const flags: u2 = switch (val) { |
| 3842 | | .got_load => 0b00, |
| 3843 | | .direct_load => 0b01, |
| 3844 | | else => unreachable, |
| 3845 | | }; |
| 3846 | | const addr_reg = (try self.register_manager.allocReg(null)).to64(); |
| 3847 | | _ = try self.addInst(.{ |
| 3848 | | .tag = .lea_pie, |
| 3849 | | .ops = (Mir.Ops{ |
| 3850 | | .reg1 = addr_reg, |
| 3851 | | .flags = flags, |
| 3852 | | }).encode(), |
| 3853 | | .data = .{ |
| 3854 | | .load_reloc = .{ |
| 3855 | | .atom_index = self.mod_fn.owner_decl.link.macho.local_sym_index, |
| 3856 | | .sym_index = sym_index, |
| 3857 | | }, |
| 3858 | | }, |
| 3859 | | }); |
| 3860 | | break :blk addr_reg; |
| 3845 | => { |
| 3846 | break :blk try self.loadMemPtrIntoRegister(Type.usize, val); |
| 3861 | 3847 | }, |
| 3862 | 3848 | .stack_offset => |off| { |
| 3863 | 3849 | const addr_reg = (try self.register_manager.allocReg(null)).to64(); |