x64_86 fix: RMI can accept imm16 only for imul r16,r/m16

This commit is contained in:
Mathieu Suen
2026-02-16 10:29:26 +01:00
committed by mlugg
parent 998b714708
commit 2c88821c56
+23 -1
View File
@@ -1850,11 +1850,33 @@ fn asmRegisterMemoryImmediate(
m: Memory,
imm: Immediate,
) !void {
if (switch (imm) {
if (reg.size() == .qword and tag[1] == .mul) {
// imul does not support imm16 for RMI r64, r/m64
const payload = try self.addExtra(Mir.Imm32{ .imm = switch (imm) {
.signed => |s| @bitCast(s),
.unsigned => |u| @as(u32, @intCast(u)),
.nav, .uav, .lazy_sym, .extern_func => unreachable,
} });
assert(payload + 1 == try self.addExtra(Mir.Memory.encode(m)));
_ = try self.addInst(.{
.tag = tag[1],
.ops = switch (imm) {
.signed => .rmi_s,
.unsigned => .rmi_u,
.nav, .uav, .lazy_sym, .extern_func => unreachable,
},
.data = .{ .rx = .{
.fixes = tag[0],
.r1 = reg,
.payload = payload,
} },
});
} else if (switch (imm) {
.signed => |s| if (std.math.cast(i16, s)) |x| @as(u16, @bitCast(x)) else null,
.unsigned => |u| std.math.cast(u16, u),
.nav, .uav, .lazy_sym, .extern_func => unreachable,
}) |small_imm| {
// This is only valid for imul RMI r16, r/m16
_ = try self.addInst(.{
.tag = tag[1],
.ops = .rmi,