| ... | @@ -1785,6 +1785,15 @@ fn genBinMathOpMir( | ... | @@ -1785,6 +1785,15 @@ fn genBinMathOpMir( |
| 1785 | } | 1785 | } |
| 1786 | }, | 1786 | }, |
| 1787 | .stack_offset => |off| { | 1787 | .stack_offset => |off| { |
| | 1788 | if (off > math.maxInt(i32)) { |
| | 1789 | return self.fail("stack offset too large", .{}); |
| | 1790 | } |
| | 1791 | const abi_size = dst_ty.abiSize(self.target.*); |
| | 1792 | if (abi_size > 8) { |
| | 1793 | return self.fail("TODO implement ADD/SUB/CMP for stack dst with large ABI", .{}); |
| | 1794 | } |
| | 1795 | const adj_off = off + abi_size; |
| | 1796 | |
| 1788 | switch (src_mcv) { | 1797 | switch (src_mcv) { |
| 1789 | .none => unreachable, | 1798 | .none => unreachable, |
| 1790 | .undef => return self.genSetStack(dst_ty, off, .undef), | 1799 | .undef => return self.genSetStack(dst_ty, off, .undef), |
| ... | @@ -1792,11 +1801,6 @@ fn genBinMathOpMir( | ... | @@ -1792,11 +1801,6 @@ fn genBinMathOpMir( |
| 1792 | .ptr_stack_offset => unreachable, | 1801 | .ptr_stack_offset => unreachable, |
| 1793 | .ptr_embedded_in_code => unreachable, | 1802 | .ptr_embedded_in_code => unreachable, |
| 1794 | .register => |src_reg| { | 1803 | .register => |src_reg| { |
| 1795 | if (off > math.maxInt(i32)) { | | |
| 1796 | return self.fail("stack offset too large", .{}); | | |
| 1797 | } | | |
| 1798 | const abi_size = dst_ty.abiSize(self.target.*); | | |
| 1799 | const adj_off = off + abi_size; | | |
| 1800 | _ = try self.addInst(.{ | 1804 | _ = try self.addInst(.{ |
| 1801 | .tag = mir_tag, | 1805 | .tag = mir_tag, |
| 1802 | .ops = (Mir.Ops{ | 1806 | .ops = (Mir.Ops{ |
| ... | @@ -1808,8 +1812,34 @@ fn genBinMathOpMir( | ... | @@ -1808,8 +1812,34 @@ fn genBinMathOpMir( |
| 1808 | }); | 1812 | }); |
| 1809 | }, | 1813 | }, |
| 1810 | .immediate => |imm| { | 1814 | .immediate => |imm| { |
| 1811 | _ = imm; | 1815 | const tag: Mir.Inst.Tag = switch (mir_tag) { |
| 1812 | return self.fail("TODO implement x86 ADD/SUB/CMP source immediate", .{}); | 1816 | .add => .add_mem_imm, |
| | 1817 | .@"or" => .or_mem_imm, |
| | 1818 | .@"and" => .and_mem_imm, |
| | 1819 | .sub => .sub_mem_imm, |
| | 1820 | .xor => .xor_mem_imm, |
| | 1821 | .cmp => .cmp_mem_imm, |
| | 1822 | else => unreachable, |
| | 1823 | }; |
| | 1824 | const flags: u2 = switch (abi_size) { |
| | 1825 | 1 => 0b00, |
| | 1826 | 2 => 0b01, |
| | 1827 | 4 => 0b10, |
| | 1828 | 8 => 0b11, |
| | 1829 | else => unreachable, |
| | 1830 | }; |
| | 1831 | const payload = try self.addExtra(Mir.ImmPair{ |
| | 1832 | .dest_off = -@intCast(i32, adj_off), |
| | 1833 | .operand = @bitCast(i32, @intCast(u32, imm)), |
| | 1834 | }); |
| | 1835 | _ = try self.addInst(.{ |
| | 1836 | .tag = tag, |
| | 1837 | .ops = (Mir.Ops{ |
| | 1838 | .reg1 = .rbp, |
| | 1839 | .flags = flags, |
| | 1840 | }).encode(), |
| | 1841 | .data = .{ .payload = payload }, |
| | 1842 | }); |
| 1813 | }, | 1843 | }, |
| 1814 | .embedded_in_code, .memory, .stack_offset => { | 1844 | .embedded_in_code, .memory, .stack_offset => { |
| 1815 | return self.fail("TODO implement x86 ADD/SUB/CMP source memory", .{}); | 1845 | return self.fail("TODO implement x86 ADD/SUB/CMP source memory", .{}); |