| ... | ... | @@ -3873,39 +3873,65 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3873 | 3873 | |
| 3874 | 3874 | const lhs_mcv = try self.resolveInst(bin_op.lhs); |
| 3875 | 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); |
| 3876 | 3902 | |
| 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)) |
| 3879 | 3905 | 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( |
| 3882 | 3908 | .{ ._, .mov }, |
| 3883 | 3909 | tmp_regs[0], |
| 3884 | | rhs_mcv.address().offset(8).deref().mem(.qword), |
| 3910 | mat_rhs_mcv.address().offset(8).deref().mem(.qword), |
| 3885 | 3911 | ) else try self.asmRegisterRegister( |
| 3886 | 3912 | .{ ._, .mov }, |
| 3887 | 3913 | tmp_regs[0], |
| 3888 | | rhs_mcv.register_pair[1], |
| 3914 | mat_rhs_mcv.register_pair[1], |
| 3889 | 3915 | ); |
| 3890 | 3916 | try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]); |
| 3891 | 3917 | try self.asmSetccRegister(.nz, tmp_regs[1].to8()); |
| 3892 | 3918 | try self.asmRegisterRegister(.{ .i_, .mul }, tmp_regs[0], .rax); |
| 3893 | 3919 | 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)) |
| 3896 | 3922 | else |
| 3897 | | try self.asmRegister(.{ ._, .mul }, rhs_mcv.register_pair[0]); |
| 3923 | try self.asmRegister(.{ ._, .mul }, mat_rhs_mcv.register_pair[0]); |
| 3898 | 3924 | try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_regs[0]); |
| 3899 | 3925 | try self.asmSetccRegister(.c, tmp_regs[3].to8()); |
| 3900 | 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 | 3928 | .{ ._, .mov }, |
| 3903 | 3929 | tmp_regs[0], |
| 3904 | | lhs_mcv.address().offset(8).deref().mem(.qword), |
| 3930 | mat_lhs_mcv.address().offset(8).deref().mem(.qword), |
| 3905 | 3931 | ) else try self.asmRegisterRegister( |
| 3906 | 3932 | .{ ._, .mov }, |
| 3907 | 3933 | tmp_regs[0], |
| 3908 | | lhs_mcv.register_pair[1], |
| 3934 | mat_lhs_mcv.register_pair[1], |
| 3909 | 3935 | ); |
| 3910 | 3936 | try self.asmRegisterRegister(.{ ._, .@"test" }, tmp_regs[0], tmp_regs[0]); |
| 3911 | 3937 | try self.asmSetccRegister(.nz, tmp_regs[3].to8()); |
| ... | ... | @@ -3915,13 +3941,13 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void { |
| 3915 | 3941 | tmp_regs[3].to8(), |
| 3916 | 3942 | ); |
| 3917 | 3943 | 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)) |
| 3920 | 3946 | else |
| 3921 | 3947 | try self.asmRegisterRegister( |
| 3922 | 3948 | .{ .i_, .mul }, |
| 3923 | 3949 | tmp_regs[0], |
| 3924 | | rhs_mcv.register_pair[0], |
| 3950 | mat_rhs_mcv.register_pair[0], |
| 3925 | 3951 | ); |
| 3926 | 3952 | try self.asmSetccRegister(.o, tmp_regs[2].to8()); |
| 3927 | 3953 | try self.asmRegisterRegister(.{ ._, .@"or" }, tmp_regs[1].to8(), tmp_regs[2].to8()); |
| ... | ... | @@ -7359,34 +7385,61 @@ fn genMulDivBinOp( |
| 7359 | 7385 | const reg_locks = self.register_manager.lockRegsAssumeUnused(2, .{ .rax, .rdx }); |
| 7360 | 7386 | defer for (reg_locks) |lock| self.register_manager.unlockReg(lock); |
| 7361 | 7387 | |
| 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 | 7415 | const tmp_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp); |
| 7363 | 7416 | const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); |
| 7364 | 7417 | defer self.register_manager.unlockReg(tmp_lock); |
| 7365 | 7418 | |
| 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)) |
| 7368 | 7421 | 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( |
| 7371 | 7424 | .{ ._, .mov }, |
| 7372 | 7425 | 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]); |
| 7375 | 7428 | 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)) |
| 7378 | 7431 | else |
| 7379 | | try self.asmRegister(.{ ._, .mul }, rhs_mcv.register_pair[0]); |
| 7432 | try self.asmRegister(.{ ._, .mul }, mat_rhs_mcv.register_pair[0]); |
| 7380 | 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 | 7435 | .{ ._, .mov }, |
| 7383 | 7436 | 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)) |
| 7388 | 7441 | 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 | 7443 | try self.asmRegisterRegister(.{ ._, .add }, .rdx, tmp_reg); |
| 7391 | 7444 | return .{ .register_pair = .{ .rax, .rdx } }; |
| 7392 | 7445 | } |