Commit 292f91aef2

Jakub Konka <kubkon@jakubkonka.com>
2023-03-07 16:59:38
Handle .ah vs .spl register aliases
1 parent bc43cee
Changed files (3)
src/arch/x86_64/encoder.zig
@@ -102,12 +102,12 @@ pub const Instruction = struct {
         op3: Operand = .none,
         op4: Operand = .none,
     }) !Instruction {
-        const encoding = Encoding.findByMnemonic(mnemonic, .{
+        const encoding = (try Encoding.findByMnemonic(mnemonic, .{
             .op1 = args.op1,
             .op2 = args.op2,
             .op3 = args.op3,
             .op4 = args.op4,
-        }) orelse {
+        })) orelse {
             std.log.debug("{s} {s} {s} {s} {s}", .{
                 @tagName(mnemonic),
                 @tagName(Encoding.Op.fromOperand(args.op1)),
@@ -251,13 +251,8 @@ pub const Instruction = struct {
     fn encodeRexPrefix(inst: Instruction, encoder: anytype) !void {
         const op_en = inst.encoding.op_en;
 
-        // Check if we need REX and can actually encode it
-        const is_rex_invalid = for (&[_]Operand{ inst.op1, inst.op2, inst.op3, inst.op4 }) |op| switch (op) {
-            .reg => |r| if (r.isRexInvalid()) break true,
-            else => {},
-        } else false;
-
         var rex = Rex{};
+        rex.present = inst.encoding.mode == .rex;
         rex.w = inst.encoding.mode == .long;
 
         switch (op_en) {
@@ -293,8 +288,6 @@ pub const Instruction = struct {
             },
         }
 
-        if (rex.isSet() and is_rex_invalid) return error.CannotEncode;
-
         try encoder.rex(rex);
     }
 
@@ -507,9 +500,9 @@ fn Encoder(comptime T: type) type {
         /// or one of reg, index, r/m, base, or opcode-reg might be extended.
         ///
         /// See struct `Rex` for a description of each field.
-        ///
-        /// Does not add a prefix byte if none of the fields are set!
         pub fn rex(self: Self, byte: Rex) !void {
+            if (!byte.present and !byte.isSet()) return;
+
             var value: u8 = 0b0100_0000;
 
             if (byte.w) value |= 0b1000;
@@ -517,9 +510,7 @@ fn Encoder(comptime T: type) type {
             if (byte.x) value |= 0b0010;
             if (byte.b) value |= 0b0001;
 
-            if (value != 0b0100_0000) {
-                try self.writer.writeByte(value);
-            }
+            try self.writer.writeByte(value);
         }
 
         // ------
@@ -788,6 +779,7 @@ pub const Rex = struct {
     r: bool = false,
     x: bool = false,
     b: bool = false,
+    present: bool = false,
 
     pub fn isSet(rex: Rex) bool {
         return rex.w or rex.r or rex.x or rex.b;
src/arch/x86_64/Encoding.zig
@@ -29,12 +29,42 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: struct {
     op2: Instruction.Operand,
     op3: Instruction.Operand,
     op4: Instruction.Operand,
-}) ?Encoding {
+}) !?Encoding {
     const input_op1 = Op.fromOperand(args.op1);
     const input_op2 = Op.fromOperand(args.op2);
     const input_op3 = Op.fromOperand(args.op3);
     const input_op4 = Op.fromOperand(args.op4);
 
+    const ops = &[_]Instruction.Operand{ args.op1, args.op2, args.op3, args.op4 };
+    const rex_required = for (ops) |op| switch (op) {
+        .reg => |r| switch (r) {
+            .spl, .bpl, .sil, .dil => break true,
+            else => {},
+        },
+        else => {},
+    } else false;
+    const rex_invalid = for (ops) |op| switch (op) {
+        .reg => |r| switch (r) {
+            .ah, .bh, .ch, .dh => break true,
+            else => {},
+        },
+        else => {},
+    } else false;
+    const rex_extended = for (ops) |op| switch (op) {
+        .reg => |r| if (r.isExtended()) break true,
+        .mem => |m| {
+            if (m.base()) |base| {
+                if (base.isExtended()) break true;
+            }
+            if (m.scaleIndex()) |si| {
+                if (si.index.isExtended()) break true;
+            }
+        },
+        else => {},
+    } else false;
+
+    if ((rex_required or rex_extended) and rex_invalid) return error.CannotEncode;
+
     // TODO work out what is the maximum number of variants we can actually find in one swoop.
     var candidates: [10]Encoding = undefined;
     var count: usize = 0;
@@ -57,13 +87,24 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: struct {
             input_op3.isSubset(enc.op3, enc.mode) and
             input_op4.isSubset(enc.op4, enc.mode))
         {
-            candidates[count] = enc;
-            count += 1;
+            if (rex_required) {
+                switch (enc.mode) {
+                    .rex, .long => {
+                        candidates[count] = enc;
+                        count += 1;
+                    },
+                    else => {},
+                }
+            } else {
+                if (enc.mode != .rex) {
+                    candidates[count] = enc;
+                    count += 1;
+                }
+            }
         }
     }
 
     if (count == 0) return null;
-    if (count == 1) return candidates[0];
 
     const EncodingLength = struct {
         fn estimate(encoding: Encoding, params: struct {
@@ -71,7 +112,7 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: struct {
             op2: Instruction.Operand,
             op3: Instruction.Operand,
             op4: Instruction.Operand,
-        }) usize {
+        }) !usize {
             var inst = Instruction{
                 .op1 = params.op1,
                 .op2 = params.op2,
@@ -91,7 +132,13 @@ pub fn findByMnemonic(mnemonic: Mnemonic, args: struct {
     } = null;
     var i: usize = 0;
     while (i < count) : (i += 1) {
-        const len = EncodingLength.estimate(candidates[i], .{
+        const candidate = candidates[i];
+        switch (candidate.mode) {
+            .long, .rex => if (rex_invalid) return error.CannotEncode,
+            else => {},
+        }
+
+        const len = try EncodingLength.estimate(candidate, .{
             .op1 = args.op1,
             .op2 = args.op2,
             .op3 = args.op3,
@@ -136,20 +183,11 @@ pub fn findByOpcode(opc: []const u8, prefixes: struct {
         if (match) {
             if (prefixes.rex.w) {
                 switch (enc.mode) {
-                    .fpu, .sse, .sse2 => {},
-                    .long => return enc,
-                    .none => {
-                        // TODO this is a hack to allow parsing of instructions which contain
-                        // spurious prefix bytes such as
-                        // rex.W mov dil, 0x1
-                        // Here, rex.W is not needed.
-                        const rex_w_allowed = blk: {
-                            const bit_size = enc.operandBitSize();
-                            break :blk bit_size == 64 or bit_size == 8;
-                        };
-                        if (rex_w_allowed) return enc;
-                    },
+                    .fpu, .sse, .sse2, .none => {},
+                    .long, .rex => return enc,
                 }
+            } else if (prefixes.rex.present and !prefixes.rex.isSet()) {
+                if (enc.mode == .rex) return enc;
             } else if (prefixes.legacy.prefix_66) {
                 switch (enc.operandBitSize()) {
                     16 => return enc,
@@ -542,6 +580,7 @@ pub const Op = enum {
 pub const Mode = enum {
     none,
     fpu,
+    rex,
     long,
     sse,
     sse2,
src/arch/x86_64/encodings.zig
@@ -18,6 +18,7 @@ pub const table = &[_]Entry{
     .{ .adc, .zi, .eax,  .imm32,  .none, .none, 1, 0x15, 0x00, 0x00, 0, .none  },
     .{ .adc, .zi, .rax,  .imm32s, .none, .none, 1, 0x15, 0x00, 0x00, 0, .long  },
     .{ .adc, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 2, .none  },
+    .{ .adc, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 2, .rex   },
     .{ .adc, .mi, .rm16, .imm16,  .none, .none, 1, 0x81, 0x00, 0x00, 2, .none  },
     .{ .adc, .mi, .rm32, .imm32,  .none, .none, 1, 0x81, 0x00, 0x00, 2, .none  },
     .{ .adc, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 2, .long  },
@@ -25,10 +26,12 @@ pub const table = &[_]Entry{
     .{ .adc, .mi, .rm32, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 2, .none  },
     .{ .adc, .mi, .rm64, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 2, .long  },
     .{ .adc, .mr, .rm8,  .r8,     .none, .none, 1, 0x10, 0x00, 0x00, 0, .none  },
+    .{ .adc, .mr, .rm8,  .r8,     .none, .none, 1, 0x10, 0x00, 0x00, 0, .rex   },
     .{ .adc, .mr, .rm16, .r16,    .none, .none, 1, 0x11, 0x00, 0x00, 0, .none  },
     .{ .adc, .mr, .rm32, .r32,    .none, .none, 1, 0x11, 0x00, 0x00, 0, .none  },
     .{ .adc, .mr, .rm64, .r64,    .none, .none, 1, 0x11, 0x00, 0x00, 0, .long  },
     .{ .adc, .rm, .r8,   .rm8,    .none, .none, 1, 0x12, 0x00, 0x00, 0, .none  },
+    .{ .adc, .rm, .r8,   .rm8,    .none, .none, 1, 0x12, 0x00, 0x00, 0, .rex   },
     .{ .adc, .rm, .r16,  .rm16,   .none, .none, 1, 0x13, 0x00, 0x00, 0, .none  },
     .{ .adc, .rm, .r32,  .rm32,   .none, .none, 1, 0x13, 0x00, 0x00, 0, .none  },
     .{ .adc, .rm, .r64,  .rm64,   .none, .none, 1, 0x13, 0x00, 0x00, 0, .long  },
@@ -38,6 +41,7 @@ pub const table = &[_]Entry{
     .{ .add, .zi, .eax,  .imm32,  .none, .none, 1, 0x05, 0x00, 0x00, 0, .none  },
     .{ .add, .zi, .rax,  .imm32s, .none, .none, 1, 0x05, 0x00, 0x00, 0, .long  },
     .{ .add, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 0, .none  },
+    .{ .add, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 0, .rex   },
     .{ .add, .mi, .rm16, .imm16,  .none, .none, 1, 0x81, 0x00, 0x00, 0, .none  },
     .{ .add, .mi, .rm32, .imm32,  .none, .none, 1, 0x81, 0x00, 0x00, 0, .none  },
     .{ .add, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 0, .long  },
@@ -45,10 +49,12 @@ pub const table = &[_]Entry{
     .{ .add, .mi, .rm32, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 0, .none  },
     .{ .add, .mi, .rm64, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 0, .long  },
     .{ .add, .mr, .rm8,  .r8,     .none, .none, 1, 0x00, 0x00, 0x00, 0, .none  },
+    .{ .add, .mr, .rm8,  .r8,     .none, .none, 1, 0x00, 0x00, 0x00, 0, .rex   },
     .{ .add, .mr, .rm16, .r16,    .none, .none, 1, 0x01, 0x00, 0x00, 0, .none  },
     .{ .add, .mr, .rm32, .r32,    .none, .none, 1, 0x01, 0x00, 0x00, 0, .none  },
     .{ .add, .mr, .rm64, .r64,    .none, .none, 1, 0x01, 0x00, 0x00, 0, .long  },
     .{ .add, .rm, .r8,   .rm8,    .none, .none, 1, 0x02, 0x00, 0x00, 0, .none  },
+    .{ .add, .rm, .r8,   .rm8,    .none, .none, 1, 0x02, 0x00, 0x00, 0, .rex   },
     .{ .add, .rm, .r16,  .rm16,   .none, .none, 1, 0x03, 0x00, 0x00, 0, .none  },
     .{ .add, .rm, .r32,  .rm32,   .none, .none, 1, 0x03, 0x00, 0x00, 0, .none  },
     .{ .add, .rm, .r64,  .rm64,   .none, .none, 1, 0x03, 0x00, 0x00, 0, .long  },
@@ -58,6 +64,7 @@ pub const table = &[_]Entry{
     .{ .@"and", .zi, .eax,  .imm32,  .none, .none, 1, 0x25, 0x00, 0x00, 0, .none  },
     .{ .@"and", .zi, .rax,  .imm32s, .none, .none, 1, 0x25, 0x00, 0x00, 0, .long  },
     .{ .@"and", .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 4, .none  },
+    .{ .@"and", .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 4, .rex   },
     .{ .@"and", .mi, .rm16, .imm16,  .none, .none, 1, 0x81, 0x00, 0x00, 4, .none  },
     .{ .@"and", .mi, .rm32, .imm32,  .none, .none, 1, 0x81, 0x00, 0x00, 4, .none  },
     .{ .@"and", .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 4, .long  },
@@ -65,10 +72,12 @@ pub const table = &[_]Entry{
     .{ .@"and", .mi, .rm32, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 4, .none  },
     .{ .@"and", .mi, .rm64, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 4, .long  },
     .{ .@"and", .mr, .rm8,  .r8,     .none, .none, 1, 0x20, 0x00, 0x00, 0, .none  },
+    .{ .@"and", .mr, .rm8,  .r8,     .none, .none, 1, 0x20, 0x00, 0x00, 0, .rex   },
     .{ .@"and", .mr, .rm16, .r16,    .none, .none, 1, 0x21, 0x00, 0x00, 0, .none  },
     .{ .@"and", .mr, .rm32, .r32,    .none, .none, 1, 0x21, 0x00, 0x00, 0, .none  },
     .{ .@"and", .mr, .rm64, .r64,    .none, .none, 1, 0x21, 0x00, 0x00, 0, .long  },
     .{ .@"and", .rm, .r8,   .rm8,    .none, .none, 1, 0x22, 0x00, 0x00, 0, .none  },
+    .{ .@"and", .rm, .r8,   .rm8,    .none, .none, 1, 0x22, 0x00, 0x00, 0, .rex   },
     .{ .@"and", .rm, .r16,  .rm16,   .none, .none, 1, 0x23, 0x00, 0x00, 0, .none  },
     .{ .@"and", .rm, .r32,  .rm32,   .none, .none, 1, 0x23, 0x00, 0x00, 0, .none  },
     .{ .@"and", .rm, .r64,  .rm64,   .none, .none, 1, 0x23, 0x00, 0x00, 0, .long  },
@@ -181,6 +190,7 @@ pub const table = &[_]Entry{
     .{ .cmp, .zi, .eax,  .imm32,  .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none  },
     .{ .cmp, .zi, .rax,  .imm32s, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .long  },
     .{ .cmp, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 7, .none  },
+    .{ .cmp, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 7, .rex   },
     .{ .cmp, .mi, .rm16, .imm16,  .none, .none, 1, 0x81, 0x00, 0x00, 7, .none  },
     .{ .cmp, .mi, .rm32, .imm32,  .none, .none, 1, 0x81, 0x00, 0x00, 7, .none  },
     .{ .cmp, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 7, .long  },
@@ -188,15 +198,18 @@ pub const table = &[_]Entry{
     .{ .cmp, .mi, .rm32, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 7, .none  },
     .{ .cmp, .mi, .rm64, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 7, .long  },
     .{ .cmp, .mr, .rm8,  .r8,     .none, .none, 1, 0x38, 0x00, 0x00, 0, .none  },
+    .{ .cmp, .mr, .rm8,  .r8,     .none, .none, 1, 0x38, 0x00, 0x00, 0, .rex   },
     .{ .cmp, .mr, .rm16, .r16,    .none, .none, 1, 0x39, 0x00, 0x00, 0, .none  },
     .{ .cmp, .mr, .rm32, .r32,    .none, .none, 1, 0x39, 0x00, 0x00, 0, .none  },
     .{ .cmp, .mr, .rm64, .r64,    .none, .none, 1, 0x39, 0x00, 0x00, 0, .long  },
     .{ .cmp, .rm, .r8,   .rm8,    .none, .none, 1, 0x3a, 0x00, 0x00, 0, .none  },
+    .{ .cmp, .rm, .r8,   .rm8,    .none, .none, 1, 0x3a, 0x00, 0x00, 0, .rex   },
     .{ .cmp, .rm, .r16,  .rm16,   .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none  },
     .{ .cmp, .rm, .r32,  .rm32,   .none, .none, 1, 0x3b, 0x00, 0x00, 0, .none  },
     .{ .cmp, .rm, .r64,  .rm64,   .none, .none, 1, 0x3b, 0x00, 0x00, 0, .long  },
 
     .{ .div, .m, .rm8,  .none, .none, .none, 1, 0xf6, 0x00, 0x00, 6, .none  },
+    .{ .div, .m, .rm8,  .none, .none, .none, 1, 0xf6, 0x00, 0x00, 6, .rex   },
     .{ .div, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 6, .none  },
     .{ .div, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 6, .none  },
     .{ .div, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 6, .long  },
@@ -210,11 +223,13 @@ pub const table = &[_]Entry{
     .{ .fld, .m, .m80, .none, .none, .none, 1, 0xdb, 0x00, 0x00, 5, .fpu },
 
     .{ .idiv, .m, .rm8,  .none, .none, .none, 1, 0xf6, 0x00, 0x00, 7, .none  },
+    .{ .idiv, .m, .rm8,  .none, .none, .none, 1, 0xf6, 0x00, 0x00, 7, .rex   },
     .{ .idiv, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .none  },
     .{ .idiv, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .none  },
     .{ .idiv, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 7, .long  },
 
     .{ .imul, .m,   .rm8,  .none, .none,   .none, 1, 0xf6, 0x00, 0x00, 5, .none  },
+    .{ .imul, .m,   .rm8,  .none, .none,   .none, 1, 0xf6, 0x00, 0x00, 5, .rex   },
     .{ .imul, .m,   .rm16, .none, .none,   .none, 1, 0xf7, 0x00, 0x00, 5, .none  },
     .{ .imul, .m,   .rm32, .none, .none,   .none, 1, 0xf7, 0x00, 0x00, 5, .none  },
     .{ .imul, .m,   .rm64, .none, .none,   .none, 1, 0xf7, 0x00, 0x00, 5, .long  },
@@ -270,10 +285,12 @@ pub const table = &[_]Entry{
     .{ .lea, .rm, .r64, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .long  },
 
     .{ .mov, .mr, .rm8,   .r8,     .none, .none, 1, 0x88, 0x00, 0x00, 0, .none  },
+    .{ .mov, .mr, .rm8,   .r8,     .none, .none, 1, 0x88, 0x00, 0x00, 0, .rex   },
     .{ .mov, .mr, .rm16,  .r16,    .none, .none, 1, 0x89, 0x00, 0x00, 0, .none  },
     .{ .mov, .mr, .rm32,  .r32,    .none, .none, 1, 0x89, 0x00, 0x00, 0, .none  },
     .{ .mov, .mr, .rm64,  .r64,    .none, .none, 1, 0x89, 0x00, 0x00, 0, .long  },
     .{ .mov, .rm, .r8,    .rm8,    .none, .none, 1, 0x8a, 0x00, 0x00, 0, .none  },
+    .{ .mov, .rm, .r8,    .rm8,    .none, .none, 1, 0x8a, 0x00, 0x00, 0, .rex   },
     .{ .mov, .rm, .r16,   .rm16,   .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none  },
     .{ .mov, .rm, .r32,   .rm32,   .none, .none, 1, 0x8b, 0x00, 0x00, 0, .none  },
     .{ .mov, .rm, .r64,   .rm64,   .none, .none, 1, 0x8b, 0x00, 0x00, 0, .long  },
@@ -290,16 +307,20 @@ pub const table = &[_]Entry{
     .{ .mov, .td, .moffs, .eax,    .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none  },
     .{ .mov, .td, .moffs, .rax,    .none, .none, 1, 0xa3, 0x00, 0x00, 0, .long  },
     .{ .mov, .oi, .r8,    .imm8,   .none, .none, 1, 0xb0, 0x00, 0x00, 0, .none  },
+    .{ .mov, .oi, .r8,    .imm8,   .none, .none, 1, 0xb0, 0x00, 0x00, 0, .rex   },
     .{ .mov, .oi, .r16,   .imm16,  .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none  },
     .{ .mov, .oi, .r32,   .imm32,  .none, .none, 1, 0xb8, 0x00, 0x00, 0, .none  },
     .{ .mov, .oi, .r64,   .imm64,  .none, .none, 1, 0xb8, 0x00, 0x00, 0, .long  },
     .{ .mov, .mi, .rm8,   .imm8,   .none, .none, 1, 0xc6, 0x00, 0x00, 0, .none  },
+    .{ .mov, .mi, .rm8,   .imm8,   .none, .none, 1, 0xc6, 0x00, 0x00, 0, .rex   },
     .{ .mov, .mi, .rm16,  .imm16,  .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none  },
     .{ .mov, .mi, .rm32,  .imm32,  .none, .none, 1, 0xc7, 0x00, 0x00, 0, .none  },
     .{ .mov, .mi, .rm64,  .imm32s, .none, .none, 1, 0xc7, 0x00, 0x00, 0, .long  },
 
     .{ .movsx, .rm, .r16, .rm8,  .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none  },
+    .{ .movsx, .rm, .r16, .rm8,  .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .rex   },
     .{ .movsx, .rm, .r32, .rm8,  .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .none  },
+    .{ .movsx, .rm, .r32, .rm8,  .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .rex   },
     .{ .movsx, .rm, .r64, .rm8,  .none, .none, 2, 0x0f, 0xbe, 0x00, 0, .long  },
     .{ .movsx, .rm, .r32, .rm16, .none, .none, 2, 0x0f, 0xbf, 0x00, 0, .none  },
     .{ .movsx, .rm, .r64, .rm16, .none, .none, 2, 0x0f, 0xbf, 0x00, 0, .long  },
@@ -315,6 +336,7 @@ pub const table = &[_]Entry{
     .{ .movzx, .rm, .r64, .rm16, .none, .none, 2, 0x0f, 0xb7, 0x00, 0, .long  },
 
     .{ .mul, .m, .rm8,  .none, .none, .none, 1, 0xf6, 0x00, 0x00, 4, .none  },
+    .{ .mul, .m, .rm8,  .none, .none, .none, 1, 0xf6, 0x00, 0x00, 4, .rex   },
     .{ .mul, .m, .rm16, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 4, .none  },
     .{ .mul, .m, .rm32, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 4, .none  },
     .{ .mul, .m, .rm64, .none, .none, .none, 1, 0xf7, 0x00, 0x00, 4, .long  },
@@ -326,6 +348,7 @@ pub const table = &[_]Entry{
     .{ .@"or", .zi, .eax,  .imm32,  .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none  },
     .{ .@"or", .zi, .rax,  .imm32s, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .long  },
     .{ .@"or", .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 1, .none  },
+    .{ .@"or", .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 1, .rex   },
     .{ .@"or", .mi, .rm16, .imm16,  .none, .none, 1, 0x81, 0x00, 0x00, 1, .none  },
     .{ .@"or", .mi, .rm32, .imm32,  .none, .none, 1, 0x81, 0x00, 0x00, 1, .none  },
     .{ .@"or", .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 1, .long  },
@@ -333,10 +356,12 @@ pub const table = &[_]Entry{
     .{ .@"or", .mi, .rm32, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 1, .none  },
     .{ .@"or", .mi, .rm64, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 1, .long  },
     .{ .@"or", .mr, .rm8,  .r8,     .none, .none, 1, 0x08, 0x00, 0x00, 0, .none  },
+    .{ .@"or", .mr, .rm8,  .r8,     .none, .none, 1, 0x08, 0x00, 0x00, 0, .rex   },
     .{ .@"or", .mr, .rm16, .r16,    .none, .none, 1, 0x09, 0x00, 0x00, 0, .none  },
     .{ .@"or", .mr, .rm32, .r32,    .none, .none, 1, 0x09, 0x00, 0x00, 0, .none  },
     .{ .@"or", .mr, .rm64, .r64,    .none, .none, 1, 0x09, 0x00, 0x00, 0, .long  },
     .{ .@"or", .rm, .r8,   .rm8,    .none, .none, 1, 0x0a, 0x00, 0x00, 0, .none  },
+    .{ .@"or", .rm, .r8,   .rm8,    .none, .none, 1, 0x0a, 0x00, 0x00, 0, .rex   },
     .{ .@"or", .rm, .r16,  .rm16,   .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none  },
     .{ .@"or", .rm, .r32,  .rm32,   .none, .none, 1, 0x0b, 0x00, 0x00, 0, .none  },
     .{ .@"or", .rm, .r64,  .rm64,   .none, .none, 1, 0x0b, 0x00, 0x00, 0, .long  },
@@ -357,27 +382,33 @@ pub const table = &[_]Entry{
     .{ .ret, .np, .none, .none, .none, .none, 1, 0xc3, 0x00, 0x00, 0, .none },
 
     .{ .sal, .m1, .rm8,  .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 4, .none  },
+    .{ .sal, .m1, .rm8,  .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 4, .rex   },
     .{ .sal, .m1, .rm16, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .none  },
     .{ .sal, .m1, .rm32, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .none  },
     .{ .sal, .m1, .rm64, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .long  },
     .{ .sal, .mc, .rm8,  .cl,    .none, .none, 1, 0xd2, 0x00, 0x00, 4, .none  },
+    .{ .sal, .mc, .rm8,  .cl,    .none, .none, 1, 0xd2, 0x00, 0x00, 4, .rex   },
     .{ .sal, .mc, .rm16, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 4, .none  },
     .{ .sal, .mc, .rm32, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 4, .none  },
     .{ .sal, .mc, .rm64, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 4, .long  },
     .{ .sal, .mi, .rm8,  .imm8,  .none, .none, 1, 0xc0, 0x00, 0x00, 4, .none  },
+    .{ .sal, .mi, .rm8,  .imm8,  .none, .none, 1, 0xc0, 0x00, 0x00, 4, .rex   },
     .{ .sal, .mi, .rm16, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 4, .none  },
     .{ .sal, .mi, .rm32, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 4, .none  },
     .{ .sal, .mi, .rm64, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 4, .long  },
 
     .{ .sar, .m1, .rm8,  .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 7, .none  },
+    .{ .sar, .m1, .rm8,  .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 7, .rex   },
     .{ .sar, .m1, .rm16, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 7, .none  },
     .{ .sar, .m1, .rm32, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 7, .none  },
     .{ .sar, .m1, .rm64, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 7, .long  },
     .{ .sar, .mc, .rm8,  .cl,    .none, .none, 1, 0xd2, 0x00, 0x00, 7, .none  },
+    .{ .sar, .mc, .rm8,  .cl,    .none, .none, 1, 0xd2, 0x00, 0x00, 7, .rex   },
     .{ .sar, .mc, .rm16, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 7, .none  },
     .{ .sar, .mc, .rm32, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 7, .none  },
     .{ .sar, .mc, .rm64, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 7, .long  },
     .{ .sar, .mi, .rm8,  .imm8,  .none, .none, 1, 0xc0, 0x00, 0x00, 7, .none  },
+    .{ .sar, .mi, .rm8,  .imm8,  .none, .none, 1, 0xc0, 0x00, 0x00, 7, .rex   },
     .{ .sar, .mi, .rm16, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 7, .none  },
     .{ .sar, .mi, .rm32, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 7, .none  },
     .{ .sar, .mi, .rm64, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 7, .long  },
@@ -387,6 +418,7 @@ pub const table = &[_]Entry{
     .{ .sbb, .zi, .eax,  .imm32,  .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none  },
     .{ .sbb, .zi, .rax,  .imm32s, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .long  },
     .{ .sbb, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 3, .none  },
+    .{ .sbb, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 3, .rex   },
     .{ .sbb, .mi, .rm16, .imm16,  .none, .none, 1, 0x81, 0x00, 0x00, 3, .none  },
     .{ .sbb, .mi, .rm32, .imm32,  .none, .none, 1, 0x81, 0x00, 0x00, 3, .none  },
     .{ .sbb, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 3, .long  },
@@ -394,67 +426,105 @@ pub const table = &[_]Entry{
     .{ .sbb, .mi, .rm32, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 3, .none  },
     .{ .sbb, .mi, .rm64, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 3, .long  },
     .{ .sbb, .mr, .rm8,  .r8,     .none, .none, 1, 0x18, 0x00, 0x00, 0, .none  },
+    .{ .sbb, .mr, .rm8,  .r8,     .none, .none, 1, 0x18, 0x00, 0x00, 0, .rex   },
     .{ .sbb, .mr, .rm16, .r16,    .none, .none, 1, 0x19, 0x00, 0x00, 0, .none  },
     .{ .sbb, .mr, .rm32, .r32,    .none, .none, 1, 0x19, 0x00, 0x00, 0, .none  },
     .{ .sbb, .mr, .rm64, .r64,    .none, .none, 1, 0x19, 0x00, 0x00, 0, .long  },
     .{ .sbb, .rm, .r8,   .rm8,    .none, .none, 1, 0x1a, 0x00, 0x00, 0, .none  },
+    .{ .sbb, .rm, .r8,   .rm8,    .none, .none, 1, 0x1a, 0x00, 0x00, 0, .rex   },
     .{ .sbb, .rm, .r16,  .rm16,   .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none  },
     .{ .sbb, .rm, .r32,  .rm32,   .none, .none, 1, 0x1b, 0x00, 0x00, 0, .none  },
     .{ .sbb, .rm, .r64,  .rm64,   .none, .none, 1, 0x1b, 0x00, 0x00, 0, .long  },
 
     .{ .seta,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .none },
+    .{ .seta,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .rex  },
     .{ .setae,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .none },
+    .{ .setae,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .rex  },
     .{ .setb,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .none },
+    .{ .setb,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .rex  },
     .{ .setbe,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x96, 0x00, 0, .none },
+    .{ .setbe,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x96, 0x00, 0, .rex  },
     .{ .setc,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .none },
+    .{ .setc,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .rex  },
     .{ .sete,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x94, 0x00, 0, .none },
+    .{ .sete,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x94, 0x00, 0, .rex  },
     .{ .setg,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9f, 0x00, 0, .none },
+    .{ .setg,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9f, 0x00, 0, .rex  },
     .{ .setge,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9d, 0x00, 0, .none },
+    .{ .setge,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9d, 0x00, 0, .rex  },
     .{ .setl,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9c, 0x00, 0, .none },
+    .{ .setl,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9c, 0x00, 0, .rex  },
     .{ .setle,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9e, 0x00, 0, .none },
+    .{ .setle,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9e, 0x00, 0, .rex  },
     .{ .setna,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x96, 0x00, 0, .none },
+    .{ .setna,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x96, 0x00, 0, .rex  },
     .{ .setnae, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .none },
+    .{ .setnae, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x92, 0x00, 0, .rex  },
     .{ .setnb,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .none },
+    .{ .setnb,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .rex  },
     .{ .setnbe, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .none },
+    .{ .setnbe, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x97, 0x00, 0, .rex  },
     .{ .setnc,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .none },
+    .{ .setnc,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x93, 0x00, 0, .rex  },
     .{ .setne,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x95, 0x00, 0, .none },
+    .{ .setne,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x95, 0x00, 0, .rex  },
     .{ .setng,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9e, 0x00, 0, .none },
+    .{ .setng,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9e, 0x00, 0, .rex  },
     .{ .setnge, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9c, 0x00, 0, .none },
+    .{ .setnge, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9c, 0x00, 0, .rex  },
     .{ .setnl,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9d, 0x00, 0, .none },
+    .{ .setnl,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9d, 0x00, 0, .rex  },
     .{ .setnle, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9f, 0x00, 0, .none },
+    .{ .setnle, .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9f, 0x00, 0, .rex  },
     .{ .setno,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x91, 0x00, 0, .none },
+    .{ .setno,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x91, 0x00, 0, .rex  },
     .{ .setnp,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9b, 0x00, 0, .none },
+    .{ .setnp,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9b, 0x00, 0, .rex  },
     .{ .setns,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x99, 0x00, 0, .none },
+    .{ .setns,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x99, 0x00, 0, .rex  },
     .{ .setnz,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x95, 0x00, 0, .none },
+    .{ .setnz,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x95, 0x00, 0, .rex  },
     .{ .seto,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x90, 0x00, 0, .none },
+    .{ .seto,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x90, 0x00, 0, .rex  },
     .{ .setp,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9a, 0x00, 0, .none },
+    .{ .setp,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9a, 0x00, 0, .rex  },
     .{ .setpe,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9a, 0x00, 0, .none },
+    .{ .setpe,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9a, 0x00, 0, .rex  },
     .{ .setpo,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9b, 0x00, 0, .none },
+    .{ .setpo,  .m, .rm8, .none, .none, .none, 2, 0x0f, 0x9b, 0x00, 0, .rex  },
     .{ .sets,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x98, 0x00, 0, .none },
+    .{ .sets,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x98, 0x00, 0, .rex  },
     .{ .setz,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x94, 0x00, 0, .none },
+    .{ .setz,   .m, .rm8, .none, .none, .none, 2, 0x0f, 0x94, 0x00, 0, .rex  },
 
     .{ .shl, .m1, .rm8,  .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 4, .none  },
+    .{ .shl, .m1, .rm8,  .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 4, .rex   },
     .{ .shl, .m1, .rm16, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .none  },
     .{ .shl, .m1, .rm32, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .none  },
     .{ .shl, .m1, .rm64, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 4, .long  },
     .{ .shl, .mc, .rm8,  .cl,    .none, .none, 1, 0xd2, 0x00, 0x00, 4, .none  },
+    .{ .shl, .mc, .rm8,  .cl,    .none, .none, 1, 0xd2, 0x00, 0x00, 4, .rex   },
     .{ .shl, .mc, .rm16, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 4, .none  },
     .{ .shl, .mc, .rm32, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 4, .none  },
     .{ .shl, .mc, .rm64, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 4, .long  },
     .{ .shl, .mi, .rm8,  .imm8,  .none, .none, 1, 0xc0, 0x00, 0x00, 4, .none  },
+    .{ .shl, .mi, .rm8,  .imm8,  .none, .none, 1, 0xc0, 0x00, 0x00, 4, .rex   },
     .{ .shl, .mi, .rm16, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 4, .none  },
     .{ .shl, .mi, .rm32, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 4, .none  },
     .{ .shl, .mi, .rm64, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 4, .long  },
 
     .{ .shr, .m1, .rm8,  .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 5, .none  },
+    .{ .shr, .m1, .rm8,  .unity, .none, .none, 1, 0xd0, 0x00, 0x00, 5, .rex   },
     .{ .shr, .m1, .rm16, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 5, .none  },
     .{ .shr, .m1, .rm32, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 5, .none  },
     .{ .shr, .m1, .rm64, .unity, .none, .none, 1, 0xd1, 0x00, 0x00, 5, .long  },
     .{ .shr, .mc, .rm8,  .cl,    .none, .none, 1, 0xd2, 0x00, 0x00, 5, .none  },
+    .{ .shr, .mc, .rm8,  .cl,    .none, .none, 1, 0xd2, 0x00, 0x00, 5, .rex   },
     .{ .shr, .mc, .rm16, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 5, .none  },
     .{ .shr, .mc, .rm32, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 5, .none  },
     .{ .shr, .mc, .rm64, .cl,    .none, .none, 1, 0xd3, 0x00, 0x00, 5, .long  },
     .{ .shr, .mi, .rm8,  .imm8,  .none, .none, 1, 0xc0, 0x00, 0x00, 5, .none  },
+    .{ .shr, .mi, .rm8,  .imm8,  .none, .none, 1, 0xc0, 0x00, 0x00, 5, .rex   },
     .{ .shr, .mi, .rm16, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 5, .none  },
     .{ .shr, .mi, .rm32, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 5, .none  },
     .{ .shr, .mi, .rm64, .imm8,  .none, .none, 1, 0xc1, 0x00, 0x00, 5, .long  },
@@ -464,6 +534,7 @@ pub const table = &[_]Entry{
     .{ .sub, .zi, .eax,  .imm32,  .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none  },
     .{ .sub, .zi, .rax,  .imm32s, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .long  },
     .{ .sub, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 5, .none  },
+    .{ .sub, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 5, .rex   },
     .{ .sub, .mi, .rm16, .imm16,  .none, .none, 1, 0x81, 0x00, 0x00, 5, .none  },
     .{ .sub, .mi, .rm32, .imm32,  .none, .none, 1, 0x81, 0x00, 0x00, 5, .none  },
     .{ .sub, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 5, .long  },
@@ -471,10 +542,12 @@ pub const table = &[_]Entry{
     .{ .sub, .mi, .rm32, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 5, .none  },
     .{ .sub, .mi, .rm64, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 5, .long  },
     .{ .sub, .mr, .rm8,  .r8,     .none, .none, 1, 0x28, 0x00, 0x00, 0, .none  },
+    .{ .sub, .mr, .rm8,  .r8,     .none, .none, 1, 0x28, 0x00, 0x00, 0, .rex   },
     .{ .sub, .mr, .rm16, .r16,    .none, .none, 1, 0x29, 0x00, 0x00, 0, .none  },
     .{ .sub, .mr, .rm32, .r32,    .none, .none, 1, 0x29, 0x00, 0x00, 0, .none  },
     .{ .sub, .mr, .rm64, .r64,    .none, .none, 1, 0x29, 0x00, 0x00, 0, .long  },
     .{ .sub, .rm, .r8,   .rm8,    .none, .none, 1, 0x2a, 0x00, 0x00, 0, .none  },
+    .{ .sub, .rm, .r8,   .rm8,    .none, .none, 1, 0x2a, 0x00, 0x00, 0, .rex   },
     .{ .sub, .rm, .r16,  .rm16,   .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none  },
     .{ .sub, .rm, .r32,  .rm32,   .none, .none, 1, 0x2b, 0x00, 0x00, 0, .none  },
     .{ .sub, .rm, .r64,  .rm64,   .none, .none, 1, 0x2b, 0x00, 0x00, 0, .long  },
@@ -486,10 +559,12 @@ pub const table = &[_]Entry{
     .{ .@"test", .zi, .eax,  .imm32,  .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none  },
     .{ .@"test", .zi, .rax,  .imm32s, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .long  },
     .{ .@"test", .mi, .rm8,  .imm8,   .none, .none, 1, 0xf6, 0x00, 0x00, 0, .none  },
+    .{ .@"test", .mi, .rm8,  .imm8,   .none, .none, 1, 0xf6, 0x00, 0x00, 0, .rex   },
     .{ .@"test", .mi, .rm16, .imm16,  .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none  },
     .{ .@"test", .mi, .rm32, .imm32,  .none, .none, 1, 0xf7, 0x00, 0x00, 0, .none  },
     .{ .@"test", .mi, .rm64, .imm32s, .none, .none, 1, 0xf7, 0x00, 0x00, 0, .long  },
     .{ .@"test", .mr, .rm8,  .r8,     .none, .none, 1, 0x84, 0x00, 0x00, 0, .none  },
+    .{ .@"test", .mr, .rm8,  .r8,     .none, .none, 1, 0x84, 0x00, 0x00, 0, .rex   },
     .{ .@"test", .mr, .rm16, .r16,    .none, .none, 1, 0x85, 0x00, 0x00, 0, .none  },
     .{ .@"test", .mr, .rm32, .r32,    .none, .none, 1, 0x85, 0x00, 0x00, 0, .none  },
     .{ .@"test", .mr, .rm64, .r64,    .none, .none, 1, 0x85, 0x00, 0x00, 0, .long  },
@@ -501,6 +576,7 @@ pub const table = &[_]Entry{
     .{ .xor, .zi, .eax,  .imm32,  .none, .none, 1, 0x35, 0x00, 0x00, 0, .none  },
     .{ .xor, .zi, .rax,  .imm32s, .none, .none, 1, 0x35, 0x00, 0x00, 0, .long  },
     .{ .xor, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 6, .none  },
+    .{ .xor, .mi, .rm8,  .imm8,   .none, .none, 1, 0x80, 0x00, 0x00, 6, .rex   },
     .{ .xor, .mi, .rm16, .imm16,  .none, .none, 1, 0x81, 0x00, 0x00, 6, .none  },
     .{ .xor, .mi, .rm32, .imm32,  .none, .none, 1, 0x81, 0x00, 0x00, 6, .none  },
     .{ .xor, .mi, .rm64, .imm32s, .none, .none, 1, 0x81, 0x00, 0x00, 6, .long  },
@@ -508,10 +584,12 @@ pub const table = &[_]Entry{
     .{ .xor, .mi, .rm32, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 6, .none  },
     .{ .xor, .mi, .rm64, .imm8s,  .none, .none, 1, 0x83, 0x00, 0x00, 6, .long  },
     .{ .xor, .mr, .rm8,  .r8,     .none, .none, 1, 0x30, 0x00, 0x00, 0, .none  },
+    .{ .xor, .mr, .rm8,  .r8,     .none, .none, 1, 0x30, 0x00, 0x00, 0, .rex   },
     .{ .xor, .mr, .rm16, .r16,    .none, .none, 1, 0x31, 0x00, 0x00, 0, .none  },
     .{ .xor, .mr, .rm32, .r32,    .none, .none, 1, 0x31, 0x00, 0x00, 0, .none  },
     .{ .xor, .mr, .rm64, .r64,    .none, .none, 1, 0x31, 0x00, 0x00, 0, .long  },
     .{ .xor, .rm, .r8,   .rm8,    .none, .none, 1, 0x32, 0x00, 0x00, 0, .none  },
+    .{ .xor, .rm, .r8,   .rm8,    .none, .none, 1, 0x32, 0x00, 0x00, 0, .rex   },
     .{ .xor, .rm, .r16,  .rm16,   .none, .none, 1, 0x33, 0x00, 0x00, 0, .none  },
     .{ .xor, .rm, .r32,  .rm32,   .none, .none, 1, 0x33, 0x00, 0x00, 0, .none  },
     .{ .xor, .rm, .r64,  .rm64,   .none, .none, 1, 0x33, 0x00, 0x00, 0, .long  },