From 9ba9865e5191dcfdcf7ca794e3b26cbf5c6138bb Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 16 Feb 2026 09:19:33 -0500 Subject: [PATCH] x86_64: allow positive signed imms to match unsigned imm patterns --- src/codegen/x86_64/Encoding.zig | 10 +-------- src/codegen/x86_64/Lower.zig | 2 +- src/codegen/x86_64/encoder.zig | 39 ++++++++++++--------------------- 3 files changed, 16 insertions(+), 35 deletions(-) diff --git a/src/codegen/x86_64/Encoding.zig b/src/codegen/x86_64/Encoding.zig index 6043fd06b50dad070dd5741442d5781dbcc724c6..342a8015bba6b0fc17a586ef3dc6444253f473d9 100644 --- a/src/codegen/x86_64/Encoding.zig +++ b/src/codegen/x86_64/Encoding.zig @@ -649,15 +649,7 @@ pub const Op = enum { }, .imm => |imm| switch (imm) { - .signed => |x| if (x == 1) - .unity - else if (math.cast(i8, x)) |_| - .imm8s - else if (math.cast(i16, x)) |_| - .imm16s - else - .imm32s, - .unsigned => |x| if (x == 1) + inline .signed, .unsigned => |x| if (x == 1) .unity else if (math.cast(i8, x)) |_| .imm8s diff --git a/src/codegen/x86_64/Lower.zig b/src/codegen/x86_64/Lower.zig index 995f044852e360628e3621cbae7adee3ca3b0f24..b93c08b1b58770b792d6afa621ffee0a5c0dfd3b 100644 --- a/src/codegen/x86_64/Lower.zig +++ b/src/codegen/x86_64/Lower.zig @@ -565,7 +565,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void { .rmi => &.{ .{ .reg = inst.data.rix.r1 }, .{ .mem = lower.mem(1, inst.data.rix.payload) }, - .{ .imm = if (std.math.cast(u8, inst.data.rix.i)) |u| .u(u) else .s(inst.data.rix.i) }, + .{ .imm = .s(inst.data.rix.i) }, }, .rmi_s, .rmi_u => &.{ .{ .reg = inst.data.rx.r1 }, diff --git a/src/codegen/x86_64/encoder.zig b/src/codegen/x86_64/encoder.zig index 1d9c67175ef204933a5463393cad189d0e59e7fa..dd5229f3d349548caee9f6ab3f37bc82ef24e8b6 100644 --- a/src/codegen/x86_64/encoder.zig +++ b/src/codegen/x86_64/encoder.zig @@ -43,17 +43,11 @@ pub const Instruction = struct { pub fn asSigned(imm: Immediate, bit_size: u64) i64 { return switch (imm) { - .signed => |x| switch (bit_size) { - 1, 8 => @as(i8, @intCast(x)), - 16 => @as(i16, @intCast(x)), - 32, 64 => x, - else => unreachable, - }, - .unsigned => |x| switch (bit_size) { - 1, 8 => @as(i8, @bitCast(@as(u8, @intCast(x)))), - 16 => @as(i16, @bitCast(@as(u16, @intCast(x)))), - 32 => @as(i32, @bitCast(@as(u32, @intCast(x)))), - 64 => @bitCast(x), + inline .signed, .unsigned => |x| switch (bit_size) { + 1, 8 => @as(i8, if (x < 0) @intCast(x) else @bitCast(@as(u8, @intCast(x)))), + 16 => @as(i16, if (x < 0) @intCast(x) else @bitCast(@as(u16, @intCast(x)))), + 32 => @as(i32, if (x < 0) @intCast(x) else @bitCast(@as(u32, @intCast(x)))), + 64 => @as(i64, if (x < 0) @intCast(x) else @bitCast(@as(u64, @intCast(x)))), else => unreachable, }, }; @@ -61,17 +55,11 @@ pub const Instruction = struct { pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 { return switch (imm) { - .signed => |x| switch (bit_size) { - 1, 8 => @as(u8, @bitCast(@as(i8, @intCast(x)))), - 16 => @as(u16, @bitCast(@as(i16, @intCast(x)))), - 32, 64 => @as(u32, @bitCast(x)), - else => unreachable, - }, - .unsigned => |x| switch (bit_size) { - 1, 8 => @as(u8, @intCast(x)), - 16 => @as(u16, @intCast(x)), - 32 => @as(u32, @intCast(x)), - 64 => x, + inline .signed, .unsigned => |x| switch (bit_size) { + 1, 8 => @as(u8, if (x < 0) @bitCast(@as(i8, @intCast(x))) else @intCast(x)), + 16 => @as(u16, if (x < 0) @bitCast(@as(i16, @intCast(x))) else @intCast(x)), + 32 => @as(u32, if (x < 0) @bitCast(@as(i32, @intCast(x))) else @intCast(x)), + 64 => @as(u64, if (x < 0) @bitCast(@as(i64, @intCast(x))) else @intCast(x)), else => unreachable, }, }; @@ -712,9 +700,10 @@ pub const Instruction = struct { } } - fn encodeImm(imm: Immediate, kind: Encoding.Op, encoder: anytype) !void { - const raw = imm.asUnsigned(kind.immBitSize()); - switch (kind.immBitSize()) { + fn encodeImm(imm: Immediate, enc_op: Encoding.Op, encoder: anytype) !void { + const bit_size = enc_op.immBitSize(); + const raw = imm.asUnsigned(bit_size); + switch (bit_size) { 8 => try encoder.imm8(@as(u8, @intCast(raw))), 16 => try encoder.imm16(@as(u16, @intCast(raw))), 32 => try encoder.imm32(@as(u32, @intCast(raw))), -- 2.54.0