| ... | ... | @@ -1857,18 +1857,15 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1857 | 1857 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { |
| 1858 | 1858 | const tag = self.air.instructions.items(.tag)[inst]; |
| 1859 | 1859 | const ty = self.air.typeOf(bin_op.lhs); |
| 1860 | | const abi_size = ty.abiSize(self.target.*); |
| 1861 | 1860 | switch (ty.zigTypeTag()) { |
| 1862 | 1861 | .Vector => return self.fail("TODO implement add/sub/shl with overflow for Vector type", .{}), |
| 1863 | 1862 | .Int => { |
| 1864 | | if (abi_size > 8) { |
| 1865 | | return self.fail("TODO implement add/sub/shl with overflow for Ints larger than 64bits", .{}); |
| 1866 | | } |
| 1867 | | |
| 1868 | 1863 | try self.spillEflagsIfOccupied(); |
| 1869 | 1864 | |
| 1870 | 1865 | if (tag == .shl_with_overflow) { |
| 1871 | 1866 | try self.spillRegisters(&.{.rcx}); |
| 1867 | // cf/of don't work for shifts other than 1 |
| 1868 | return self.fail("TODO implement shl_with_overflow for x86_64", .{}); |
| 1872 | 1869 | } |
| 1873 | 1870 | |
| 1874 | 1871 | const partial: MCValue = switch (tag) { |
| ... | ... | @@ -1885,16 +1882,29 @@ fn airAddSubShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 1885 | 1882 | }; |
| 1886 | 1883 | |
| 1887 | 1884 | const int_info = ty.intInfo(self.target.*); |
| 1888 | | |
| 1889 | 1885 | if (int_info.bits >= 8 and math.isPowerOfTwo(int_info.bits)) { |
| 1890 | | self.eflags_inst = inst; |
| 1891 | | break :result .{ .register_overflow = .{ |
| 1892 | | .reg = partial.register, |
| 1893 | | .eflags = switch (int_info.signedness) { |
| 1894 | | .unsigned => .c, |
| 1895 | | .signed => .o, |
| 1886 | const cc: Condition = switch (int_info.signedness) { |
| 1887 | .unsigned => .c, |
| 1888 | .signed => .o, |
| 1889 | }; |
| 1890 | switch (partial) { |
| 1891 | .register => |reg| { |
| 1892 | self.eflags_inst = inst; |
| 1893 | break :result .{ .register_overflow = .{ .reg = reg, .eflags = cc } }; |
| 1896 | 1894 | }, |
| 1897 | | } }; |
| 1895 | else => {}, |
| 1896 | } |
| 1897 | |
| 1898 | const abi_size = @intCast(i32, ty.abiSize(self.target.*)); |
| 1899 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 1900 | try self.genSetStack( |
| 1901 | Type.u1, |
| 1902 | dst_mcv.stack_offset - abi_size, |
| 1903 | .{ .eflags = cc }, |
| 1904 | .{}, |
| 1905 | ); |
| 1906 | try self.genSetStack(ty, dst_mcv.stack_offset, partial, .{}); |
| 1907 | break :result dst_mcv; |
| 1898 | 1908 | } |
| 1899 | 1909 | |
| 1900 | 1910 | const tuple_ty = self.air.typeOfIndex(inst); |