authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-10-28 09:07:03+02:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-28 03:48:18-04:00
log20a36641534cfb88e656944cf3d84aa667cb7ad0
treee927616df9cf6a3efeda4ada203c55a7b9d86fd2
parent396003fb06b7187917d2bebbfb494839988945fe

x86_64: handle .load_symbol in mul_with_overflow and mul_div


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

src/arch/x86_64/CodeGen.zig+83-30
......@@ -3873,39 +3873,65 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
38733873
38743874 const lhs_mcv = try self.resolveInst(bin_op.lhs);
38753875 const rhs_mcv = try self.resolveInst(bin_op.rhs);
3876 const mat_lhs_mcv = switch (lhs_mcv) {
3877 .load_symbol => mat_lhs_mcv: {
3878 // TODO clean this up!
3879 const addr_reg = try self.copyToTmpRegister(Type.usize, lhs_mcv.address());
3880 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
3881 },
3882 else => lhs_mcv,
3883 };
3884 const mat_lhs_lock = switch (mat_lhs_mcv) {
3885 .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg),
3886 else => null,
3887 };
3888 defer if (mat_lhs_lock) |lock| self.register_manager.unlockReg(lock);
3889 const mat_rhs_mcv = switch (rhs_mcv) {
3890 .load_symbol => mat_rhs_mcv: {
3891 // TODO clean this up!
3892 const addr_reg = try self.copyToTmpRegister(Type.usize, rhs_mcv.address());
3893 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
3894 },
3895 else => rhs_mcv,
3896 };
3897 const mat_rhs_lock = switch (mat_rhs_mcv) {
3898 .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg),
3899 else => null,
3900 };
3901 defer if (mat_rhs_lock) |lock| self.register_manager.unlockReg(lock);
38763902
3877 if (lhs_mcv.isMemory())
3878 try self.asmRegisterMemory(.{ ._, .mov }, .rax, lhs_mcv.mem(.qword))
3903 if (mat_lhs_mcv.isMemory())
3904 try self.asmRegisterMemory(.{ ._, .mov }, .rax, mat_lhs_mcv.mem(.qword))
38793905 else
3880 try self.asmRegisterRegister(.{ ._, .mov }, .rax, lhs_mcv.register_pair[0]);
3881 if (rhs_mcv.isMemory()) try self.asmRegisterMemory(
3906 try self.asmRegisterRegister(.{ ._, .mov }, .rax, mat_lhs_mcv.register_pair[0]);
3907 if (mat_rhs_mcv.isMemory()) try self.asmRegisterMemory(
38823908 .{ ._, .mov },
38833909 tmp_regs[0],
3884 rhs_mcv.address().offset(8).deref().mem(.qword),
3910 mat_rhs_mcv.address().offset(8).deref().mem(.qword),
38853911 ) else try self.asmRegisterRegister(
38863912 .{ ._, .mov },
38873913 tmp_regs[0],
3888 rhs_mcv.register_pair[1],
3914 mat_rhs_mcv.register_pair[1],
38893915 );
38903916 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]);
38913917 try self.asmSetccRegister(.nz, tmp_regs[1].to8());
38923918 try self.asmRegisterRegister(.{ .i_, .mul }, tmp_regs[0], .rax);
38933919 try self.asmSetccRegister(.o, tmp_regs[2].to8());
3894 if (rhs_mcv.isMemory())
3895 try self.asmMemory(.{ ._, .mul }, rhs_mcv.mem(.qword))
3920 if (mat_rhs_mcv.isMemory())
3921 try self.asmMemory(.{ ._, .mul }, mat_rhs_mcv.mem(.qword))
38963922 else
3897 try self.asmRegister(.{ ._, .mul }, rhs_mcv.register_pair[0]);
3923 try self.asmRegister(.{ ._, .mul }, mat_rhs_mcv.register_pair[0]);
38983924 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_regs[0]);
38993925 try self.asmSetccRegister(.c, tmp_regs[3].to8());
39003926 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[2].to8(), tmp_regs[3].to8());
3901 if (lhs_mcv.isMemory()) try self.asmRegisterMemory(
3927 if (mat_lhs_mcv.isMemory()) try self.asmRegisterMemory(
39023928 .{ ._, .mov },
39033929 tmp_regs[0],
3904 lhs_mcv.address().offset(8).deref().mem(.qword),
3930 mat_lhs_mcv.address().offset(8).deref().mem(.qword),
39053931 ) else try self.asmRegisterRegister(
39063932 .{ ._, .mov },
39073933 tmp_regs[0],
3908 lhs_mcv.register_pair[1],
3934 mat_lhs_mcv.register_pair[1],
39093935 );
39103936 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]);
39113937 try self.asmSetccRegister(.nz, tmp_regs[3].to8());
......@@ -3915,13 +3941,13 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
39153941 tmp_regs[3].to8(),
39163942 );
39173943 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8());
3918 if (rhs_mcv.isMemory())
3919 try self.asmRegisterMemory(.{ .i_, .mul }, tmp_regs[0], rhs_mcv.mem(.qword))
3944 if (mat_rhs_mcv.isMemory())
3945 try self.asmRegisterMemory(.{ .i_, .mul }, tmp_regs[0], mat_rhs_mcv.mem(.qword))
39203946 else
39213947 try self.asmRegisterRegister(
39223948 .{ .i_, .mul },
39233949 tmp_regs[0],
3924 rhs_mcv.register_pair[0],
3950 mat_rhs_mcv.register_pair[0],
39253951 );
39263952 try self.asmSetccRegister(.o, tmp_regs[2].to8());
39273953 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8());
......@@ -7359,34 +7385,61 @@ fn genMulDivBinOp(
73597385 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
73607386 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);
73617387
7388 const mat_lhs_mcv = switch (lhs_mcv) {
7389 .load_symbol => mat_lhs_mcv: {
7390 // TODO clean this up!
7391 const addr_reg = try self.copyToTmpRegister(Type.usize, lhs_mcv.address());
7392 break :mat_lhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
7393 },
7394 else => lhs_mcv,
7395 };
7396 const mat_lhs_lock = switch (mat_lhs_mcv) {
7397 .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg),
7398 else => null,
7399 };
7400 defer if (mat_lhs_lock) |lock| self.register_manager.unlockReg(lock);
7401 const mat_rhs_mcv = switch (rhs_mcv) {
7402 .load_symbol => mat_rhs_mcv: {
7403 // TODO clean this up!
7404 const addr_reg = try self.copyToTmpRegister(Type.usize, rhs_mcv.address());
7405 break :mat_rhs_mcv MCValue{ .indirect = .{ .reg = addr_reg } };
7406 },
7407 else => rhs_mcv,
7408 };
7409 const mat_rhs_lock = switch (mat_rhs_mcv) {
7410 .indirect => |reg_off| self.register_manager.lockReg(reg_off.reg),
7411 else => null,
7412 };
7413 defer if (mat_rhs_lock) |lock| self.register_manager.unlockReg(lock);
7414
73627415 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
73637416 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
73647417 defer self.register_manager.unlockReg(tmp_lock);
73657418
7366 if (lhs_mcv.isMemory())
7367 try self.asmRegisterMemory(.{ ._, .mov }, .rax, lhs_mcv.mem(.qword))
7419 if (mat_lhs_mcv.isMemory())
7420 try self.asmRegisterMemory(.{ ._, .mov }, .rax, mat_lhs_mcv.mem(.qword))
73687421 else
7369 try self.asmRegisterRegister(.{ ._, .mov }, .rax, lhs_mcv.register_pair[0]);
7370 if (rhs_mcv.isMemory()) try self.asmRegisterMemory(
7422 try self.asmRegisterRegister(.{ ._, .mov }, .rax, mat_lhs_mcv.register_pair[0]);
7423 if (mat_rhs_mcv.isMemory()) try self.asmRegisterMemory(
73717424 .{ ._, .mov },
73727425 tmp_reg,
7373 rhs_mcv.address().offset(8).deref().mem(.qword),
7374 ) else try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, rhs_mcv.register_pair[1]);
7426 mat_rhs_mcv.address().offset(8).deref().mem(.qword),
7427 ) else try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, mat_rhs_mcv.register_pair[1]);
73757428 try self.asmRegisterRegister(.{ .i_, .mul }, tmp_reg, .rax);
7376 if (rhs_mcv.isMemory())
7377 try self.asmMemory(.{ ._, .mul }, rhs_mcv.mem(.qword))
7429 if (mat_rhs_mcv.isMemory())
7430 try self.asmMemory(.{ ._, .mul }, mat_rhs_mcv.mem(.qword))
73787431 else
7379 try self.asmRegister(.{ ._, .mul }, rhs_mcv.register_pair[0]);
7432 try self.asmRegister(.{ ._, .mul }, mat_rhs_mcv.register_pair[0]);
73807433 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_reg);
7381 if (lhs_mcv.isMemory()) try self.asmRegisterMemory(
7434 if (mat_lhs_mcv.isMemory()) try self.asmRegisterMemory(
73827435 .{ ._, .mov },
73837436 tmp_reg,
7384 lhs_mcv.address().offset(8).deref().mem(.qword),
7385 ) else try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, lhs_mcv.register_pair[1]);
7386 if (rhs_mcv.isMemory())
7387 try self.asmRegisterMemory(.{ .i_, .mul }, tmp_reg, rhs_mcv.mem(.qword))
7437 mat_lhs_mcv.address().offset(8).deref().mem(.qword),
7438 ) else try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, mat_lhs_mcv.register_pair[1]);
7439 if (mat_rhs_mcv.isMemory())
7440 try self.asmRegisterMemory(.{ .i_, .mul }, tmp_reg, mat_rhs_mcv.mem(.qword))
73887441 else
7389 try self.asmRegisterRegister(.{ .i_, .mul }, tmp_reg, rhs_mcv.register_pair[0]);
7442 try self.asmRegisterRegister(.{ .i_, .mul }, tmp_reg, mat_rhs_mcv.register_pair[0]);
73907443 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_reg);
73917444 return .{ .register_pair = .{ .rax, .rdx } };
73927445 }