authorgravatar for miguel.p.paradinha@gmail.commparadinha <miguel.p.paradinha@gmail.com> 2022-02-02 08:48:00+00:00
committergravatar for miguel.p.paradinha@gmail.commparadinha <miguel.p.paradinha@gmail.com> 2022-02-02 09:24:39+00:00
logef4c54ba3836ecb4962f64f10b0b5c12188c9ff4
tree48b21c8ce57fa9615a256b7e58e341b0c73c7744
parentb67b89025cc12785f78a7908e321f8ed0b83afc6

need to go through the GOT, and use a temporary register


1 files changed, 57 insertions(+), 5 deletions(-)

src/arch/x86_64/CodeGen.zig+57-5
...@@ -1781,18 +1781,70 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type...@@ -1781,18 +1781,70 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
1781 }1781 }
1782 },1782 },
1783 .memory => |addr| {1783 .memory => |addr| {
1784 const reg = try self.copyToTmpRegister(ptr_ty, .{ .memory = addr });1784 // TODO: in case the address fits in an imm32 we can use [ds:imm32]
1785 // instead of wasting an instruction copying the address to a register
1786
1787 const addr_reg = try self.copyToTmpRegister(ptr_ty, .{ .immediate = addr });
1788 // to get the actual address of the value we want to modify we have to go through the GOT
1785 // mov reg, [reg]1789 // mov reg, [reg]
1786 _ = try self.addInst(.{1790 _ = try self.addInst(.{
1787 .tag = .mov,1791 .tag = .mov,
1788 .ops = (Mir.Ops{1792 .ops = (Mir.Ops{
1789 .reg1 = reg.to64(),1793 .reg1 = addr_reg.to64(),
1790 .reg2 = reg.to64(),1794 .reg2 = addr_reg.to64(),
1791 .flags = 0b10,1795 .flags = 0b01,
1792 }).encode(),1796 }).encode(),
1793 .data = .{ .imm = 0 },1797 .data = .{ .imm = 0 },
1794 });1798 });
1795 return self.store(.{ .register = reg }, value, ptr_ty, value_ty);1799
1800 const abi_size = value_ty.abiSize(self.target.*);
1801 switch (value) {
1802 .immediate => |imm| {
1803 const payload = try self.addExtra(Mir.ImmPair{
1804 .dest_off = 0,
1805 .operand = @intCast(u32, imm),
1806 });
1807 _ = try self.addInst(.{
1808 .tag = .mov_mem_imm,
1809 .ops = (Mir.Ops{
1810 .reg1 = addr_reg.to64(),
1811 .flags = switch (abi_size) {
1812 1 => 0b00,
1813 2 => 0b01,
1814 4 => 0b10,
1815 8 => flag: {
1816 const top_bits: u32 = @intCast(u32, imm >> 32);
1817 const can_extend = if (value_ty.isUnsignedInt())
1818 (top_bits == 0) and (imm & 0x8000_0000) == 0
1819 else
1820 top_bits == 0xffff_ffff;
1821
1822 if (!can_extend) {
1823 return self.fail("TODO imm64 would get incorrectly sign extended", .{});
1824 }
1825 break :flag 0b11;
1826 },
1827 else => {
1828 return self.fail("TODO saving imm to memory for abi_size {}", .{abi_size});
1829 },
1830 },
1831 }).encode(),
1832 .data = .{ .payload = payload },
1833 });
1834 },
1835 .register => |reg| {
1836 _ = try self.addInst(.{
1837 .tag = .mov,
1838 .ops = (Mir.Ops{
1839 .reg1 = addr_reg.to64(),
1840 .reg2 = reg,
1841 .flags = 0b10,
1842 }).encode(),
1843 .data = .{ .imm = 0 },
1844 });
1845 },
1846 else => return self.fail("TODO implement storing {} to MCValue.memory", .{value}),
1847 }
1796 },1848 },
1797 .stack_offset => {1849 .stack_offset => {
1798 return self.fail("TODO implement storing to MCValue.stack_offset", .{});1850 return self.fail("TODO implement storing to MCValue.stack_offset", .{});