authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-27 03:36:44-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-27 05:58:00-04:00
log587eacefec7d00c60cb32a10f7084dd7e61a970a
treee205a64c3132457d6fddc5a59157ca3a20735c05
parent65838fcabeee8f0330425156c31a4711d0e026f7

x86_64: fix 64-bit multiply by 32-bit immediate


1 files changed, 10 insertions(+), 9 deletions(-)

src/arch/x86_64/CodeGen.zig+10-9
...@@ -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 },