Commit 2543e2d97c

Jacob Young <jacobly0@users.noreply.github.com>
2025-06-02 07:18:21
x86_64: implement integer `@divFloor` and `@mod`
Closes #24039
1 parent f4f4460
Changed files (7)
src/arch/x86_64/abi.zig
@@ -575,22 +575,22 @@ const RegisterBitSet = RegisterManager.RegisterBitSet;
 pub const RegisterClass = struct {
     pub const gp: RegisterBitSet = blk: {
         var set = RegisterBitSet.initEmpty();
-        for (allocatable_regs, 0..) |reg, index| if (reg.class() == .general_purpose) set.set(index);
+        for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.general_purpose)) set.set(index);
         break :blk set;
     };
     pub const gphi: RegisterBitSet = blk: {
         var set = RegisterBitSet.initEmpty();
-        for (allocatable_regs, 0..) |reg, index| if (reg.hasHi8()) set.set(index);
+        for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.gphi)) set.set(index);
         break :blk set;
     };
     pub const x87: RegisterBitSet = blk: {
         var set = RegisterBitSet.initEmpty();
-        for (allocatable_regs, 0..) |reg, index| if (reg.class() == .x87) set.set(index);
+        for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.x87)) set.set(index);
         break :blk set;
     };
     pub const sse: RegisterBitSet = blk: {
         var set = RegisterBitSet.initEmpty();
-        for (allocatable_regs, 0..) |reg, index| if (reg.class() == .sse) set.set(index);
+        for (allocatable_regs, 0..) |reg, index| if (reg.isClass(.sse)) set.set(index);
         break :blk set;
     };
 };
src/arch/x86_64/bits.zig
@@ -429,6 +429,16 @@ pub const Register = enum(u8) {
         };
     }
 
+    pub inline fn isClass(reg: Register, rc: Class) bool {
+        switch (rc) {
+            else => return reg.class() == rc,
+            .gphi => {
+                const reg_id = reg.id();
+                return (reg_id >= comptime Register.ah.id()) and reg_id <= comptime Register.bh.id();
+            },
+        }
+    }
+
     pub fn id(reg: Register) u7 {
         const base = switch (@intFromEnum(reg)) {
             // zig fmt: off
@@ -615,22 +625,17 @@ pub const Register = enum(u8) {
     }
 
     pub fn toHi8(reg: Register) Register {
-        assert(reg.hasHi8());
+        assert(reg.isClass(.gphi));
         return @enumFromInt(@intFromEnum(reg) - reg.gpBase() + @intFromEnum(Register.ah));
     }
 
-    pub fn hasHi8(reg: Register) bool {
-        const reg_id = reg.id();
-        return (reg_id >= comptime Register.ah.id()) and reg_id <= comptime Register.bh.id();
-    }
-
     pub fn to80(reg: Register) Register {
-        assert(reg.class() == .x87);
+        assert(reg.isClass(.x87));
         return reg;
     }
 
     fn sseBase(reg: Register) u8 {
-        assert(reg.class() == .sse);
+        assert(reg.isClass(.sse));
         return switch (@intFromEnum(reg)) {
             @intFromEnum(Register.zmm0)...@intFromEnum(Register.zmm31) => @intFromEnum(Register.zmm0),
             @intFromEnum(Register.ymm0)...@intFromEnum(Register.ymm31) => @intFromEnum(Register.ymm0),
@@ -694,11 +699,13 @@ test "Register enc - different classes" {
 }
 
 test "Register classes" {
-    try expect(Register.r11.class() == .general_purpose);
-    try expect(Register.ymm11.class() == .sse);
-    try expect(Register.mm3.class() == .mmx);
-    try expect(Register.st3.class() == .x87);
-    try expect(Register.fs.class() == .segment);
+    try expect(Register.r11.isClass(.general_purpose));
+    try expect(Register.rdx.isClass(.gphi));
+    try expect(!Register.dil.isClass(.gphi));
+    try expect(Register.ymm11.isClass(.sse));
+    try expect(Register.mm3.isClass(.mmx));
+    try expect(Register.st3.isClass(.x87));
+    try expect(Register.fs.isClass(.segment));
 }
 
 pub const FrameIndex = enum(u32) {
src/arch/x86_64/CodeGen.zig
@@ -47,10 +47,11 @@ pub fn legalizeFeatures(target: *const std.Target) *const Air.Legalize.Features
             .scalarize_div_float_optimized = use_old,
             .scalarize_div_trunc = use_old,
             .scalarize_div_trunc_optimized = use_old,
-            .scalarize_div_floor = use_old,
+            .scalarize_div_floor = true,
             .scalarize_div_floor_optimized = use_old,
             .scalarize_div_exact = use_old,
             .scalarize_div_exact_optimized = use_old,
+            .scalarize_mod = true,
             .scalarize_max = use_old,
             .scalarize_min = use_old,
             .scalarize_add_with_overflow = true,
@@ -690,7 +691,7 @@ const InstTracking = struct {
         }
         tracking_log.debug("spill {} from {} to {}", .{ inst, self.short, self.long });
         try cg.genCopy(cg.typeOfIndex(inst), self.long, self.short, .{});
-        for (self.short.getRegs()) |reg| if (reg.class() == .x87) try cg.asmRegister(.{ .f_, .free }, reg);
+        for (self.short.getRegs()) |reg| if (reg.isClass(.x87)) try cg.asmRegister(.{ .f_, .free }, reg);
     }
 
     fn reuseFrame(self: *InstTracking) void {
@@ -2468,7 +2469,7 @@ fn genBodyBlock(self: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
 }
 
 fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
-    @setEvalBranchQuota(28_600);
+    @setEvalBranchQuota(28_700);
     const pt = cg.pt;
     const zcu = pt.zcu;
     const ip = &zcu.intern_pool;
@@ -35458,12 +35459,249 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                 };
                 try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
             },
-            .div_floor => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, air_tag) else fallback: {
+            .div_floor => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, air_tag) else {
                 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
-                if (cg.floatBits(cg.typeOf(bin_op.lhs).scalarType(zcu)) == null) break :fallback try cg.airMulDivBinOp(inst, air_tag);
+                const ty = cg.typeOf(bin_op.lhs);
                 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
                 var res: [1]Temp = undefined;
-                cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{
+                (if (cg.intInfo(ty)) |int_info| err: switch (int_info.signedness) {
+                    .signed => cg.select(&res, &.{ty}, &ops, comptime &.{ .{
+                        .src_constraints = .{ .{ .exact_signed_int = 1 }, .{ .exact_signed_int = 1 }, .any },
+                        .patterns = &.{
+                            .{ .src = .{ .any, .any, .none } },
+                        },
+                        .dst_temps = .{ .{ .imm = 0 }, .unused },
+                        .each = .{ .once = &.{} },
+                    }, .{
+                        .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
+                        .patterns = &.{
+                            .{ .src = .{ .mem, .to_mut_gphi, .none } },
+                            .{ .src = .{ .to_gpr, .to_mut_gphi, .none } },
+                        },
+                        .dst_temps = .{ .{ .reg = .al }, .unused },
+                        .clobbers = .{ .eflags = true },
+                        .each = .{ .once = &.{
+                            .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ },
+                            .{ ._, .i_, .div, .src1b, ._, ._, ._ },
+                            .{ ._, ._, .@"and", .src1b, .sa(.src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .xor, .src1b, .dst0h, ._, ._ },
+                            .{ ._, ._, .cmp, .src1b, .sia(1, .src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .adc, .dst0b, .si(-1), ._, ._ },
+                        } },
+                    }, .{
+                        .required_features = .{ .fast_imm16, null, null, null },
+                        .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
+                        .patterns = &.{
+                            .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } },
+                        },
+                        .extra_temps = .{
+                            .{ .type = .i16, .kind = .{ .reg = .dx } },
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                        },
+                        .dst_temps = .{ .{ .ref = .src0 }, .unused },
+                        .clobbers = .{ .eflags = true },
+                        .each = .{ .once = &.{
+                            .{ ._, ._, .cwd, ._, ._, ._, ._ },
+                            .{ ._, .i_, .div, .src1w, ._, ._, ._ },
+                            .{ ._, ._, .@"and", .src1w, .sa(.src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .xor, .src1d, .tmp0d, ._, ._ },
+                            .{ ._, ._, .cmp, .src1w, .sia(1, .src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .adc, .dst0d, .si(-1), ._, ._ },
+                        } },
+                    }, .{
+                        .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
+                        .patterns = &.{
+                            .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } },
+                        },
+                        .extra_temps = .{
+                            .{ .type = .i16, .kind = .{ .reg = .dx } },
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                        },
+                        .dst_temps = .{ .{ .ref = .src0 }, .unused },
+                        .clobbers = .{ .eflags = true },
+                        .each = .{ .once = &.{
+                            .{ ._, ._, .cwd, ._, ._, ._, ._ },
+                            .{ ._, .i_, .div, .src1w, ._, ._, ._ },
+                            .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .xor, .src1d, .tmp0d, ._, ._ },
+                            .{ ._, ._, .cmp, .src1w, .sia(1, .src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .adc, .dst0d, .si(-1), ._, ._ },
+                        } },
+                    }, .{
+                        .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
+                        .patterns = &.{
+                            .{ .src = .{ .{ .to_reg = .eax }, .to_mut_gpr, .none } },
+                        },
+                        .extra_temps = .{
+                            .{ .type = .i32, .kind = .{ .reg = .edx } },
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                        },
+                        .dst_temps = .{ .{ .ref = .src0 }, .unused },
+                        .clobbers = .{ .eflags = true },
+                        .each = .{ .once = &.{
+                            .{ ._, ._, .cdq, ._, ._, ._, ._ },
+                            .{ ._, .i_, .div, .src1d, ._, ._, ._ },
+                            .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .xor, .src1d, .tmp0d, ._, ._ },
+                            .{ ._, ._, .cmp, .src1d, .sia(1, .src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .adc, .dst0d, .si(-1), ._, ._ },
+                        } },
+                    }, .{
+                        .required_features = .{ .@"64bit", null, null, null },
+                        .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any },
+                        .patterns = &.{
+                            .{ .src = .{ .{ .to_reg = .rax }, .to_mut_gpr, .none } },
+                        },
+                        .extra_temps = .{
+                            .{ .type = .i64, .kind = .{ .reg = .rdx } },
+                            .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                        },
+                        .dst_temps = .{ .{ .ref = .src0 }, .unused },
+                        .clobbers = .{ .eflags = true },
+                        .each = .{ .once = &.{
+                            .{ ._, ._, .cqo, ._, ._, ._, ._ },
+                            .{ ._, .i_, .div, .src1q, ._, ._, ._ },
+                            .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .@"and", .src1q, .tmp1q, ._, ._ },
+                            .{ ._, ._, .xor, .src1q, .tmp0q, ._, ._ },
+                            .{ ._, ._c, .st, ._, ._, ._, ._ },
+                            .{ ._, ._, .sbb, .src1q, .tmp1q, ._, ._ },
+                            .{ ._, ._, .adc, .dst0q, .si(-1), ._, ._ },
+                        } },
+                    }, .{
+                        .required_features = .{ .@"64bit", null, null, null },
+                        .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
+                        .patterns = &.{
+                            .{ .src = .{ .mem, .mem, .none } },
+                        },
+                        .call_frame = .{ .alignment = .@"16" },
+                        .extra_temps = .{
+                            .{ .type = .i128, .kind = .{ .param_gpr_pair = .{ .cc = .ccc, .at = 0 } } },
+                            .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
+                            .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
+                            .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
+                            .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divti3" } } },
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                            .unused,
+                        },
+                        .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
+                        .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
+                        .each = .{ .once = &.{
+                            .{ ._, ._, .mov, .tmp0q0, .mem(.src0q), ._, ._ },
+                            .{ ._, ._, .mov, .tmp0q1, .memd(.src0q, 8), ._, ._ },
+                            .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ },
+                            .{ ._, ._, .mov, .tmp1q, .memd(.src1q, 8), ._, ._ },
+                            .{ ._, ._, .call, .tmp2d, ._, ._, ._ },
+                            .{ ._, ._, .mov, .tmp0q0, .ua(.src0, .add_smin), ._, ._ },
+                            .{ ._, ._, .mov, .tmp1q, .memd(.src1q, 8), ._, ._ },
+                            .{ ._, ._, .mov, .tmp0q1, .tmp0q0, ._, ._ },
+                            .{ ._, ._, .@"and", .tmp0q1, .tmp1q, ._, ._ },
+                            .{ ._, ._, .xor, .tmp0q1, .dst0q1, ._, ._ },
+                            .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
+                            .{ ._, ._, .sbb, .tmp0q1, .tmp0q0, ._, ._ },
+                            .{ ._, ._, .sbb, .tmp3q, .tmp3q, ._, ._ },
+                            .{ ._, ._, .mov, .tmp0q0, .mem(.src0q), ._, ._ },
+                            .{ ._, ._, .mov, .tmp0q1, .memd(.src0q, 8), ._, ._ },
+                            .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ },
+                            .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
+                            .{ ._, ._c, .st, ._, ._, ._, ._ },
+                            .{ ._, ._, .sbb, .dst0q0, .tmp3q, ._, ._ },
+                            .{ ._, ._, .sbb, .dst0q1, .tmp3q, ._, ._ },
+                        } },
+                    }, .{
+                        .required_features = .{ .@"64bit", null, null, null },
+                        .src_constraints = .{
+                            .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
+                            .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
+                            .any,
+                        },
+                        .patterns = &.{
+                            .{ .src = .{ .to_mut_mem, .to_mut_mem, .none } },
+                        },
+                        .call_frame = .{ .alignment = .@"16" },
+                        .extra_temps = .{
+                            .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                            .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                            .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                            .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
+                            .{ .type = .i32, .kind = .{ .rc = .general_purpose } },
+                            .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } },
+                            .{ .kind = .{ .mem_of_type = .dst0 } },
+                            .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
+                            .unused,
+                            .unused,
+                            .unused,
+                        },
+                        .dst_temps = .{ .mem, .unused },
+                        .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
+                        .each = .{ .once = &.{
+                            .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
+                            .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
+                            .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
+                            .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ },
+                            .{ ._, ._, .mov, .tmp4d, .memad(.src0d, .add_size, -4), ._, ._ },
+                            .{ ._, ._, .xor, .tmp4d, .memad(.src1d, .add_size, -4), ._, ._ },
+                            .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
+                            .{ ._, ._, .@"test", .tmp4d, .tmp4d, ._, ._ },
+                            .{ ._, ._ns, .j, .@"0f", ._, ._, ._ },
+                            .{ ._, ._, .lea, .tmp0p, .mem(.tmp6), ._, ._ },
+                            .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
+                            .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
+                            .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ },
+                            .{ ._, ._, .call, .tmp7d, ._, ._, ._ },
+                            .{ ._, ._, .mov, .tmp0d, .sia(-8, .dst0, .add_size), ._, ._ },
+                            .{ .@"1:", ._, .cmp, .memi(.tmp6q, .tmp0), .si(0), ._, ._ },
+                            .{ ._, ._e, .j, .@"3f", ._, ._, ._ },
+                            .{ ._, ._, .mov, .tmp0p, .sa(.dst0, .sub_size_div_8), ._, ._ },
+                            .{ .@"2:", ._, .adc, .memsia(.dst0q, .@"8", .tmp0, .add_size), .si(-1), ._, ._ },
+                            .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
+                            .{ ._, ._nz, .j, .@"2b", ._, ._, ._ },
+                            .{ .@"3:", ._, .sub, .tmp0d, .si(8), ._, ._ },
+                            .{ ._, ._ae, .j, .@"1b", ._, ._, ._ },
+                        } },
+                    } }),
+                    .unsigned => res[0] = ops[0].divTruncInts(&ops[1], cg) catch |err| break :err err,
+                } else cg.select(&res, &.{ty}, &ops, comptime &.{ .{
                     .required_features = .{ .f16c, null, null, null },
                     .src_constraints = .{
                         .{ .scalar_float = .{ .of = .word, .is = .word } },
@@ -36494,10 +36732,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                         .{ ._, ._, .add, .tmp0p, .si(16), ._, ._ },
                         .{ ._, ._nc, .j, .@"0b", ._, ._, ._ },
                     } },
-                } }) catch |err| switch (err) {
+                } })) catch |err| switch (err) {
                     error.SelectFailed => return cg.fail("failed to select {s} {} {} {}", .{
                         @tagName(air_tag),
-                        cg.typeOf(bin_op.lhs).fmt(pt),
+                        ty.fmt(pt),
                         ops[0].tracking(cg),
                         ops[1].tracking(cg),
                     }),
@@ -36510,6 +36748,13 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
                 var res: [1]Temp = undefined;
                 cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{
+                    .src_constraints = .{ .{ .exact_int = 1 }, .{ .exact_int = 1 }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .any, .any, .none } },
+                    },
+                    .dst_temps = .{ .{ .imm = 0 }, .unused },
+                    .each = .{ .once = &.{} },
+                }, .{
                     .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
                     .patterns = &.{
                         .{ .src = .{ .mem, .mem, .none } },
@@ -36616,8 +36861,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
                     .patterns = &.{
                         .{ .src = .{
-                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
-                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
+                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
+                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
                             .none,
                         } },
                     },
@@ -36635,7 +36880,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                         .unused,
                         .unused,
                     },
-                    .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
+                    .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
                     .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
                     .each = .{ .once = &.{
                         .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
@@ -36645,8 +36890,8 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
                     .patterns = &.{
                         .{ .src = .{
-                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
-                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
+                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
+                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
                             .none,
                         } },
                     },
@@ -36664,7 +36909,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                         .unused,
                         .unused,
                     },
-                    .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
+                    .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
                     .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
                     .each = .{ .once = &.{
                         .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
@@ -36681,10 +36926,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     },
                     .call_frame = .{ .alignment = .@"16" },
                     .extra_temps = .{
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                         .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
                         .unused,
                         .unused,
@@ -36714,10 +36959,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     },
                     .call_frame = .{ .alignment = .@"16" },
                     .extra_temps = .{
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                         .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },
                         .unused,
                         .unused,
@@ -37078,12 +37323,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .call_frame = .{ .alignment = .@"16" },
                     .extra_temps = .{
                         .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
-                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                        .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                        .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                        .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                        .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                         .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
-                        .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
+                        .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
                         .unused,
                         .unused,
                         .unused,
@@ -37116,12 +37361,12 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .call_frame = .{ .alignment = .@"16" },
                     .extra_temps = .{
                         .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
-                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                        .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                         .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } },
-                        .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
+                        .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
                         .unused,
                         .unused,
                         .unused,
@@ -37154,10 +37399,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .call_frame = .{ .alignment = .@"16" },
                     .extra_temps = .{
                         .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                         .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
                         .unused,
                         .unused,
@@ -37190,10 +37435,10 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .call_frame = .{ .alignment = .@"16" },
                     .extra_temps = .{
                         .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                         .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },
                         .unused,
                         .unused,
@@ -37987,12 +38232,498 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                 };
                 try res[0].finish(inst, &.{ bin_op.lhs, bin_op.rhs }, &ops, cg);
             },
-            .mod, .mod_optimized => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, .mod) else fallback: {
+            .mod, .mod_optimized => |air_tag| if (use_old) try cg.airMulDivBinOp(inst, .mod) else {
                 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
-                if (cg.floatBits(cg.typeOf(bin_op.lhs).scalarType(zcu)) == null) break :fallback try cg.airMulDivBinOp(inst, .mod);
                 var ops = try cg.tempsFromOperands(inst, .{ bin_op.lhs, bin_op.rhs });
                 var res: [1]Temp = undefined;
                 cg.select(&res, &.{cg.typeOf(bin_op.lhs)}, &ops, comptime &.{ .{
+                    .src_constraints = .{ .{ .exact_int = 1 }, .{ .exact_int = 1 }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .any, .any, .none } },
+                    },
+                    .dst_temps = .{ .{ .imm = 0 }, .unused },
+                    .each = .{ .once = &.{} },
+                }, .{
+                    .required_features = .{ .cmov, null, null, null },
+                    .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .mem, .to_mut_gphi, .none } },
+                        .{ .src = .{ .to_gpr, .to_mut_gphi, .none } },
+                    },
+                    .extra_temps = .{
+                        .{ .type = .i8, .kind = .{ .rc = .gphi } },
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                    },
+                    .dst_temps = .{ .{ .reg = .ah }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ },
+                        .{ ._, .i_, .div, .src1b, ._, ._, ._ },
+                        .{ ._, ._, .mov, .tmp0d, .dst0d, ._, ._ },
+                        .{ ._, ._, .add, .tmp0h, .src1b, ._, ._ },
+                        .{ ._, ._, .@"and", .src1b, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .xor, .src1b, .dst0h, ._, ._ },
+                        .{ ._, ._, .cmp, .src1b, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._a, .cmov, .dst0d, .tmp0d, ._, ._ },
+                    } },
+                }, .{
+                    .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .mem, .to_gphi, .none } },
+                        .{ .src = .{ .to_gpr, .to_gphi, .none } },
+                    },
+                    .extra_temps = .{
+                        .{ .type = .i8, .kind = .{ .rc = .gphi } },
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                    },
+                    .dst_temps = .{ .{ .reg = .ah }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .movsx, .dst0d, .src0b, ._, ._ },
+                        .{ ._, .i_, .div, .src1b, ._, ._, ._ },
+                        .{ ._, ._, .mov, .tmp0d, .src1d, ._, ._ },
+                        .{ ._, ._, .@"and", .tmp0b, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .xor, .tmp0b, .dst0h, ._, ._ },
+                        .{ ._, ._, .cmp, .tmp0b, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
+                        .{ ._, ._, .add, .dst0h, .src1b, ._, ._ },
+                    } },
+                }, .{
+                    .src_constraints = .{ .{ .unsigned_int = .byte }, .{ .unsigned_int = .byte }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .mem, .mem, .none } },
+                        .{ .src = .{ .to_gpr, .mem, .none } },
+                        .{ .src = .{ .mem, .to_gpr, .none } },
+                        .{ .src = .{ .to_gpr, .to_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .ah }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .movzx, .dst0d, .src0b, ._, ._ },
+                        .{ ._, ._, .div, .src1b, ._, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .cmov, .fast_imm16, null, null },
+                    .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .dx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .cwd, ._, ._, ._, ._ },
+                        .{ ._, .i_, .div, .src1w, ._, ._, ._ },
+                        .{ ._, ._, .mov, .src0d, .dst0d, ._, ._ },
+                        .{ ._, ._, .add, .src0d, .src1d, ._, ._ },
+                        .{ ._, ._, .@"and", .src1w, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .xor, .src1d, .dst0d, ._, ._ },
+                        .{ ._, ._, .cmp, .src1w, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._a, .cmov, .dst0d, .src0d, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .cmov, null, null, null },
+                    .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .ax }, .to_mut_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .dx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .cwd, ._, ._, ._, ._ },
+                        .{ ._, .i_, .div, .src1w, ._, ._, ._ },
+                        .{ ._, ._, .mov, .src0d, .dst0d, ._, ._ },
+                        .{ ._, ._, .add, .src0d, .src1d, ._, ._ },
+                        .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .xor, .src1d, .dst0d, ._, ._ },
+                        .{ ._, ._, .cmp, .src1w, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._a, .cmov, .dst0d, .src0d, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .fast_imm16, null, null, null },
+                    .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .dx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .cwd, ._, ._, ._, ._ },
+                        .{ ._, .i_, .div, .src1w, ._, ._, ._ },
+                        .{ ._, ._, .mov, .src0d, .src1d, ._, ._ },
+                        .{ ._, ._, .@"and", .src0w, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .xor, .src0d, .dst0d, ._, ._ },
+                        .{ ._, ._, .cmp, .src0w, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
+                        .{ ._, ._, .add, .dst0d, .src1d, ._, ._ },
+                    } },
+                }, .{
+                    .src_constraints = .{ .{ .signed_int = .word }, .{ .signed_int = .word }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .dx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .cwd, ._, ._, ._, ._ },
+                        .{ ._, .i_, .div, .src1w, ._, ._, ._ },
+                        .{ ._, ._, .mov, .src0d, .src1d, ._, ._ },
+                        .{ ._, ._, .@"and", .src0d, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .xor, .src0d, .dst0d, ._, ._ },
+                        .{ ._, ._, .cmp, .src0w, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
+                        .{ ._, ._, .add, .dst0d, .src1d, ._, ._ },
+                    } },
+                }, .{
+                    .src_constraints = .{ .{ .unsigned_int = .word }, .{ .unsigned_int = .word }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .ax }, .mem, .none } },
+                        .{ .src = .{ .{ .to_reg = .ax }, .to_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .dx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
+                        .{ ._, ._, .div, .src1w, ._, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .cmov, null, null, null },
+                    .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .eax }, .to_mut_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .edx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .cdq, ._, ._, ._, ._ },
+                        .{ ._, .i_, .div, .src1d, ._, ._, ._ },
+                        .{ ._, ._, .mov, .src0d, .dst0d, ._, ._ },
+                        .{ ._, ._, .add, .src0d, .src1d, ._, ._ },
+                        .{ ._, ._, .@"and", .src1d, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .xor, .src1d, .dst0d, ._, ._ },
+                        .{ ._, ._, .cmp, .src1d, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._a, .cmov, .dst0d, .src0d, ._, ._ },
+                    } },
+                }, .{
+                    .src_constraints = .{ .{ .signed_int = .dword }, .{ .signed_int = .dword }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .edx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .cdq, ._, ._, ._, ._ },
+                        .{ ._, .i_, .div, .src1d, ._, ._, ._ },
+                        .{ ._, ._, .mov, .src0d, .src1d, ._, ._ },
+                        .{ ._, ._, .@"and", .src0d, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .xor, .src0d, .dst0d, ._, ._ },
+                        .{ ._, ._, .cmp, .src0d, .sa(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
+                        .{ ._, ._, .add, .dst0d, .src1d, ._, ._ },
+                    } },
+                }, .{
+                    .src_constraints = .{ .{ .unsigned_int = .dword }, .{ .unsigned_int = .dword }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .eax }, .mem, .none } },
+                        .{ .src = .{ .{ .to_reg = .eax }, .to_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .edx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .xor, .dst0d, .dst0d, ._, ._ },
+                        .{ ._, ._, .div, .src1d, ._, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .@"64bit", .cmov, null, null },
+                    .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .rax }, .to_mut_gpr, .none } },
+                    },
+                    .extra_temps = .{
+                        .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                    },
+                    .dst_temps = .{ .{ .reg = .rdx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .cqo, ._, ._, ._, ._ },
+                        .{ ._, .i_, .div, .src1q, ._, ._, ._ },
+                        .{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .mov, .src0q, .dst0q, ._, ._ },
+                        .{ ._, ._, .add, .src0q, .src1q, ._, ._ },
+                        .{ ._, ._, .@"and", .src1q, .tmp0q, ._, ._ },
+                        .{ ._, ._, .xor, .src1q, .dst0q, ._, ._ },
+                        .{ ._, ._, .cmp, .src1q, .tmp0q, ._, ._ },
+                        .{ ._, ._a, .cmov, .dst0q, .src0q, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .@"64bit", null, null, null },
+                    .src_constraints = .{ .{ .signed_int = .qword }, .{ .signed_int = .qword }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } },
+                    },
+                    .extra_temps = .{
+                        .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                    },
+                    .dst_temps = .{ .{ .reg = .rdx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .cqo, ._, ._, ._, ._ },
+                        .{ ._, .i_, .div, .src1q, ._, ._, ._ },
+                        .{ ._, ._, .mov, .tmp0q, .ua(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .mov, .src0q, .src1q, ._, ._ },
+                        .{ ._, ._, .@"and", .src0q, .tmp0q, ._, ._ },
+                        .{ ._, ._, .xor, .src0q, .dst0q, ._, ._ },
+                        .{ ._, ._, .cmp, .src0q, .tmp0q, ._, ._ },
+                        .{ ._, ._na, .j, .@"0f", ._, ._, ._ },
+                        .{ ._, ._, .add, .dst0q, .src1q, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .@"64bit", null, null, null },
+                    .src_constraints = .{ .{ .unsigned_int = .qword }, .{ .unsigned_int = .qword }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_reg = .rax }, .mem, .none } },
+                        .{ .src = .{ .{ .to_reg = .rax }, .to_gpr, .none } },
+                    },
+                    .dst_temps = .{ .{ .reg = .rdx }, .unused },
+                    .clobbers = .{ .eflags = true },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .xor, .dst0q, .dst0q, ._, ._ },
+                        .{ ._, ._, .div, .src1q, ._, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .@"64bit", .cmov, null, null },
+                    .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .to_mem, .none } },
+                    },
+                    .call_frame = .{ .alignment = .@"16" },
+                    .extra_temps = .{
+                        .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
+                        .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
+                        .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                    },
+                    .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
+                    .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ },
+                        .{ ._, ._, .mov, .tmp0q, .memd(.src1q, 8), ._, ._ },
+                        .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
+                        .{ ._, ._, .mov, .src0q0, .memd(.src1q, 8), ._, ._ },
+                        .{ ._, ._, .mov, .src0q1, .ua(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .mov, .tmp0q, .src0q0, ._, ._ },
+                        .{ ._, ._, .@"and", .tmp0q, .src0q1, ._, ._ },
+                        .{ ._, ._, .xor, .tmp0q, .dst0q1, ._, ._ },
+                        .{ ._, ._, .xor, .tmp2d, .tmp2d, ._, ._ },
+                        .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
+                        .{ ._, ._, .sbb, .tmp0q, .src0q1, ._, ._ },
+                        .{ ._, ._nae, .cmov, .src0q0, .tmp2q, ._, ._ },
+                        .{ ._, ._ae, .cmov, .tmp2q, .mem(.src1q), ._, ._ },
+                        .{ ._, ._, .add, .dst0q0, .tmp2q, ._, ._ },
+                        .{ ._, ._, .adc, .dst0q1, .src0q0, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .@"64bit", null, null, null },
+                    .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
+                    .patterns = &.{
+                        .{ .src = .{ .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .to_mem, .none } },
+                    },
+                    .call_frame = .{ .alignment = .@"16" },
+                    .extra_temps = .{
+                        .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
+                        .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modti3" } } },
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                    },
+                    .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
+                    .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .mov, .dst0q1, .mem(.src1q), ._, ._ },
+                        .{ ._, ._, .mov, .tmp0q, .memd(.src1q, 8), ._, ._ },
+                        .{ ._, ._, .call, .tmp1d, ._, ._, ._ },
+                        .{ ._, ._, .mov, .src0q0, .memd(.src1q, 8), ._, ._ },
+                        .{ ._, ._, .mov, .src0q1, .ua(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .mov, .tmp0q, .src0q0, ._, ._ },
+                        .{ ._, ._, .@"and", .tmp0q, .src0q1, ._, ._ },
+                        .{ ._, ._, .xor, .tmp0q, .dst0q1, ._, ._ },
+                        .{ ._, ._, .cmp, .dst0q0, .si(1), ._, ._ },
+                        .{ ._, ._, .sbb, .tmp0q, .src0q1, ._, ._ },
+                        .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
+                        .{ ._, ._, .add, .dst0q0, .mem(.src1q), ._, ._ },
+                        .{ ._, ._, .adc, .dst0q1, .src0q0, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .@"64bit", null, null, null },
+                    .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
+                    .patterns = &.{
+                        .{ .src = .{
+                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
+                            .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
+                            .none,
+                        } },
+                    },
+                    .call_frame = .{ .alignment = .@"16" },
+                    .extra_temps = .{
+                        .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodti3" } } },
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                    },
+                    .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
+                    .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .@"64bit", null, null, null },
+                    .src_constraints = .{
+                        .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
+                        .{ .remainder_signed_int = .{ .of = .dword, .is = .dword } },
+                        .any,
+                    },
+                    .patterns = &.{
+                        .{ .src = .{ .to_mut_mem, .to_mut_mem, .none } },
+                    },
+                    .call_frame = .{ .alignment = .@"16" },
+                    .extra_temps = .{
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
+                        .{ .type = .i64, .kind = .{ .rc = .general_purpose } },
+                        .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__modei4" } } },
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                    },
+                    .dst_temps = .{ .mem, .unused },
+                    .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
+                        .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
+                        .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
+                        .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ },
+                        .{ ._, ._, .mov, .tmp4q, .memad(.src1q, .add_size, -8), ._, ._ },
+                        .{ ._, ._, .call, .tmp5d, ._, ._, ._ },
+                        .{ ._, ._, .mov, .tmp0d, .sia(-3, .dst0, .add_size_div_8), ._, ._ },
+                        .{ ._, ._, .mov, .tmp1q, .ua(.src0, .add_smin), ._, ._ },
+                        .{ ._, ._, .mov, .tmp2q, .tmp4q, ._, ._ },
+                        .{ ._, ._, .@"and", .tmp2q, .tmp1q, ._, ._ },
+                        .{ ._, ._, .xor, .tmp2q, .memad(.dst0q, .add_size, -8), ._, ._ },
+                        .{ ._, ._, .cmp, .memad(.dst0q, .add_size, -16), .si(1), ._, ._ },
+                        .{ .@"0:", ._, .mov, .tmp3q, .memsi(.dst0q, .@"8", .tmp0), ._, ._ },
+                        .{ ._, ._, .sbb, .tmp3q, .si(0), ._, ._ },
+                        .{ ._, ._c, .de, .tmp0d, ._, ._, ._ },
+                        .{ ._, ._ns, .j, .@"0b", ._, ._, ._ },
+                        .{ ._, ._, .sbb, .tmp2q, .tmp1q, ._, ._ },
+                        .{ ._, ._nae, .j, .@"0f", ._, ._, ._ },
+                        .{ ._, ._, .mov, .tmp0p, .sa(.src1, .sub_size_div_8), ._, ._ },
+                        .{ ._, ._, .@"test", .tmp4q, .tmp4q, ._, ._ },
+                        .{ ._, ._ns, .j, .@"2f", ._, ._, ._ },
+                        .{ .@"1:", ._, .mov, .tmp1q, .memsia(.src1q, .@"8", .tmp0, .add_size), ._, ._ },
+                        .{ ._, ._, .sbb, .memsia(.dst0q, .@"8", .tmp0, .add_size), .tmp1q, ._, ._ },
+                        .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
+                        .{ ._, ._nz, .j, .@"1b", ._, ._, ._ },
+                        .{ ._, ._mp, .j, .@"0f", ._, ._, ._ },
+                        .{ .@"2:", ._, .mov, .tmp1q, .memsia(.src1q, .@"8", .tmp0, .add_size), ._, ._ },
+                        .{ ._, ._, .adc, .memsia(.dst0q, .@"8", .tmp0, .add_size), .tmp1q, ._, ._ },
+                        .{ ._, ._c, .in, .tmp0p, ._, ._, ._ },
+                        .{ ._, ._nz, .j, .@"2b", ._, ._, ._ },
+                    } },
+                }, .{
+                    .required_features = .{ .@"64bit", null, null, null },
+                    .src_constraints = .{
+                        .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } },
+                        .{ .remainder_unsigned_int = .{ .of = .dword, .is = .dword } },
+                        .any,
+                    },
+                    .patterns = &.{
+                        .{ .src = .{ .to_mem, .to_mem, .none } },
+                    },
+                    .call_frame = .{ .alignment = .@"16" },
+                    .extra_temps = .{
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                        .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
+                        .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__umodei4" } } },
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                        .unused,
+                    },
+                    .dst_temps = .{ .mem, .unused },
+                    .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
+                    .each = .{ .once = &.{
+                        .{ ._, ._, .lea, .tmp0p, .mem(.dst0), ._, ._ },
+                        .{ ._, ._, .lea, .tmp1p, .mem(.src0), ._, ._ },
+                        .{ ._, ._, .lea, .tmp2p, .mem(.src1), ._, ._ },
+                        .{ ._, ._, .mov, .tmp3d, .sa(.src0, .add_bit_size), ._, ._ },
+                        .{ ._, ._, .call, .tmp4d, ._, ._, ._ },
+                    } },
+                }, .{
                     .required_features = .{ .f16c, .fast_imm16, null, null },
                     .src_constraints = .{
                         .{ .scalar_float = .{ .of = .word, .is = .word } },
@@ -160281,9 +161012,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     inline .memcpy, .memmove => |symbol| comptime &.{.{
                         .patterns = &.{
                             .{ .src = .{
-                                .{ .to_param_gpr = .{ .cc = .ccc, .index = 0 } },
-                                .{ .to_param_gpr = .{ .cc = .ccc, .index = 1 } },
-                                .{ .to_param_gpr = .{ .cc = .ccc, .index = 2 } },
+                                .{ .to_param_gpr = .{ .cc = .ccc, .at = 0 } },
+                                .{ .to_param_gpr = .{ .cc = .ccc, .at = 1 } },
+                                .{ .to_param_gpr = .{ .cc = .ccc, .at = 2 } },
                             } },
                         },
                         .call_frame = .{ .alignment = .@"16" },
@@ -160333,7 +161064,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .required_features = .{ .avx, null, null, null },
                     .src_constraints = .{ .{ .int = .gpr }, .any, .any },
                     .patterns = &.{
-                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
+                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
                     },
                     .call_frame = .{ .alignment = .@"32" },
                     .extra_temps = .{
@@ -160359,7 +161090,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .required_features = .{ .sse, null, null, null },
                     .src_constraints = .{ .{ .int = .gpr }, .any, .any },
                     .patterns = &.{
-                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
+                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
                     },
                     .call_frame = .{ .alignment = .@"16" },
                     .extra_temps = .{
@@ -160384,7 +161115,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                 }, .{
                     .src_constraints = .{ .{ .int = .gpr }, .any, .any },
                     .patterns = &.{
-                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
+                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
                     },
                     .call_frame = .{ .alignment = .@"8" },
                     .extra_temps = .{
@@ -160424,7 +161155,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .required_features = .{ .avx, null, null, null },
                     .src_constraints = .{ .{ .int = .gpr }, .any, .any },
                     .patterns = &.{
-                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
+                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
                     },
                     .call_frame = .{ .alignment = .@"32" },
                     .extra_temps = .{
@@ -160440,7 +161171,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                         .unused,
                         .unused,
                     },
-                    .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .index = 1 } }, .unused },
+                    .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .at = 1 } }, .unused },
                     .clobbers = .{ .eflags = true, .caller_preserved = .zigcc },
                     .each = .{ .once = &.{
                         .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
@@ -160449,7 +161180,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .required_features = .{ .sse, null, null, null },
                     .src_constraints = .{ .{ .int = .gpr }, .any, .any },
                     .patterns = &.{
-                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
+                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
                     },
                     .call_frame = .{ .alignment = .@"16" },
                     .extra_temps = .{
@@ -160465,7 +161196,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                         .unused,
                         .unused,
                     },
-                    .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .index = 1 } }, .unused },
+                    .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .at = 1 } }, .unused },
                     .clobbers = .{ .eflags = true, .caller_preserved = .zigcc },
                     .each = .{ .once = &.{
                         .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
@@ -160473,7 +161204,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                 }, .{
                     .src_constraints = .{ .{ .int = .gpr }, .any, .any },
                     .patterns = &.{
-                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
+                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
                     },
                     .call_frame = .{ .alignment = .@"8" },
                     .extra_temps = .{
@@ -160489,7 +161220,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                         .unused,
                         .unused,
                     },
-                    .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .index = 1 } }, .unused },
+                    .dst_temps = .{ .{ .ret_gpr = .{ .cc = .zigcc, .at = 1 } }, .unused },
                     .clobbers = .{ .eflags = true, .caller_preserved = .zigcc },
                     .each = .{ .once = &.{
                         .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
@@ -160621,7 +161352,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .required_features = .{ .avx, null, null, null },
                     .src_constraints = .{ .{ .int = .gpr }, .any, .any },
                     .patterns = &.{
-                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
+                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
                     },
                     .call_frame = .{ .alignment = .@"32" },
                     .extra_temps = .{
@@ -160647,7 +161378,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                     .required_features = .{ .sse, null, null, null },
                     .src_constraints = .{ .{ .int = .gpr }, .any, .any },
                     .patterns = &.{
-                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
+                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
                     },
                     .call_frame = .{ .alignment = .@"16" },
                     .extra_temps = .{
@@ -160672,7 +161403,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
                 }, .{
                     .src_constraints = .{ .{ .int = .gpr }, .any, .any },
                     .patterns = &.{
-                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .index = 0 } }, .none, .none } },
+                        .{ .src = .{ .{ .to_param_gpr = .{ .cc = .zigcc, .at = 0 } }, .none, .none } },
                     },
                     .call_frame = .{ .alignment = .@"8" },
                     .extra_temps = .{
@@ -162921,7 +163652,7 @@ fn getValueIfFree(self: *CodeGen, value: MCValue, inst: ?Air.Inst.Index) void {
 
 fn freeReg(self: *CodeGen, reg: Register) !void {
     self.register_manager.freeReg(reg);
-    if (reg.class() == .x87) try self.asmRegister(.{ .f_, .free }, reg);
+    if (reg.isClass(.x87)) try self.asmRegister(.{ .f_, .free }, reg);
 }
 
 fn freeValue(self: *CodeGen, value: MCValue) !void {
@@ -163840,7 +164571,7 @@ fn airIntCast(self: *CodeGen, inst: Air.Inst.Index) !void {
             else => src_int_info.bits,
         };
 
-        const dst_mcv = if ((if (src_mcv.getReg()) |src_reg| src_reg.class() == .general_purpose else src_abi_size > 8) and
+        const dst_mcv = if ((if (src_mcv.getReg()) |src_reg| src_reg.isClass(.general_purpose) else src_abi_size > 8) and
             dst_int_info.bits <= src_storage_bits and
             std.math.divCeil(u16, dst_int_info.bits, 64) catch unreachable ==
                 std.math.divCeil(u32, src_storage_bits, 64) catch unreachable and
@@ -163921,7 +164652,7 @@ fn airTrunc(self: *CodeGen, inst: Air.Inst.Index) !void {
             if (src_mcv.getReg()) |reg| self.register_manager.lockRegAssumeUnused(reg) else null;
         defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
 
-        const dst_mcv = if (src_mcv.isRegister() and src_mcv.getReg().?.class() == self.regClassForType(dst_ty) and
+        const dst_mcv = if (src_mcv.isRegister() and src_mcv.getReg().?.isClass(self.regClassForType(dst_ty)) and
             self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
             src_mcv
         else if (dst_abi_size <= 8)
@@ -176332,7 +177063,11 @@ fn genSetReg(
                 ),
             },
             .ip, .cr, .dr => unreachable,
-        },
+        } else if ((dst_reg.class() == .gphi) != (src_reg.class() == .gphi)) try self.asmRegisterRegister(
+            .{ ._, .mov },
+            dst_reg.to8(),
+            src_reg.to8(),
+        ),
         inline .register_pair,
         .register_triple,
         .register_quadruple,
@@ -176452,7 +177187,7 @@ fn genSetReg(
             });
         },
         .register_mask => |src_reg_mask| {
-            assert(src_reg_mask.reg.class() == .sse);
+            assert(src_reg_mask.reg.isClass(.sse));
             const has_avx = self.hasFeature(.avx);
             const bits_reg = switch (dst_reg.class()) {
                 .general_purpose => dst_reg,
@@ -177055,7 +177790,7 @@ fn airBitCast(self: *CodeGen, inst: Air.Inst.Index) !void {
         defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
 
         const dst_mcv = if (src_mcv != .register_mask and
-            (if (src_mcv.getReg()) |src_reg| src_reg.class() == .general_purpose else true) and
+            (if (src_mcv.getReg()) |src_reg| src_reg.isClass(.general_purpose) else true) and
             dst_rc.supersetOf(src_rc) and dst_ty.abiSize(zcu) <= src_ty.abiSize(zcu) and
             dst_ty.abiAlignment(zcu).order(src_ty.abiAlignment(zcu)).compare(.lte) and
             self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) src_mcv else dst: {
@@ -179909,7 +180644,7 @@ fn airReduce(self: *CodeGen, inst: Air.Inst.Index) !void {
                         const operand_reg = registerAlias(operand_reg: {
                             if (operand_mcv.isRegister()) {
                                 const operand_reg = operand_mcv.getReg().?;
-                                if (operand_reg.class() == .general_purpose) break :operand_reg operand_reg;
+                                if (operand_reg.isClass(.general_purpose)) break :operand_reg operand_reg;
                             }
                             break :operand_reg try self.copyToTmpRegister(operand_ty, operand_mcv);
                         }, abi_size);
@@ -180779,12 +181514,12 @@ fn resolveCallingConventionValues(
                             ret_tracking_i += 1;
                         }
                     },
-                    .sseup => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .sse),
+                    .sseup => assert(ret_tracking[ret_tracking_i - 1].short.register.isClass(.sse)),
                     .x87 => {
                         ret_tracking[ret_tracking_i] = .init(.{ .register = abi.getCAbiX87ReturnRegs(cc)[0] });
                         ret_tracking_i += 1;
                     },
-                    .x87up => assert(ret_tracking[ret_tracking_i - 1].short.register.class() == .x87),
+                    .x87up => assert(ret_tracking[ret_tracking_i - 1].short.register.isClass(.x87)),
                     .complex_x87 => {
                         ret_tracking[ret_tracking_i] = .init(.{ .register_pair = abi.getCAbiX87ReturnRegs(cc)[0..2].* });
                         ret_tracking_i += 1;
@@ -180871,7 +181606,7 @@ fn resolveCallingConventionValues(
                             arg_mcv_i += 1;
                         }
                     },
-                    .sseup => assert(arg_mcv[arg_mcv_i - 1].register.class() == .sse),
+                    .sseup => assert(arg_mcv[arg_mcv_i - 1].register.isClass(.sse)),
                     .x87, .x87up, .complex_x87, .memory, .win_i128 => switch (cc) {
                         .x86_64_sysv => switch (class) {
                             .x87, .x87up, .complex_x87, .memory => break,
@@ -181864,8 +182599,8 @@ const Temp = struct {
         const val = temp.tracking(cg).short;
         if (!mut or temp.isMut(cg)) switch (val) {
             else => {},
-            .register => |reg| if (reg.class() == rc) return false,
-            .register_offset => |reg_off| if (reg_off.reg.class() == rc and reg_off.off == 0) return false,
+            .register => |reg| if (reg.isClass(rc)) return false,
+            .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.isClass(rc)) return false,
         };
         const ty = temp.typeOf(cg);
         const new_temp_index = cg.next_temp_index;
@@ -185888,6 +186623,21 @@ const Temp = struct {
         var ops: [2]Temp = .{ lhs.*, rhs.* };
         var res: [1]Temp = undefined;
         try cg.select(&res, &.{lhs.typeOf(cg)}, &ops, comptime &.{ .{
+            .src_constraints = .{ .{ .exact_signed_int = 1 }, .{ .exact_signed_int = 1 }, .any },
+            .patterns = &.{
+                .{ .src = .{ .any, .any, .none } },
+            },
+            .dst_temps = .{ .{ .imm = 0 }, .unused },
+            .each = .{ .once = &.{} },
+        }, .{
+            .src_constraints = .{ .{ .exact_unsigned_int = 1 }, .{ .exact_unsigned_int = 1 }, .any },
+            .patterns = &.{
+                .{ .src = .{ .mut_mem, .any, .none } },
+                .{ .src = .{ .to_mut_gpr, .any, .none } },
+            },
+            .dst_temps = .{ .{ .ref = .src0 }, .unused },
+            .each = .{ .once = &.{} },
+        }, .{
             .src_constraints = .{ .{ .signed_int = .byte }, .{ .signed_int = .byte }, .any },
             .patterns = &.{
                 .{ .src = .{ .mem, .mem, .none } },
@@ -186072,8 +186822,8 @@ const Temp = struct {
             .src_constraints = .{ .{ .signed_int = .xword }, .{ .signed_int = .xword }, .any },
             .patterns = &.{
                 .{ .src = .{
-                    .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
-                    .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
+                    .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
+                    .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
                     .none,
                 } },
             },
@@ -186091,7 +186841,7 @@ const Temp = struct {
                 .unused,
                 .unused,
             },
-            .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
+            .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
             .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
             .each = .{ .once = &.{
                 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
@@ -186101,8 +186851,8 @@ const Temp = struct {
             .src_constraints = .{ .{ .unsigned_int = .xword }, .{ .unsigned_int = .xword }, .any },
             .patterns = &.{
                 .{ .src = .{
-                    .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 0 } },
-                    .{ .to_param_gpr_pair = .{ .cc = .ccc, .index = 2 } },
+                    .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 0 } },
+                    .{ .to_param_gpr_pair = .{ .cc = .ccc, .at = 2 } },
                     .none,
                 } },
             },
@@ -186120,7 +186870,7 @@ const Temp = struct {
                 .unused,
                 .unused,
             },
-            .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .index = 0 } }, .unused },
+            .dst_temps = .{ .{ .ret_gpr_pair = .{ .cc = .ccc, .at = 0 } }, .unused },
             .clobbers = .{ .eflags = true, .caller_preserved = .ccc },
             .each = .{ .once = &.{
                 .{ ._, ._, .call, .tmp0d, ._, ._, ._ },
@@ -186137,10 +186887,10 @@ const Temp = struct {
             },
             .call_frame = .{ .alignment = .@"16" },
             .extra_temps = .{
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } },
                 .unused,
                 .unused,
@@ -186170,10 +186920,10 @@ const Temp = struct {
             },
             .call_frame = .{ .alignment = .@"16" },
             .extra_temps = .{
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivei4" } } },
                 .unused,
                 .unused,
@@ -186534,12 +187284,12 @@ const Temp = struct {
             .call_frame = .{ .alignment = .@"16" },
             .extra_temps = .{
                 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
-                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                .{ .type = .i64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divti3" } } },
-                .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
+                .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
                 .unused,
                 .unused,
                 .unused,
@@ -186572,12 +187322,12 @@ const Temp = struct {
             .call_frame = .{ .alignment = .@"16" },
             .extra_temps = .{
                 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
-                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                .{ .type = .u64, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivti3" } } },
-                .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .index = 0 } } },
+                .{ .type = .u64, .kind = .{ .ret_gpr = .{ .cc = .ccc, .at = 0 } } },
                 .unused,
                 .unused,
                 .unused,
@@ -186610,10 +187360,10 @@ const Temp = struct {
             .call_frame = .{ .alignment = .@"16" },
             .extra_temps = .{
                 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__divei4" } } },
                 .unused,
                 .unused,
@@ -186646,10 +187396,10 @@ const Temp = struct {
             .call_frame = .{ .alignment = .@"16" },
             .extra_temps = .{
                 .{ .type = .isize, .kind = .{ .rc = .general_purpose } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 0 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 1 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 2 } } },
-                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .index = 3 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 0 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 1 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 2 } } },
+                .{ .type = .usize, .kind = .{ .param_gpr = .{ .cc = .ccc, .at = 3 } } },
                 .{ .type = .usize, .kind = .{ .symbol = &.{ .name = "__udivei4" } } },
                 .unused,
                 .unused,
@@ -187117,8 +187867,7 @@ const Select = struct {
     }
 
     fn lowerReg(s: *const Select, reg: Register) Register {
-        if (reg.class() != .x87) return reg;
-        return @enumFromInt(@intFromEnum(Register.st0) + (@as(u3, @intCast(reg.enc())) -% s.top));
+        return if (reg.isClass(.x87)) @enumFromInt(@intFromEnum(Register.st0) + (@as(u3, @intCast(reg.enc())) -% s.top)) else reg;
     }
 
     const Case = struct {
@@ -187505,6 +188254,8 @@ const Select = struct {
             to_gpr,
             mut_gpr,
             to_mut_gpr,
+            to_gphi,
+            to_mut_gphi,
             x87,
             to_x87,
             mut_x87,
@@ -187581,84 +188332,84 @@ const Select = struct {
                     .mut_mem => temp.isMut(cg) and temp.tracking(cg).short.isMemory(),
                     .to_reg, .to_reg_pair, .to_param_gpr, .to_param_gpr_pair, .to_ret_gpr, .to_ret_gpr_pair => true,
                     .gpr => temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .general_purpose,
-                        .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.general_purpose),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.general_purpose) and reg_off.off == 0,
                         else => false,
                     },
                     .immut_gpr => !temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .general_purpose,
-                        .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.general_purpose),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.general_purpose) and reg_off.off == 0,
                         else => false,
                     },
                     .mut_gpr => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8 and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .general_purpose,
-                        .register_offset => |reg_off| reg_off.reg.class() == .general_purpose and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.general_purpose),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.general_purpose) and reg_off.off == 0,
                         else => false,
                     },
-                    .to_gpr, .to_mut_gpr => temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8,
+                    .to_gpr, .to_mut_gpr, .to_gphi, .to_mut_gphi => temp.typeOf(cg).abiSize(cg.pt.zcu) <= 8,
                     .x87 => switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .x87,
-                        .register_offset => |reg_off| reg_off.reg.class() == .x87 and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.x87),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.x87) and reg_off.off == 0,
                         else => false,
                     },
                     .mut_x87 => temp.isMut(cg) and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .x87,
-                        .register_offset => |reg_off| reg_off.reg.class() == .x87 and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.x87),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.x87) and reg_off.off == 0,
                         else => false,
                     },
                     .to_x87, .to_mut_x87 => true,
                     .mmx => switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .mmx,
-                        .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.mmx),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0,
                         else => false,
                     },
                     .mut_mmx => temp.isMut(cg) and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .mmx,
-                        .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.mmx),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0,
                         else => false,
                     },
                     .to_mmx, .to_mut_mmx => true,
                     .mm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 8 and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .mmx,
-                        .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.mmx),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0,
                         else => false,
                     },
                     .mut_mm => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) == 8 and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .mmx,
-                        .register_offset => |reg_off| reg_off.reg.class() == .mmx and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.mmx),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.mmx) and reg_off.off == 0,
                         else => false,
                     },
                     .to_mm, .to_mut_mm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 8,
                     .sse => switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .sse,
-                        .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.sse),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
                         else => false,
                     },
                     .mut_sse => temp.isMut(cg) and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .sse,
-                        .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.sse),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
                         else => false,
                     },
                     .to_sse, .to_mut_sse => true,
                     .xmm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 16 and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .sse,
-                        .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.sse),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
                         else => false,
                     },
                     .mut_xmm => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) == 16 and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .sse,
-                        .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.sse),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
                         else => false,
                     },
                     .to_xmm, .to_mut_xmm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 16,
                     .ymm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 32 and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .sse,
-                        .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.sse),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
                         else => false,
                     },
                     .mut_ymm => temp.isMut(cg) and temp.typeOf(cg).abiSize(cg.pt.zcu) == 32 and switch (temp.tracking(cg).short) {
-                        .register => |reg| reg.class() == .sse,
-                        .register_offset => |reg_off| reg_off.reg.class() == .sse and reg_off.off == 0,
+                        .register => |reg| reg.isClass(.sse),
+                        .register_offset => |reg_off| reg_off.reg.isClass(.sse) and reg_off.off == 0,
                         else => false,
                     },
                     .to_ymm, .to_mut_ymm => temp.typeOf(cg).abiSize(cg.pt.zcu) == 32,
@@ -187684,12 +188435,14 @@ const Select = struct {
                     .mut_mem, .to_mut_mem => try temp.toBase(true, cg),
                     .to_reg => |reg| try temp.toReg(reg, cg),
                     .to_reg_pair => |regs| try temp.toRegPair(regs, cg),
-                    .to_param_gpr => |param_spec| try temp.toReg(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index], cg),
-                    .to_param_gpr_pair => |param_spec| try temp.toRegPair(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*, cg),
-                    .to_ret_gpr => |ret_spec| try temp.toReg(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index], cg),
-                    .to_ret_gpr_pair => |ret_spec| try temp.toRegPair(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*, cg),
+                    .to_param_gpr => |param_spec| try temp.toReg(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at], cg),
+                    .to_param_gpr_pair => |param_spec| try temp.toRegPair(abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..2].*, cg),
+                    .to_ret_gpr => |ret_spec| try temp.toReg(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at], cg),
+                    .to_ret_gpr_pair => |ret_spec| try temp.toRegPair(abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..2].*, cg),
                     .gpr, .immut_gpr, .to_gpr => try temp.toRegClass(false, .general_purpose, cg),
                     .mut_gpr, .to_mut_gpr => try temp.toRegClass(true, .general_purpose, cg),
+                    .to_gphi => try temp.toRegClass(false, .gphi, cg),
+                    .to_mut_gphi => try temp.toRegClass(true, .gphi, cg),
                     .x87, .to_x87 => try temp.toRegClass(false, .x87, cg),
                     .mut_x87, .to_mut_x87 => try temp.toRegClass(true, .x87, cg),
                     .mmx, .to_mmx, .mm, .to_mm => try temp.toRegClass(false, .mmx, cg),
@@ -187761,7 +188514,7 @@ const Select = struct {
 
             const CallConvRegSpec = struct {
                 cc: Case.CallConv,
-                index: u2,
+                at: u2,
 
                 fn tag(spec: CallConvRegSpec, cg: *const CodeGen) std.builtin.CallingConvention.Tag {
                     return switch (spec.cc) {
@@ -187778,10 +188531,10 @@ const Select = struct {
                     else => return reg_locks,
                     .reg => |reg| .{ reg, .none },
                     .reg_pair => |regs| regs,
-                    .param_gpr => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..1].* ++ .{.none},
-                    .param_gpr_pair => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*,
-                    .ret_gpr => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..1].* ++ .{.none},
-                    .ret_gpr_pair => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*,
+                    .param_gpr => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..1].* ++ .{.none},
+                    .param_gpr_pair => |param_spec| abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..2].*,
+                    .ret_gpr => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..1].* ++ .{.none},
+                    .ret_gpr_pair => |ret_spec| abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..2].*,
                 };
                 for (regs, &reg_locks) |reg, *reg_lock| {
                     if (reg == .none) continue;
@@ -187791,13 +188544,6 @@ const Select = struct {
                 }
                 return reg_locks;
             }
-
-            fn finish(kind: Kind, temp: Temp, cg: *CodeGen) void {
-                switch (kind) {
-                    else => {},
-                    inline .rc_mask, .mut_rc_mask, .ref_mask => |mask| temp.asMask(mask.info, cg),
-                }
-            }
         };
 
         fn create(spec: TempSpec, s: *const Select) InnerError!struct { Temp, bool } {
@@ -187822,24 +188568,24 @@ const Select = struct {
                 .reg => |reg| .{ try cg.tempInit(spec.type, .{ .register = reg }), true },
                 .reg_pair => |regs| .{ try cg.tempInit(spec.type, .{ .register_pair = regs }), true },
                 .param_gpr => |param_spec| .{ try cg.tempInit(spec.type, .{
-                    .register = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index],
+                    .register = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at],
                 }), true },
                 .param_gpr_pair => |param_spec| .{ try cg.tempInit(spec.type, .{
-                    .register_pair = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.index..][0..2].*,
+                    .register_pair = abi.getCAbiIntParamRegs(param_spec.tag(cg))[param_spec.at..][0..2].*,
                 }), true },
                 .ret_gpr => |ret_spec| .{ try cg.tempInit(spec.type, .{
-                    .register = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index],
+                    .register = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at],
                 }), true },
                 .ret_gpr_pair => |ret_spec| .{ try cg.tempInit(spec.type, .{
-                    .register_pair = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.index..][0..2].*,
+                    .register_pair = abi.getCAbiIntReturnRegs(ret_spec.tag(cg))[ret_spec.at..][0..2].*,
                 }), true },
                 .rc => |rc| .{ try cg.tempAllocReg(spec.type, regSetForRegClass(rc)), true },
                 .rc_pair => |rc| .{ try cg.tempAllocRegPair(spec.type, regSetForRegClass(rc)), true },
                 .mut_rc => |ref_rc| {
                     const temp = ref_rc.ref.tempOf(s);
                     if (temp.isMut(cg)) switch (temp.tracking(cg).short) {
-                        .register => |reg| if (reg.class() == ref_rc.rc) return .{ temp, false },
-                        .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.class() == ref_rc.rc) return .{ temp, false },
+                        .register => |reg| if (reg.isClass(ref_rc.rc)) return .{ temp, false },
+                        .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.isClass(ref_rc.rc)) return .{ temp, false },
                         else => {},
                     };
                     return .{ try cg.tempAllocReg(spec.type, regSetForRegClass(ref_rc.rc)), true };
@@ -187849,8 +188595,8 @@ const Select = struct {
                 .mut_rc_mask => |ref_rc_mask| {
                     const temp = ref_rc_mask.ref.tempOf(s);
                     if (temp.isMut(cg)) switch (temp.tracking(cg).short) {
-                        .register => |reg| if (reg.class() == ref_rc_mask.rc) return .{ temp, false },
-                        .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.class() == ref_rc_mask.rc) return .{ temp, false },
+                        .register => |reg| if (reg.isClass(ref_rc_mask.rc)) return .{ temp, false },
+                        .register_offset => |reg_off| if (reg_off.off == 0 and reg_off.reg.isClass(ref_rc_mask.rc)) return .{ temp, false },
                         else => {},
                     };
                     return .{ try cg.tempAllocReg(spec.type, regSetForRegClass(ref_rc_mask.rc)), true };
@@ -188228,6 +188974,14 @@ const Select = struct {
                 } }), true },
             };
         }
+
+        fn finish(spec: TempSpec, temp: *Temp, cg: *CodeGen) InnerError!void {
+            switch (spec.kind) {
+                else => {},
+                inline .rc_mask, .mut_rc_mask, .ref_mask => |mask| temp.asMask(mask.info, cg),
+            }
+            cg.temp_type[@intFromEnum(temp.unwrap(cg).temp)] = spec.type;
+        }
     };
 
     const Instruction = struct {
@@ -188255,8 +189009,7 @@ const Select = struct {
 
         const Tag = enum(u3) {
             none,
-            backward_label,
-            forward_label,
+            label,
             ref,
             simm,
             uimm,
@@ -188626,16 +189379,16 @@ const Select = struct {
 
         const @"_": Select.Operand = .{ .flags = .{ .tag = .none } };
 
-        const @"0b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp0, .size = .none } } };
-        const @"0f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp0, .size = .none } } };
-        const @"1b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp1, .size = .none } } };
-        const @"1f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp1, .size = .none } } };
-        const @"2b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp2, .size = .none } } };
-        const @"2f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp2, .size = .none } } };
-        const @"3b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp3, .size = .none } } };
-        const @"3f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp3, .size = .none } } };
-        const @"4b": Select.Operand = .{ .flags = .{ .tag = .backward_label, .base = .{ .ref = .tmp4, .size = .none } } };
-        const @"4f": Select.Operand = .{ .flags = .{ .tag = .forward_label, .base = .{ .ref = .tmp4, .size = .none } } };
+        const @"0b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 0) };
+        const @"0f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 0) };
+        const @"1b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 1) };
+        const @"1f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 1) };
+        const @"2b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 2) };
+        const @"2f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 2) };
+        const @"3b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 3) };
+        const @"3f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 3) };
+        const @"4b": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = ~@as(i32, 4) };
+        const @"4f": Select.Operand = .{ .flags = .{ .tag = .label }, .imm = @as(i32, 4) };
 
         const tmp0l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0l } };
         const tmp0h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0h } };
@@ -188648,6 +189401,8 @@ const Select = struct {
         const tmp0t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0t } };
         const tmp0x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0x } };
         const tmp0y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0y } };
+        const tmp0q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0q }, .imm = 1 };
+        const tmp0q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp0q }, .imm = 2 };
 
         const tmp1l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1l } };
         const tmp1h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1h } };
@@ -188660,6 +189415,8 @@ const Select = struct {
         const tmp1t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1t } };
         const tmp1x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1x } };
         const tmp1y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1y } };
+        const tmp1q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1q }, .imm = 1 };
+        const tmp1q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp1q }, .imm = 2 };
 
         const tmp2l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2l } };
         const tmp2h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2h } };
@@ -188672,6 +189429,8 @@ const Select = struct {
         const tmp2t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2t } };
         const tmp2x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2x } };
         const tmp2y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2y } };
+        const tmp2q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2q }, .imm = 1 };
+        const tmp2q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp2q }, .imm = 2 };
 
         const tmp3l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3l } };
         const tmp3h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3h } };
@@ -188684,6 +189443,8 @@ const Select = struct {
         const tmp3t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3t } };
         const tmp3x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3x } };
         const tmp3y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3y } };
+        const tmp3q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3q }, .imm = 1 };
+        const tmp3q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp3q }, .imm = 2 };
 
         const tmp4l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4l } };
         const tmp4h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4h } };
@@ -188696,6 +189457,8 @@ const Select = struct {
         const tmp4t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4t } };
         const tmp4x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4x } };
         const tmp4y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4y } };
+        const tmp4q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4q }, .imm = 1 };
+        const tmp4q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp4q }, .imm = 2 };
 
         const tmp5l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5l } };
         const tmp5h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5h } };
@@ -188708,6 +189471,8 @@ const Select = struct {
         const tmp5t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5t } };
         const tmp5x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5x } };
         const tmp5y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5y } };
+        const tmp5q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5q }, .imm = 1 };
+        const tmp5q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp5q }, .imm = 2 };
 
         const tmp6l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6l } };
         const tmp6h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6h } };
@@ -188720,6 +189485,8 @@ const Select = struct {
         const tmp6t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6t } };
         const tmp6x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6x } };
         const tmp6y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6y } };
+        const tmp6q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6q }, .imm = 1 };
+        const tmp6q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp6q }, .imm = 2 };
 
         const tmp7l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7l } };
         const tmp7h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7h } };
@@ -188732,6 +189499,8 @@ const Select = struct {
         const tmp7t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7t } };
         const tmp7x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7x } };
         const tmp7y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7y } };
+        const tmp7q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7q }, .imm = 1 };
+        const tmp7q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp7q }, .imm = 2 };
 
         const tmp8l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8l } };
         const tmp8h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8h } };
@@ -188744,6 +189513,8 @@ const Select = struct {
         const tmp8t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8t } };
         const tmp8x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8x } };
         const tmp8y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8y } };
+        const tmp8q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8q }, .imm = 1 };
+        const tmp8q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp8q }, .imm = 2 };
 
         const tmp9l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9l } };
         const tmp9h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9h } };
@@ -188756,6 +189527,8 @@ const Select = struct {
         const tmp9t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9t } };
         const tmp9x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9x } };
         const tmp9y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9y } };
+        const tmp9q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9q }, .imm = 1 };
+        const tmp9q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp9q }, .imm = 2 };
 
         const tmp10l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10l } };
         const tmp10h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10h } };
@@ -188768,6 +189541,8 @@ const Select = struct {
         const tmp10t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10t } };
         const tmp10x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10x } };
         const tmp10y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10y } };
+        const tmp10q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10q }, .imm = 1 };
+        const tmp10q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .tmp10q }, .imm = 2 };
 
         const dst0l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0l } };
         const dst0h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0h } };
@@ -188780,6 +189555,8 @@ const Select = struct {
         const dst0t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0t } };
         const dst0x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0x } };
         const dst0y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0y } };
+        const dst0q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0q }, .imm = 1 };
+        const dst0q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst0q }, .imm = 2 };
 
         const dst1l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1l } };
         const dst1h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1h } };
@@ -188792,6 +189569,8 @@ const Select = struct {
         const dst1t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1t } };
         const dst1x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1x } };
         const dst1y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1y } };
+        const dst1q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1q }, .imm = 1 };
+        const dst1q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .dst1q }, .imm = 2 };
 
         const src0l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0l } };
         const src0h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0h } };
@@ -188804,6 +189583,8 @@ const Select = struct {
         const src0t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0t } };
         const src0x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0x } };
         const src0y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0y } };
+        const src0q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0q }, .imm = 1 };
+        const src0q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src0q }, .imm = 2 };
 
         const src1l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1l } };
         const src1h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1h } };
@@ -188816,6 +189597,8 @@ const Select = struct {
         const src1t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1t } };
         const src1x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1x } };
         const src1y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1y } };
+        const src1q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1q }, .imm = 1 };
+        const src1q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src1q }, .imm = 2 };
 
         const src2l: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2l } };
         const src2h: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2h } };
@@ -188828,6 +189611,8 @@ const Select = struct {
         const src2t: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2t } };
         const src2x: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2x } };
         const src2y: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2y } };
+        const src2q0: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2q }, .imm = 1 };
+        const src2q1: Select.Operand = .{ .flags = .{ .tag = .ref, .base = .src2q }, .imm = 2 };
 
         fn si(imm: i32) Select.Operand {
             return .{ .flags = .{ .tag = .simm }, .imm = imm };
@@ -189207,24 +189992,41 @@ const Select = struct {
         fn lower(op: Select.Operand, s: *Select) InnerError!CodeGen.Operand {
             return switch (op.flags.tag) {
                 .none => .none,
-                .backward_label => .{ .inst = s.labels[@intFromEnum(op.flags.base.ref)].backward.? },
-                .forward_label => for (&s.labels[@intFromEnum(op.flags.base.ref)].forward) |*label| {
+                .label => if (op.imm < 0)
+                    .{ .inst = s.labels[@intCast(~op.imm)].backward.? }
+                else for (&s.labels[@intCast(op.imm)].forward) |*label| {
                     if (label.*) |_| continue;
                     label.* = @intCast(s.cg.mir_instructions.len);
                     break .{ .inst = undefined };
                 } else unreachable,
-                .ref => switch (op.flags.base.ref.valueOf(s)) {
-                    .immediate => |imm| .{ .imm = switch (op.flags.base.size) {
-                        .byte => if (std.math.cast(i8, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u8, @intCast(imm))),
-                        .word => if (std.math.cast(i16, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u16, @intCast(imm))),
-                        .dword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u32, @intCast(imm))),
-                        .qword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(imm),
-                        else => unreachable,
-                    } },
-                    else => |mcv| .{ .mem = try mcv.mem(s.cg, .{ .size = op.flags.base.size }) },
-                    .register => |reg| .{ .reg = s.lowerReg(reg.toSize(op.flags.base.size, s.cg.target)) },
-                    .register_mask => |reg_mask| .{ .reg = s.lowerReg(reg_mask.reg.toSize(op.flags.base.size, s.cg.target)) },
-                    .lea_symbol => |sym_off| .{ .imm = .rel(sym_off) },
+                .ref => switch (op.imm) {
+                    else => unreachable,
+                    0 => switch (op.flags.base.ref.valueOf(s)) {
+                        .none, .unreach, .dead, .undef => unreachable,
+                        .immediate => |imm| .{ .imm = switch (op.flags.base.size) {
+                            .byte => if (std.math.cast(i8, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u8, @intCast(imm))),
+                            .word => if (std.math.cast(i16, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u16, @intCast(imm))),
+                            .dword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(@as(u32, @intCast(imm))),
+                            .qword => if (std.math.cast(i32, @as(i64, @bitCast(imm)))) |simm| .s(simm) else .u(imm),
+                            else => unreachable,
+                        } },
+                        .eflags => unreachable,
+                        .register => |reg| .{ .reg = s.lowerReg(reg.toSize(op.flags.base.size, s.cg.target)) },
+                        .register_pair, .register_triple, .register_quadruple, .register_offset, .register_overflow => unreachable,
+                        .register_mask => |reg_mask| .{ .reg = s.lowerReg(reg_mask.reg.toSize(op.flags.base.size, s.cg.target)) },
+                        else => |mcv| .{ .mem = try mcv.mem(s.cg, .{ .size = op.flags.base.size }) },
+                        .lea_symbol => |sym_off| .{ .imm = .rel(sym_off) },
+                        .load_direct, .lea_direct, .load_got, .lea_got, .lea_frame, .elementwise_args, .reserved_frame, .air_ref => unreachable,
+                    },
+                    1...2 => |imm| switch (op.flags.base.ref.valueOf(s)) {
+                        inline .register_pair, .register_triple, .register_quadruple => |regs| .{
+                            .reg = s.lowerReg(regs[@intCast(imm - 1)].toSize(op.flags.base.size, s.cg.target)),
+                        },
+                        else => |mcv| .{ .mem = try mcv.mem(s.cg, .{
+                            .size = op.flags.base.size,
+                            .disp = @as(i32, @intCast(@divExact(op.flags.base.size.bitSize(s.cg.target), 8))) * (imm - 1),
+                        }) },
+                    },
                 },
                 .simm => .{ .imm = .s(op.adjustedImm(i32, s)) },
                 .uimm => .{ .imm = .u(@bitCast(op.adjustedImm(i64, s))) },
@@ -189392,11 +190194,8 @@ fn select(
                     },
                 }
             }
-            for (case.dst_temps[0..dst_temps.len], dst_temps, dst_tys) |tmp_kind, dst_temp, dst_ty| {
-                tmp_kind.finish(dst_temp, cg);
-                cg.temp_type[@intFromEnum(dst_temp.unwrap(cg).temp)] = dst_ty;
-            }
             for (tmp_owned, s_tmp_temps) |owned, temp| if (owned) try temp.die(cg);
+            for (dst_tys, case.dst_temps[0..dst_temps.len], dst_temps) |dst_ty, dst_kind, *dst_temp| try Select.TempSpec.finish(.{ .type = dst_ty, .kind = dst_kind }, dst_temp, cg);
             return;
         }
     }
src/arch/x86_64/encoder.zig
@@ -111,7 +111,7 @@ pub const Instruction = struct {
         };
 
         pub fn initMoffs(reg: Register, offset: u64) Memory {
-            assert(reg.class() == .segment);
+            assert(reg.isClass(.segment));
             return .{ .moffs = .{ .seg = reg, .offset = offset } };
         }
 
@@ -139,7 +139,7 @@ pub const Instruction = struct {
                 .rip => false,
                 .sib => |s| switch (s.base) {
                     .none, .frame, .table, .reloc, .rip_inst => false,
-                    .reg => |reg| reg.class() == .segment,
+                    .reg => |reg| reg.isClass(.segment),
                 },
             };
         }
@@ -199,7 +199,7 @@ pub const Instruction = struct {
         pub fn isSegmentRegister(op: Operand) bool {
             return switch (op) {
                 .none => unreachable,
-                .reg => |reg| reg.class() == .segment,
+                .reg => |reg| reg.isClass(.segment),
                 .mem => |mem| mem.isSegmentRegister(),
                 .imm => unreachable,
                 .bytes => unreachable,
@@ -776,7 +776,7 @@ pub const LegacyPrefixes = packed struct {
     padding: u5 = 0,
 
     pub fn setSegmentOverride(self: *LegacyPrefixes, reg: Register) void {
-        assert(reg.class() == .segment);
+        assert(reg.isClass(.segment));
         switch (reg) {
             .cs => self.prefix_2e = true,
             .ss => self.prefix_36 = true,
@@ -2457,7 +2457,7 @@ const Assembler = struct {
                 .general_purpose, .segment => {
                     const tok = try as.expect(.string);
                     const base = registerFromString(as.source(tok)) orelse return error.InvalidMemoryOperand;
-                    if (base.class() != cond) return error.InvalidMemoryOperand;
+                    if (!base.isClass(cond)) return error.InvalidMemoryOperand;
                     res.base = base;
                 },
                 .rip => {
@@ -2498,7 +2498,7 @@ const Assembler = struct {
                         error.Overflow => {
                             if (is_neg) return err;
                             if (res.base) |base| {
-                                if (base.class() != .segment) return err;
+                                if (!base.isClass(.segment)) return err;
                             }
                             const offset = try std.fmt.parseInt(u64, as.source(tok), 0);
                             res.offset = offset;
test/behavior/x86_64/binary.zig
@@ -5181,6 +5181,8 @@ inline fn divFloor(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@divFloor(
 }
 test divFloor {
     const test_div_floor = binary(divFloor, .{ .compare = .approx_int });
+    try test_div_floor.testInts();
+    try test_div_floor.testIntVectors();
     try test_div_floor.testFloats();
     try test_div_floor.testFloatVectors();
 }
@@ -5198,7 +5200,7 @@ test rem {
 
 inline fn mod(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@mod(lhs, rhs)) {
     // workaround llvm backend bugs
-    if (@inComptime()) {
+    if (@inComptime() and @typeInfo(Scalar(Type)) == .float) {
         const scalarMod = struct {
             fn scalarMod(scalar_lhs: Scalar(Type), scalar_rhs: Scalar(Type)) Scalar(Type) {
                 const scalar_rem = @rem(scalar_lhs, scalar_rhs);
@@ -5218,6 +5220,8 @@ inline fn mod(comptime Type: type, lhs: Type, rhs: Type) @TypeOf(@mod(lhs, rhs))
 }
 test mod {
     const test_mod = binary(mod, .{});
+    try test_mod.testInts();
+    try test_mod.testIntVectors();
     try test_mod.testFloats();
     try test_mod.testFloatVectors();
 }
test/behavior/math.zig
@@ -1893,13 +1893,13 @@ test "float divide by zero" {
 
 test "partially-runtime integer vector division would be illegal if vector elements were reordered" {
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
+    if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
 
     var lhs: @Vector(2, i8) = .{ -128, 5 };
     const rhs: @Vector(2, i8) = .{ 1, -1 };
test/behavior/vector.zig
@@ -559,12 +559,12 @@ test "vector comparison operators" {
 
 test "vector division operators" {
     if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
-    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
     if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
+    if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest;
 
     const S = struct {
         fn doTheTestDiv(comptime T: type, x: @Vector(4, T), y: @Vector(4, T)) !void {