authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-03 14:00:28+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-03 14:00:28+01:00
loge52af268569e0005fb0c40c30154c50591e2fc6c
tree793f58aa9229761dd571fd9b9140f5e65f149207
parentb77757fe393dd8cdea1a2bd63a13939ec9beb706
parentef4c54ba3836ecb4962f64f10b0b5c12188c9ff4

Merge branch 'test-1486' of git://github.com/mparadinha/zig into mparadinha-test-1486


1 files changed, 83 insertions(+), 2 deletions(-)

src/arch/x86_64/CodeGen.zig+83-2
......@@ -1736,6 +1736,24 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
17361736 .data = .{ .payload = payload },
17371737 });
17381738 },
1739 8 => {
1740 // TODO: optimization: if the imm is only using the lower
1741 // 4 bytes and can be sign extended we can use a normal mov
1742 // with indirect addressing (mov [reg64], imm32).
1743
1744 // movabs does not support indirect register addressing
1745 // so we need an extra register and an extra mov.
1746 const tmp_reg = try self.copyToTmpRegister(value_ty, value);
1747 _ = try self.addInst(.{
1748 .tag = .mov,
1749 .ops = (Mir.Ops{
1750 .reg1 = reg.to64(),
1751 .reg2 = tmp_reg.to64(),
1752 .flags = 0b10,
1753 }).encode(),
1754 .data = .{ .imm = 0 },
1755 });
1756 },
17391757 else => {
17401758 return self.fail("TODO implement set pointee with immediate of ABI size {d}", .{abi_size});
17411759 },
......@@ -1758,8 +1776,71 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
17581776 },
17591777 }
17601778 },
1761 .memory => {
1762 return self.fail("TODO implement storing to MCValue.memory", .{});
1779 .memory => |addr| {
1780 // TODO: in case the address fits in an imm32 we can use [ds:imm32]
1781 // instead of wasting an instruction copying the address to a register
1782
1783 const addr_reg = try self.copyToTmpRegister(ptr_ty, .{ .immediate = addr });
1784 // to get the actual address of the value we want to modify we have to go through the GOT
1785 // mov reg, [reg]
1786 _ = try self.addInst(.{
1787 .tag = .mov,
1788 .ops = (Mir.Ops{
1789 .reg1 = addr_reg.to64(),
1790 .reg2 = addr_reg.to64(),
1791 .flags = 0b01,
1792 }).encode(),
1793 .data = .{ .imm = 0 },
1794 });
1795
1796 const abi_size = value_ty.abiSize(self.target.*);
1797 switch (value) {
1798 .immediate => |imm| {
1799 const payload = try self.addExtra(Mir.ImmPair{
1800 .dest_off = 0,
1801 .operand = @intCast(u32, imm),
1802 });
1803 _ = try self.addInst(.{
1804 .tag = .mov_mem_imm,
1805 .ops = (Mir.Ops{
1806 .reg1 = addr_reg.to64(),
1807 .flags = switch (abi_size) {
1808 1 => 0b00,
1809 2 => 0b01,
1810 4 => 0b10,
1811 8 => flag: {
1812 const top_bits: u32 = @intCast(u32, imm >> 32);
1813 const can_extend = if (value_ty.isUnsignedInt())
1814 (top_bits == 0) and (imm & 0x8000_0000) == 0
1815 else
1816 top_bits == 0xffff_ffff;
1817
1818 if (!can_extend) {
1819 return self.fail("TODO imm64 would get incorrectly sign extended", .{});
1820 }
1821 break :flag 0b11;
1822 },
1823 else => {
1824 return self.fail("TODO saving imm to memory for abi_size {}", .{abi_size});
1825 },
1826 },
1827 }).encode(),
1828 .data = .{ .payload = payload },
1829 });
1830 },
1831 .register => |reg| {
1832 _ = try self.addInst(.{
1833 .tag = .mov,
1834 .ops = (Mir.Ops{
1835 .reg1 = addr_reg.to64(),
1836 .reg2 = reg,
1837 .flags = 0b10,
1838 }).encode(),
1839 .data = .{ .imm = 0 },
1840 });
1841 },
1842 else => return self.fail("TODO implement storing {} to MCValue.memory", .{value}),
1843 }
17631844 },
17641845 .stack_offset => {
17651846 return self.fail("TODO implement storing to MCValue.stack_offset", .{});