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 {...@@ -3873,39 +3873,65 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
38733873
3874 const lhs_mcv = try self.resolveInst(bin_op.lhs);3874 const lhs_mcv = try self.resolveInst(bin_op.lhs);
3875 const rhs_mcv = try self.resolveInst(bin_op.rhs);3875 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())3903 if (mat_lhs_mcv.isMemory())
3878 try self.asmRegisterMemory(.{ ._, .mov }, .rax, lhs_mcv.mem(.qword))3904 try self.asmRegisterMemory(.{ ._, .mov }, .rax, mat_lhs_mcv.mem(.qword))
3879 else3905 else
3880 try self.asmRegisterRegister(.{ ._, .mov }, .rax, lhs_mcv.register_pair[0]);3906 try self.asmRegisterRegister(.{ ._, .mov }, .rax, mat_lhs_mcv.register_pair[0]);
3881 if (rhs_mcv.isMemory()) try self.asmRegisterMemory(3907 if (mat_rhs_mcv.isMemory()) try self.asmRegisterMemory(
3882 .{ ._, .mov },3908 .{ ._, .mov },
3883 tmp_regs[0],3909 tmp_regs[0],
3884 rhs_mcv.address().offset(8).deref().mem(.qword),3910 mat_rhs_mcv.address().offset(8).deref().mem(.qword),
3885 ) else try self.asmRegisterRegister(3911 ) else try self.asmRegisterRegister(
3886 .{ ._, .mov },3912 .{ ._, .mov },
3887 tmp_regs[0],3913 tmp_regs[0],
3888 rhs_mcv.register_pair[1],3914 mat_rhs_mcv.register_pair[1],
3889 );3915 );
3890 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]);3916 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]);
3891 try self.asmSetccRegister(.nz, tmp_regs[1].to8());3917 try self.asmSetccRegister(.nz, tmp_regs[1].to8());
3892 try self.asmRegisterRegister(.{ .i_, .mul }, tmp_regs[0], .rax);3918 try self.asmRegisterRegister(.{ .i_, .mul }, tmp_regs[0], .rax);
3893 try self.asmSetccRegister(.o, tmp_regs[2].to8());3919 try self.asmSetccRegister(.o, tmp_regs[2].to8());
3894 if (rhs_mcv.isMemory())3920 if (mat_rhs_mcv.isMemory())
3895 try self.asmMemory(.{ ._, .mul }, rhs_mcv.mem(.qword))3921 try self.asmMemory(.{ ._, .mul }, mat_rhs_mcv.mem(.qword))
3896 else3922 else
3897 try self.asmRegister(.{ ._, .mul }, rhs_mcv.register_pair[0]);3923 try self.asmRegister(.{ ._, .mul }, mat_rhs_mcv.register_pair[0]);
3898 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_regs[0]);3924 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_regs[0]);
3899 try self.asmSetccRegister(.c, tmp_regs[3].to8());3925 try self.asmSetccRegister(.c, tmp_regs[3].to8());
3900 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[2].to8(), tmp_regs[3].to8());3926 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(
3902 .{ ._, .mov },3928 .{ ._, .mov },
3903 tmp_regs[0],3929 tmp_regs[0],
3904 lhs_mcv.address().offset(8).deref().mem(.qword),3930 mat_lhs_mcv.address().offset(8).deref().mem(.qword),
3905 ) else try self.asmRegisterRegister(3931 ) else try self.asmRegisterRegister(
3906 .{ ._, .mov },3932 .{ ._, .mov },
3907 tmp_regs[0],3933 tmp_regs[0],
3908 lhs_mcv.register_pair[1],3934 mat_lhs_mcv.register_pair[1],
3909 );3935 );
3910 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]);3936 try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]);
3911 try self.asmSetccRegister(.nz, tmp_regs[3].to8());3937 try self.asmSetccRegister(.nz, tmp_regs[3].to8());
...@@ -3915,13 +3941,13 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {...@@ -3915,13 +3941,13 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3915 tmp_regs[3].to8(),3941 tmp_regs[3].to8(),
3916 );3942 );
3917 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8());3943 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8());
3918 if (rhs_mcv.isMemory())3944 if (mat_rhs_mcv.isMemory())
3919 try self.asmRegisterMemory(.{ .i_, .mul }, tmp_regs[0], rhs_mcv.mem(.qword))3945 try self.asmRegisterMemory(.{ .i_, .mul }, tmp_regs[0], mat_rhs_mcv.mem(.qword))
3920 else3946 else
3921 try self.asmRegisterRegister(3947 try self.asmRegisterRegister(
3922 .{ .i_, .mul },3948 .{ .i_, .mul },
3923 tmp_regs[0],3949 tmp_regs[0],
3924 rhs_mcv.register_pair[0],3950 mat_rhs_mcv.register_pair[0],
3925 );3951 );
3926 try self.asmSetccRegister(.o, tmp_regs[2].to8());3952 try self.asmSetccRegister(.o, tmp_regs[2].to8());
3927 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8());3953 try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8());
...@@ -7359,34 +7385,61 @@ fn genMulDivBinOp(...@@ -7359,34 +7385,61 @@ fn genMulDivBinOp(
7359 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });7385 const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx });
7360 defer for (reg_locks) |lock| self.register_manager.unlockReg(lock);7386 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
7362 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);7415 const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
7363 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);7416 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
7364 defer self.register_manager.unlockReg(tmp_lock);7417 defer self.register_manager.unlockReg(tmp_lock);
73657418
7366 if (lhs_mcv.isMemory())7419 if (mat_lhs_mcv.isMemory())
7367 try self.asmRegisterMemory(.{ ._, .mov }, .rax, lhs_mcv.mem(.qword))7420 try self.asmRegisterMemory(.{ ._, .mov }, .rax, mat_lhs_mcv.mem(.qword))
7368 else7421 else
7369 try self.asmRegisterRegister(.{ ._, .mov }, .rax, lhs_mcv.register_pair[0]);7422 try self.asmRegisterRegister(.{ ._, .mov }, .rax, mat_lhs_mcv.register_pair[0]);
7370 if (rhs_mcv.isMemory()) try self.asmRegisterMemory(7423 if (mat_rhs_mcv.isMemory()) try self.asmRegisterMemory(
7371 .{ ._, .mov },7424 .{ ._, .mov },
7372 tmp_reg,7425 tmp_reg,
7373 rhs_mcv.address().offset(8).deref().mem(.qword),7426 mat_rhs_mcv.address().offset(8).deref().mem(.qword),
7374 ) else try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, rhs_mcv.register_pair[1]);7427 ) else try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, mat_rhs_mcv.register_pair[1]);
7375 try self.asmRegisterRegister(.{ .i_, .mul }, tmp_reg, .rax);7428 try self.asmRegisterRegister(.{ .i_, .mul }, tmp_reg, .rax);
7376 if (rhs_mcv.isMemory())7429 if (mat_rhs_mcv.isMemory())
7377 try self.asmMemory(.{ ._, .mul }, rhs_mcv.mem(.qword))7430 try self.asmMemory(.{ ._, .mul }, mat_rhs_mcv.mem(.qword))
7378 else7431 else
7379 try self.asmRegister(.{ ._, .mul }, rhs_mcv.register_pair[0]);7432 try self.asmRegister(.{ ._, .mul }, mat_rhs_mcv.register_pair[0]);
7380 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_reg);7433 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_reg);
7381 if (lhs_mcv.isMemory()) try self.asmRegisterMemory(7434 if (mat_lhs_mcv.isMemory()) try self.asmRegisterMemory(
7382 .{ ._, .mov },7435 .{ ._, .mov },
7383 tmp_reg,7436 tmp_reg,
7384 lhs_mcv.address().offset(8).deref().mem(.qword),7437 mat_lhs_mcv.address().offset(8).deref().mem(.qword),
7385 ) else try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, lhs_mcv.register_pair[1]);7438 ) else try self.asmRegisterRegister(.{ ._, .mov }, tmp_reg, mat_lhs_mcv.register_pair[1]);
7386 if (rhs_mcv.isMemory())7439 if (mat_rhs_mcv.isMemory())
7387 try self.asmRegisterMemory(.{ .i_, .mul }, tmp_reg, rhs_mcv.mem(.qword))7440 try self.asmRegisterMemory(.{ .i_, .mul }, tmp_reg, mat_rhs_mcv.mem(.qword))
7388 else7441 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]);
7390 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_reg);7443 try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_reg);
7391 return .{ .register_pair = .{ .rax, .rdx } };7444 return .{ .register_pair = .{ .rax, .rdx } };
7392 }7445 }