| ... | @@ -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 { |
| 3873 | | 3873 | |
| 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); |
| 3876 | | 3902 | |
| 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 | else | 3905 | 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 | else | 3922 | 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 | else | 3946 | 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); |
| 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 | 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); |
| 7365 | | 7418 | |
| 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 | else | 7421 | 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 | else | 7431 | 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 | else | 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 | 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 | } |