authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-02-16 09:19:33-05:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-04-10 23:23:33+02:00
log9ba9865e5191dcfdcf7ca794e3b26cbf5c6138bb
treeea414806c3d46b2e525337362449e86a02435a26
parent1552bc7ad0aace9e86999f0e4fdbe9bc18647dd1

x86_64: allow positive signed imms to match unsigned imm patterns


3 files changed, 16 insertions(+), 35 deletions(-)

src/codegen/x86_64/Encoding.zig+1-9
...@@ -649,15 +649,7 @@ pub const Op = enum {...@@ -649,15 +649,7 @@ pub const Op = enum {
649 },649 },
650650
651 .imm => |imm| switch (imm) {651 .imm => |imm| switch (imm) {
652 .signed => |x| if (x == 1)652 inline .signed, .unsigned => |x| if (x == 1)
653 .unity
654 else if (math.cast(i8, x)) |_|
655 .imm8s
656 else if (math.cast(i16, x)) |_|
657 .imm16s
658 else
659 .imm32s,
660 .unsigned => |x| if (x == 1)
661 .unity653 .unity
662 else if (math.cast(i8, x)) |_|654 else if (math.cast(i8, x)) |_|
663 .imm8s655 .imm8s
src/codegen/x86_64/Lower.zig+1-1
...@@ -565,7 +565,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -565,7 +565,7 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
565 .rmi => &.{565 .rmi => &.{
566 .{ .reg = inst.data.rix.r1 },566 .{ .reg = inst.data.rix.r1 },
567 .{ .mem = lower.mem(1, inst.data.rix.payload) },567 .{ .mem = lower.mem(1, inst.data.rix.payload) },
568 .{ .imm = if (std.math.cast(u8, inst.data.rix.i)) |u| .u(u) else .s(inst.data.rix.i) },568 .{ .imm = .s(inst.data.rix.i) },
569 },569 },
570 .rmi_s, .rmi_u => &.{570 .rmi_s, .rmi_u => &.{
571 .{ .reg = inst.data.rx.r1 },571 .{ .reg = inst.data.rx.r1 },
src/codegen/x86_64/encoder.zig+14-25
...@@ -43,17 +43,11 @@ pub const Instruction = struct {...@@ -43,17 +43,11 @@ pub const Instruction = struct {
4343
44 pub fn asSigned(imm: Immediate, bit_size: u64) i64 {44 pub fn asSigned(imm: Immediate, bit_size: u64) i64 {
45 return switch (imm) {45 return switch (imm) {
46 .signed => |x| switch (bit_size) {46 inline .signed, .unsigned => |x| switch (bit_size) {
47 1, 8 => @as(i8, @intCast(x)),47 1, 8 => @as(i8, if (x < 0) @intCast(x) else @bitCast(@as(u8, @intCast(x)))),
48 16 => @as(i16, @intCast(x)),48 16 => @as(i16, if (x < 0) @intCast(x) else @bitCast(@as(u16, @intCast(x)))),
49 32, 64 => x,49 32 => @as(i32, if (x < 0) @intCast(x) else @bitCast(@as(u32, @intCast(x)))),
50 else => unreachable,50 64 => @as(i64, if (x < 0) @intCast(x) else @bitCast(@as(u64, @intCast(x)))),
51 },
52 .unsigned => |x| switch (bit_size) {
53 1, 8 => @as(i8, @bitCast(@as(u8, @intCast(x)))),
54 16 => @as(i16, @bitCast(@as(u16, @intCast(x)))),
55 32 => @as(i32, @bitCast(@as(u32, @intCast(x)))),
56 64 => @bitCast(x),
57 else => unreachable,51 else => unreachable,
58 },52 },
59 };53 };
...@@ -61,17 +55,11 @@ pub const Instruction = struct {...@@ -61,17 +55,11 @@ pub const Instruction = struct {
6155
62 pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 {56 pub fn asUnsigned(imm: Immediate, bit_size: u64) u64 {
63 return switch (imm) {57 return switch (imm) {
64 .signed => |x| switch (bit_size) {58 inline .signed, .unsigned => |x| switch (bit_size) {
65 1, 8 => @as(u8, @bitCast(@as(i8, @intCast(x)))),59 1, 8 => @as(u8, if (x < 0) @bitCast(@as(i8, @intCast(x))) else @intCast(x)),
66 16 => @as(u16, @bitCast(@as(i16, @intCast(x)))),60 16 => @as(u16, if (x < 0) @bitCast(@as(i16, @intCast(x))) else @intCast(x)),
67 32, 64 => @as(u32, @bitCast(x)),61 32 => @as(u32, if (x < 0) @bitCast(@as(i32, @intCast(x))) else @intCast(x)),
68 else => unreachable,62 64 => @as(u64, if (x < 0) @bitCast(@as(i64, @intCast(x))) else @intCast(x)),
69 },
70 .unsigned => |x| switch (bit_size) {
71 1, 8 => @as(u8, @intCast(x)),
72 16 => @as(u16, @intCast(x)),
73 32 => @as(u32, @intCast(x)),
74 64 => x,
75 else => unreachable,63 else => unreachable,
76 },64 },
77 };65 };
...@@ -712,9 +700,10 @@ pub const Instruction = struct {...@@ -712,9 +700,10 @@ pub const Instruction = struct {
712 }700 }
713 }701 }
714702
715 fn encodeImm(imm: Immediate, kind: Encoding.Op, encoder: anytype) !void {703 fn encodeImm(imm: Immediate, enc_op: Encoding.Op, encoder: anytype) !void {
716 const raw = imm.asUnsigned(kind.immBitSize());704 const bit_size = enc_op.immBitSize();
717 switch (kind.immBitSize()) {705 const raw = imm.asUnsigned(bit_size);
706 switch (bit_size) {
718 8 => try encoder.imm8(@as(u8, @intCast(raw))),707 8 => try encoder.imm8(@as(u8, @intCast(raw))),
719 16 => try encoder.imm16(@as(u16, @intCast(raw))),708 16 => try encoder.imm16(@as(u16, @intCast(raw))),
720 32 => try encoder.imm32(@as(u32, @intCast(raw))),709 32 => try encoder.imm32(@as(u32, @intCast(raw))),