authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2022-07-09 14:46:42+07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-09-14 16:57:31-07:00
logb9897c3b84caa566fadb76bb2070b30e443cff3c
tree8dd857c470e88b1c4cbc9792b317fb3d0225cab5
parent844d3a5a74778ba76d5dc05c0dd747e7f8b85d4d

stage2: sparc64: Implement airMulOverflow for <= 32 bits


1 files changed, 68 insertions(+), 1 deletions(-)

src/arch/sparc64/CodeGen.zig+68-1
...@@ -534,7 +534,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -534,7 +534,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
534534
535 .add_with_overflow => try self.airAddSubWithOverflow(inst),535 .add_with_overflow => try self.airAddSubWithOverflow(inst),
536 .sub_with_overflow => try self.airAddSubWithOverflow(inst),536 .sub_with_overflow => try self.airAddSubWithOverflow(inst),
537 .mul_with_overflow => @panic("TODO try self.airMulWithOverflow(inst)"),537 .mul_with_overflow => try self.airMulWithOverflow(inst),
538 .shl_with_overflow => @panic("TODO try self.airShlWithOverflow(inst)"),538 .shl_with_overflow => @panic("TODO try self.airShlWithOverflow(inst)"),
539539
540 .div_float, .div_trunc, .div_floor, .div_exact => try self.airDiv(inst),540 .div_float, .div_trunc, .div_floor, .div_exact => try self.airDiv(inst),
...@@ -1792,6 +1792,73 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {...@@ -1792,6 +1792,73 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
1792 return self.finishAir(inst, .{ .register = mod_reg }, .{ bin_op.lhs, bin_op.rhs, .none });1792 return self.finishAir(inst, .{ .register = mod_reg }, .{ bin_op.lhs, bin_op.rhs, .none });
1793}1793}
17941794
1795fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
1796 //const tag = self.air.instructions.items(.tag)[inst];
1797 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
1798 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1799 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1800 const lhs = try self.resolveInst(extra.lhs);
1801 const rhs = try self.resolveInst(extra.rhs);
1802 const lhs_ty = self.air.typeOf(extra.lhs);
1803 const rhs_ty = self.air.typeOf(extra.rhs);
1804
1805 switch (lhs_ty.zigTypeTag()) {
1806 .Vector => return self.fail("TODO implement mul_with_overflow for vectors", .{}),
1807 .Int => {
1808 const mod = self.bin_file.options.module.?;
1809 assert(lhs_ty.eql(rhs_ty, mod));
1810 const int_info = lhs_ty.intInfo(self.target.*);
1811 switch (int_info.bits) {
1812 1...32 => {
1813 try self.spillConditionFlagsIfOccupied();
1814 self.condition_flags_inst = inst;
1815
1816 const dest = try self.binOp(.mul, lhs, rhs, lhs_ty, rhs_ty, null);
1817
1818 const dest_reg = dest.register;
1819 const dest_reg_lock = self.register_manager.lockRegAssumeUnused(dest_reg);
1820 defer self.register_manager.unlockReg(dest_reg_lock);
1821
1822 const truncated_reg = try self.register_manager.allocReg(null, gp);
1823 const truncated_reg_lock = self.register_manager.lockRegAssumeUnused(truncated_reg);
1824 defer self.register_manager.unlockReg(truncated_reg_lock);
1825
1826 try self.truncRegister(
1827 dest_reg,
1828 truncated_reg,
1829 int_info.signedness,
1830 int_info.bits,
1831 );
1832
1833 _ = try self.addInst(.{
1834 .tag = .cmp,
1835 .data = .{ .arithmetic_2op = .{
1836 .is_imm = false,
1837 .rs1 = dest_reg,
1838 .rs2_or_imm = .{ .rs2 = truncated_reg },
1839 } },
1840 });
1841
1842 const cond = Instruction.ICondition.ne;
1843 const ccr = Instruction.CCR.xcc;
1844
1845 break :result MCValue{ .register_with_overflow = .{
1846 .reg = truncated_reg,
1847 .flag = .{ .cond = cond, .ccr = ccr },
1848 } };
1849 },
1850 // XXX DO NOT call __multi3 directly as it'll result in us doing six multiplications,
1851 // which is far more than strictly necessary
1852 33...64 => return self.fail("TODO copy compiler-rt's mulddi3 for a 64x64->128 multiply", .{}),
1853 else => return self.fail("TODO overflow operations on other integer sizes", .{}),
1854 }
1855 },
1856 else => unreachable,
1857 }
1858 };
1859 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, .none });
1860}
1861
1795fn airNot(self: *Self, inst: Air.Inst.Index) !void {1862fn airNot(self: *Self, inst: Air.Inst.Index) !void {
1796 const ty_op = self.air.instructions.items(.data)[inst].ty_op;1863 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
1797 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {1864 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {