| ... | @@ -4974,6 +4974,10 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -4974,6 +4974,10 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 4974 | .ptr_stack_offset => unreachable, | 4974 | .ptr_stack_offset => unreachable, |
| 4975 | .register_overflow => unreachable, | 4975 | .register_overflow => unreachable, |
| 4976 | .register => |dst_reg| { | 4976 | .register => |dst_reg| { |
| | 4977 | const dst_alias = registerAlias(dst_reg, abi_size); |
| | 4978 | const dst_lock = self.register_manager.lockReg(dst_reg); |
| | 4979 | defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); |
| | 4980 | |
| 4977 | switch (src_mcv) { | 4981 | switch (src_mcv) { |
| 4978 | .none => unreachable, | 4982 | .none => unreachable, |
| 4979 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), | 4983 | .undef => try self.genSetReg(dst_ty, dst_reg, .undef), |
| ... | @@ -4982,21 +4986,18 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -4982,21 +4986,18 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 4982 | .register_overflow => unreachable, | 4986 | .register_overflow => unreachable, |
| 4983 | .register => |src_reg| try self.asmRegisterRegister( | 4987 | .register => |src_reg| try self.asmRegisterRegister( |
| 4984 | .imul, | 4988 | .imul, |
| 4985 | registerAlias(dst_reg, abi_size), | 4989 | dst_alias, |
| 4986 | registerAlias(src_reg, abi_size), | 4990 | registerAlias(src_reg, abi_size), |
| 4987 | ), | 4991 | ), |
| 4988 | .immediate => |imm| { | 4992 | .immediate => |imm| { |
| 4989 | if (math.minInt(i32) <= imm and imm <= math.maxInt(i32)) { | 4993 | if (std.math.cast(i32, imm)) |small| { |
| 4990 | // TODO take into account the type's ABI size when selecting the register alias | | |
| 4991 | // register, immediate | | |
| 4992 | try self.asmRegisterRegisterImmediate( | 4994 | try self.asmRegisterRegisterImmediate( |
| 4993 | .imul, | 4995 | .imul, |
| 4994 | dst_reg.to32(), | 4996 | dst_alias, |
| 4995 | dst_reg.to32(), | 4997 | dst_alias, |
| 4996 | Immediate.u(@intCast(u32, imm)), | 4998 | Immediate.s(small), |
| 4997 | ); | 4999 | ); |
| 4998 | } else { | 5000 | } else { |
| 4999 | // TODO verify we don't spill and assign to the same register as dst_mcv | | |
| 5000 | const src_reg = try self.copyToTmpRegister(dst_ty, src_mcv); | 5001 | const src_reg = try self.copyToTmpRegister(dst_ty, src_mcv); |
| 5001 | return self.genIntMulComplexOpMir(dst_ty, dst_mcv, MCValue{ .register = src_reg }); | 5002 | return self.genIntMulComplexOpMir(dst_ty, dst_mcv, MCValue{ .register = src_reg }); |
| 5002 | } | 5003 | } |
| ... | @@ -5004,7 +5005,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M | ... | @@ -5004,7 +5005,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M |
| 5004 | .stack_offset => |off| { | 5005 | .stack_offset => |off| { |
| 5005 | try self.asmRegisterMemory( | 5006 | try self.asmRegisterMemory( |
| 5006 | .imul, | 5007 | .imul, |
| 5007 | registerAlias(dst_reg, abi_size), | 5008 | dst_alias, |
| 5008 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), | 5009 | Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .rbp, .disp = -off }), |
| 5009 | ); | 5010 | ); |
| 5010 | }, | 5011 | }, |