| ... | @@ -1604,6 +1604,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1604,6 +1604,12 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 1604 | .stack_offset => |off| { | 1604 | .stack_offset => |off| { |
| 1605 | break :inner off; | 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 | else => return self.fail("TODO implement array_elem_val when array is {}", .{array}), | 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,6 +1851,42 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1845 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 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 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { | 1890 | fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void { |
| 1849 | _ = ptr_ty; | 1891 | _ = ptr_ty; |
| 1850 | const abi_size = value_ty.abiSize(self.target.*); | 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,41 +1997,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type |
| 1955 | value.freezeIfRegister(&self.register_manager); | 1997 | value.freezeIfRegister(&self.register_manager); |
| 1956 | defer value.unfreezeIfRegister(&self.register_manager); | 1998 | defer value.unfreezeIfRegister(&self.register_manager); |
| 1957 | | 1999 | |
| 1958 | const addr_reg: Register = blk: { | 2000 | const addr_reg = try self.loadMemPtrIntoRegister(ptr_ty, ptr); |
| 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 | }; | | |
| 1993 | | 2001 | |
| 1994 | // to get the actual address of the value we want to modify we have to go through the GOT | 2002 | // to get the actual address of the value we want to modify we have to go through the GOT |
| 1995 | // mov reg, [reg] | 2003 | // mov reg, [reg] |
| ... | @@ -3831,33 +3839,11 @@ fn genInlineMemcpy(self: *Self, stack_offset: i32, stack_reg: Register, ty: Type | ... | @@ -3831,33 +3839,11 @@ fn genInlineMemcpy(self: *Self, stack_offset: i32, stack_reg: Register, ty: Type |
| 3831 | | 3839 | |
| 3832 | const addr_reg: Register = blk: { | 3840 | const addr_reg: Register = blk: { |
| 3833 | switch (val) { | 3841 | switch (val) { |
| 3834 | .memory => |addr| { | 3842 | .memory, |
| 3835 | const reg = try self.copyToTmpRegister(Type.usize, .{ .immediate = addr }); | | |
| 3836 | break :blk reg; | | |
| 3837 | }, | | |
| 3838 | .direct_load, | 3843 | .direct_load, |
| 3839 | .got_load, | 3844 | .got_load, |
| 3840 | => |sym_index| { | 3845 | => { |
| 3841 | const flags: u2 = switch (val) { | 3846 | break :blk try self.loadMemPtrIntoRegister(Type.usize, 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; | | |
| 3861 | }, | 3847 | }, |
| 3862 | .stack_offset => |off| { | 3848 | .stack_offset => |off| { |
| 3863 | const addr_reg = (try self.register_manager.allocReg(null)).to64(); | 3849 | const addr_reg = (try self.register_manager.allocReg(null)).to64(); |