mirror of
https://github.com/ziglang/zig.git
synced 2025-12-26 08:03:08 +00:00
Merge pull request #14886 from ziglang/x86_64-encoder
x86_64: add table-driven instruction encoder
This commit is contained in:
commit
d525ecb523
@ -559,9 +559,12 @@ set(ZIG_STAGE2_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/wasm/Mir.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/CodeGen.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/Emit.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/Encoding.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/Mir.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/bits.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/abi.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/bits.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/encoder.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/arch/x86_64/encodings.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/clang.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/clang_options.zig"
|
||||
"${CMAKE_SOURCE_DIR}/src/clang_options_data.zig"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
587
src/arch/x86_64/Encoding.zig
Normal file
587
src/arch/x86_64/Encoding.zig
Normal file
@ -0,0 +1,587 @@
|
||||
const Encoding = @This();
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const math = std.math;
|
||||
|
||||
const bits = @import("bits.zig");
|
||||
const encoder = @import("encoder.zig");
|
||||
const Instruction = encoder.Instruction;
|
||||
const Register = bits.Register;
|
||||
const Rex = encoder.Rex;
|
||||
const LegacyPrefixes = encoder.LegacyPrefixes;
|
||||
|
||||
const table = @import("encodings.zig").table;
|
||||
|
||||
mnemonic: Mnemonic,
|
||||
op_en: OpEn,
|
||||
op1: Op,
|
||||
op2: Op,
|
||||
op3: Op,
|
||||
op4: Op,
|
||||
opc_len: u2,
|
||||
opc: [3]u8,
|
||||
modrm_ext: u3,
|
||||
mode: Mode,
|
||||
|
||||
pub fn findByMnemonic(mnemonic: Mnemonic, args: struct {
|
||||
op1: Instruction.Operand,
|
||||
op2: Instruction.Operand,
|
||||
op3: Instruction.Operand,
|
||||
op4: Instruction.Operand,
|
||||
}) !?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;
|
||||
for (table) |entry| {
|
||||
const enc = Encoding{
|
||||
.mnemonic = entry[0],
|
||||
.op_en = entry[1],
|
||||
.op1 = entry[2],
|
||||
.op2 = entry[3],
|
||||
.op3 = entry[4],
|
||||
.op4 = entry[5],
|
||||
.opc_len = entry[6],
|
||||
.opc = .{ entry[7], entry[8], entry[9] },
|
||||
.modrm_ext = entry[10],
|
||||
.mode = entry[11],
|
||||
};
|
||||
if (enc.mnemonic == mnemonic and
|
||||
input_op1.isSubset(enc.op1, enc.mode) and
|
||||
input_op2.isSubset(enc.op2, enc.mode) and
|
||||
input_op3.isSubset(enc.op3, enc.mode) and
|
||||
input_op4.isSubset(enc.op4, enc.mode))
|
||||
{
|
||||
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 {
|
||||
op1: Instruction.Operand,
|
||||
op2: Instruction.Operand,
|
||||
op3: Instruction.Operand,
|
||||
op4: Instruction.Operand,
|
||||
}) usize {
|
||||
var inst = Instruction{
|
||||
.op1 = params.op1,
|
||||
.op2 = params.op2,
|
||||
.op3 = params.op3,
|
||||
.op4 = params.op4,
|
||||
.encoding = encoding,
|
||||
};
|
||||
var cwriter = std.io.countingWriter(std.io.null_writer);
|
||||
inst.encode(cwriter.writer()) catch unreachable; // Not allowed to fail here unless OOM.
|
||||
return @intCast(usize, cwriter.bytes_written);
|
||||
}
|
||||
};
|
||||
|
||||
var shortest_encoding: ?struct {
|
||||
index: usize,
|
||||
len: usize,
|
||||
} = null;
|
||||
var i: usize = 0;
|
||||
while (i < count) : (i += 1) {
|
||||
const candidate = candidates[i];
|
||||
switch (candidate.mode) {
|
||||
.long, .rex => if (rex_invalid) return error.CannotEncode,
|
||||
else => {},
|
||||
}
|
||||
|
||||
const len = EncodingLength.estimate(candidate, .{
|
||||
.op1 = args.op1,
|
||||
.op2 = args.op2,
|
||||
.op3 = args.op3,
|
||||
.op4 = args.op4,
|
||||
});
|
||||
const current = shortest_encoding orelse {
|
||||
shortest_encoding = .{ .index = i, .len = len };
|
||||
continue;
|
||||
};
|
||||
if (len < current.len) {
|
||||
shortest_encoding = .{ .index = i, .len = len };
|
||||
}
|
||||
}
|
||||
|
||||
return candidates[shortest_encoding.?.index];
|
||||
}
|
||||
|
||||
/// Returns first matching encoding by opcode.
|
||||
pub fn findByOpcode(opc: []const u8, prefixes: struct {
|
||||
legacy: LegacyPrefixes,
|
||||
rex: Rex,
|
||||
}, modrm_ext: ?u3) ?Encoding {
|
||||
for (table) |entry| {
|
||||
const enc = Encoding{
|
||||
.mnemonic = entry[0],
|
||||
.op_en = entry[1],
|
||||
.op1 = entry[2],
|
||||
.op2 = entry[3],
|
||||
.op3 = entry[4],
|
||||
.op4 = entry[5],
|
||||
.opc_len = entry[6],
|
||||
.opc = .{ entry[7], entry[8], entry[9] },
|
||||
.modrm_ext = entry[10],
|
||||
.mode = entry[11],
|
||||
};
|
||||
const match = match: {
|
||||
if (modrm_ext) |ext| {
|
||||
break :match ext == enc.modrm_ext and std.mem.eql(u8, enc.opcode(), opc);
|
||||
}
|
||||
break :match std.mem.eql(u8, enc.opcode(), opc);
|
||||
};
|
||||
if (match) {
|
||||
if (prefixes.rex.w) {
|
||||
switch (enc.mode) {
|
||||
.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,
|
||||
else => {},
|
||||
}
|
||||
} else {
|
||||
if (enc.mode == .none) {
|
||||
switch (enc.operandBitSize()) {
|
||||
16 => {},
|
||||
else => return enc,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn opcode(encoding: *const Encoding) []const u8 {
|
||||
return encoding.opc[0..encoding.opc_len];
|
||||
}
|
||||
|
||||
pub fn mandatoryPrefix(encoding: *const Encoding) ?u8 {
|
||||
const prefix = encoding.opc[0];
|
||||
return switch (prefix) {
|
||||
0x66, 0xf2, 0xf3 => prefix,
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn modRmExt(encoding: Encoding) u3 {
|
||||
return switch (encoding.op_en) {
|
||||
.m, .mi, .m1, .mc => encoding.modrm_ext,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn operandBitSize(encoding: Encoding) u64 {
|
||||
if (encoding.mode == .long) return 64;
|
||||
const bit_size: u64 = switch (encoding.op_en) {
|
||||
.np => switch (encoding.op1) {
|
||||
.o16 => 16,
|
||||
.o32 => 32,
|
||||
.o64 => 64,
|
||||
else => 32,
|
||||
},
|
||||
.td => encoding.op2.bitSize(),
|
||||
else => encoding.op1.bitSize(),
|
||||
};
|
||||
return bit_size;
|
||||
}
|
||||
|
||||
pub fn format(
|
||||
encoding: Encoding,
|
||||
comptime fmt: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
writer: anytype,
|
||||
) !void {
|
||||
_ = options;
|
||||
_ = fmt;
|
||||
switch (encoding.mode) {
|
||||
.long => try writer.writeAll("REX.W + "),
|
||||
else => {},
|
||||
}
|
||||
|
||||
for (encoding.opcode()) |byte| {
|
||||
try writer.print("{x:0>2} ", .{byte});
|
||||
}
|
||||
|
||||
switch (encoding.op_en) {
|
||||
.np, .fd, .td, .i, .zi, .d => {},
|
||||
.o, .oi => {
|
||||
const tag = switch (encoding.op1) {
|
||||
.r8 => "rb",
|
||||
.r16 => "rw",
|
||||
.r32 => "rd",
|
||||
.r64 => "rd",
|
||||
else => unreachable,
|
||||
};
|
||||
try writer.print("+{s} ", .{tag});
|
||||
},
|
||||
.m, .mi, .m1, .mc => try writer.print("/{d} ", .{encoding.modRmExt()}),
|
||||
.mr, .rm, .rmi => try writer.writeAll("/r "),
|
||||
}
|
||||
|
||||
switch (encoding.op_en) {
|
||||
.i, .d, .zi, .oi, .mi, .rmi => {
|
||||
const op = switch (encoding.op_en) {
|
||||
.i, .d => encoding.op1,
|
||||
.zi, .oi, .mi => encoding.op2,
|
||||
.rmi => encoding.op3,
|
||||
else => unreachable,
|
||||
};
|
||||
const tag = switch (op) {
|
||||
.imm8, .imm8s => "ib",
|
||||
.imm16, .imm16s => "iw",
|
||||
.imm32, .imm32s => "id",
|
||||
.imm64 => "io",
|
||||
.rel8 => "cb",
|
||||
.rel16 => "cw",
|
||||
.rel32 => "cd",
|
||||
else => unreachable,
|
||||
};
|
||||
try writer.print("{s} ", .{tag});
|
||||
},
|
||||
.np, .fd, .td, .o, .m, .m1, .mc, .mr, .rm => {},
|
||||
}
|
||||
|
||||
try writer.print("{s} ", .{@tagName(encoding.mnemonic)});
|
||||
|
||||
const ops = &[_]Op{ encoding.op1, encoding.op2, encoding.op3, encoding.op4 };
|
||||
for (ops) |op| switch (op) {
|
||||
.none, .o16, .o32, .o64 => break,
|
||||
else => try writer.print("{s} ", .{@tagName(op)}),
|
||||
};
|
||||
|
||||
const op_en = switch (encoding.op_en) {
|
||||
.zi => .i,
|
||||
else => |op_en| op_en,
|
||||
};
|
||||
try writer.print("{s}", .{@tagName(op_en)});
|
||||
}
|
||||
|
||||
pub const Mnemonic = enum {
|
||||
// zig fmt: off
|
||||
// General-purpose
|
||||
adc, add, @"and",
|
||||
call, cbw, cwde, cdqe, cwd, cdq, cqo, cmp,
|
||||
cmova, cmovae, cmovb, cmovbe, cmovc, cmove, cmovg, cmovge, cmovl, cmovle, cmovna,
|
||||
cmovnae, cmovnb, cmovnbe, cmovnc, cmovne, cmovng, cmovnge, cmovnl, cmovnle, cmovno,
|
||||
cmovnp, cmovns, cmovnz, cmovo, cmovp, cmovpe, cmovpo, cmovs, cmovz,
|
||||
div,
|
||||
fisttp, fld,
|
||||
idiv, imul, int3,
|
||||
ja, jae, jb, jbe, jc, jrcxz, je, jg, jge, jl, jle, jna, jnae, jnb, jnbe,
|
||||
jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, js, jz,
|
||||
jmp,
|
||||
lea,
|
||||
mov, movsx, movsxd, movzx, mul,
|
||||
nop,
|
||||
@"or",
|
||||
pop, push,
|
||||
ret,
|
||||
sal, sar, sbb, shl, shr, sub, syscall,
|
||||
seta, setae, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae,
|
||||
setnb, setnbe, setnc, setne, setng, setnge, setnl, setnle, setno, setnp, setns,
|
||||
setnz, seto, setp, setpe, setpo, sets, setz,
|
||||
@"test",
|
||||
ud2,
|
||||
xor,
|
||||
// SSE
|
||||
addss,
|
||||
cmpss,
|
||||
movss,
|
||||
ucomiss,
|
||||
// SSE2
|
||||
addsd,
|
||||
cmpsd,
|
||||
movq, movsd,
|
||||
ucomisd,
|
||||
// zig fmt: on
|
||||
};
|
||||
|
||||
pub const OpEn = enum {
|
||||
// zig fmt: off
|
||||
np,
|
||||
o, oi,
|
||||
i, zi,
|
||||
d, m,
|
||||
fd, td,
|
||||
m1, mc, mi, mr, rm, rmi,
|
||||
// zig fmt: on
|
||||
};
|
||||
|
||||
pub const Op = enum {
|
||||
// zig fmt: off
|
||||
none,
|
||||
o16, o32, o64,
|
||||
unity,
|
||||
imm8, imm16, imm32, imm64,
|
||||
imm8s, imm16s, imm32s,
|
||||
al, ax, eax, rax,
|
||||
cl,
|
||||
r8, r16, r32, r64,
|
||||
rm8, rm16, rm32, rm64,
|
||||
m8, m16, m32, m64, m80,
|
||||
rel8, rel16, rel32,
|
||||
m,
|
||||
moffs,
|
||||
sreg,
|
||||
xmm, xmm_m32, xmm_m64,
|
||||
// zig fmt: on
|
||||
|
||||
pub fn fromOperand(operand: Instruction.Operand) Op {
|
||||
switch (operand) {
|
||||
.none => return .none,
|
||||
|
||||
.reg => |reg| {
|
||||
switch (reg.class()) {
|
||||
.segment => return .sreg,
|
||||
.floating_point => return switch (reg.bitSize()) {
|
||||
128 => .xmm,
|
||||
else => unreachable,
|
||||
},
|
||||
.general_purpose => {
|
||||
if (reg.to64() == .rax) return switch (reg) {
|
||||
.al => .al,
|
||||
.ax => .ax,
|
||||
.eax => .eax,
|
||||
.rax => .rax,
|
||||
else => unreachable,
|
||||
};
|
||||
if (reg == .cl) return .cl;
|
||||
return switch (reg.bitSize()) {
|
||||
8 => .r8,
|
||||
16 => .r16,
|
||||
32 => .r32,
|
||||
64 => .r64,
|
||||
else => unreachable,
|
||||
};
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
.mem => |mem| switch (mem) {
|
||||
.moffs => return .moffs,
|
||||
.sib, .rip => {
|
||||
const bit_size = mem.bitSize();
|
||||
return switch (bit_size) {
|
||||
8 => .m8,
|
||||
16 => .m16,
|
||||
32 => .m32,
|
||||
64 => .m64,
|
||||
80 => .m80,
|
||||
else => unreachable,
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
.imm => |imm| {
|
||||
switch (imm) {
|
||||
.signed => |x| {
|
||||
if (x == 1) return .unity;
|
||||
if (math.cast(i8, x)) |_| return .imm8s;
|
||||
if (math.cast(i16, x)) |_| return .imm16s;
|
||||
return .imm32s;
|
||||
},
|
||||
.unsigned => |x| {
|
||||
if (x == 1) return .unity;
|
||||
if (math.cast(i8, x)) |_| return .imm8s;
|
||||
if (math.cast(u8, x)) |_| return .imm8;
|
||||
if (math.cast(i16, x)) |_| return .imm16s;
|
||||
if (math.cast(u16, x)) |_| return .imm16;
|
||||
if (math.cast(i32, x)) |_| return .imm32s;
|
||||
if (math.cast(u32, x)) |_| return .imm32;
|
||||
return .imm64;
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bitSize(op: Op) u64 {
|
||||
return switch (op) {
|
||||
.none, .o16, .o32, .o64, .moffs, .m, .sreg => unreachable,
|
||||
.unity => 1,
|
||||
.imm8, .imm8s, .al, .cl, .r8, .m8, .rm8, .rel8 => 8,
|
||||
.imm16, .imm16s, .ax, .r16, .m16, .rm16, .rel16 => 16,
|
||||
.imm32, .imm32s, .eax, .r32, .m32, .rm32, .rel32, .xmm_m32 => 32,
|
||||
.imm64, .rax, .r64, .m64, .rm64, .xmm_m64 => 64,
|
||||
.m80 => 80,
|
||||
.xmm => 128,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isSigned(op: Op) bool {
|
||||
return switch (op) {
|
||||
.unity, .imm8, .imm16, .imm32, .imm64 => false,
|
||||
.imm8s, .imm16s, .imm32s => true,
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isUnsigned(op: Op) bool {
|
||||
return !op.isSigned();
|
||||
}
|
||||
|
||||
pub fn isRegister(op: Op) bool {
|
||||
// zig fmt: off
|
||||
return switch (op) {
|
||||
.cl,
|
||||
.al, .ax, .eax, .rax,
|
||||
.r8, .r16, .r32, .r64,
|
||||
.rm8, .rm16, .rm32, .rm64,
|
||||
.xmm, .xmm_m32, .xmm_m64,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
// zig fmt: on
|
||||
}
|
||||
|
||||
pub fn isImmediate(op: Op) bool {
|
||||
// zig fmt: off
|
||||
return switch (op) {
|
||||
.imm8, .imm16, .imm32, .imm64,
|
||||
.imm8s, .imm16s, .imm32s,
|
||||
.rel8, .rel16, .rel32,
|
||||
.unity,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
// zig fmt: on
|
||||
}
|
||||
|
||||
pub fn isMemory(op: Op) bool {
|
||||
// zig fmt: off
|
||||
return switch (op) {
|
||||
.rm8, .rm16, .rm32, .rm64,
|
||||
.m8, .m16, .m32, .m64, .m80,
|
||||
.m,
|
||||
.xmm_m32, .xmm_m64,
|
||||
=> true,
|
||||
else => false,
|
||||
};
|
||||
// zig fmt: on
|
||||
}
|
||||
|
||||
pub fn isSegmentRegister(op: Op) bool {
|
||||
return switch (op) {
|
||||
.moffs, .sreg => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isFloatingPointRegister(op: Op) bool {
|
||||
return switch (op) {
|
||||
.xmm, .xmm_m32, .xmm_m64 => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
/// Given an operand `op` checks if `target` is a subset for the purposes of the encoding.
|
||||
pub fn isSubset(op: Op, target: Op, mode: Mode) bool {
|
||||
switch (op) {
|
||||
.m, .o16, .o32, .o64 => unreachable,
|
||||
.moffs, .sreg => return op == target,
|
||||
.none => switch (target) {
|
||||
.o16, .o32, .o64, .none => return true,
|
||||
else => return false,
|
||||
},
|
||||
else => {
|
||||
if (op.isRegister() and target.isRegister()) {
|
||||
switch (mode) {
|
||||
.sse, .sse2 => return op.isFloatingPointRegister() and target.isFloatingPointRegister(),
|
||||
else => switch (target) {
|
||||
.cl, .al, .ax, .eax, .rax => return op == target,
|
||||
else => return op.bitSize() == target.bitSize(),
|
||||
},
|
||||
}
|
||||
}
|
||||
if (op.isMemory() and target.isMemory()) {
|
||||
switch (target) {
|
||||
.m => return true,
|
||||
else => return op.bitSize() == target.bitSize(),
|
||||
}
|
||||
}
|
||||
if (op.isImmediate() and target.isImmediate()) {
|
||||
switch (target) {
|
||||
.imm64 => if (op.bitSize() <= 64) return true,
|
||||
.imm32s, .rel32 => if (op.bitSize() < 32 or (op.bitSize() == 32 and op.isSigned()))
|
||||
return true,
|
||||
.imm32 => if (op.bitSize() <= 32) return true,
|
||||
.imm16s, .rel16 => if (op.bitSize() < 16 or (op.bitSize() == 16 and op.isSigned()))
|
||||
return true,
|
||||
.imm16 => if (op.bitSize() <= 16) return true,
|
||||
.imm8s, .rel8 => if (op.bitSize() < 8 or (op.bitSize() == 8 and op.isSigned()))
|
||||
return true,
|
||||
.imm8 => if (op.bitSize() <= 8) return true,
|
||||
else => {},
|
||||
}
|
||||
return op == target;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const Mode = enum {
|
||||
none,
|
||||
fpu,
|
||||
rex,
|
||||
long,
|
||||
sse,
|
||||
sse2,
|
||||
};
|
||||
@ -12,9 +12,12 @@ const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const bits = @import("bits.zig");
|
||||
const encoder = @import("encoder.zig");
|
||||
|
||||
const Air = @import("../../Air.zig");
|
||||
const CodeGen = @import("CodeGen.zig");
|
||||
const IntegerBitSet = std.bit_set.IntegerBitSet;
|
||||
const Memory = bits.Memory;
|
||||
const Register = bits.Register;
|
||||
|
||||
instructions: std.MultiArrayList(Inst).Slice,
|
||||
@ -24,431 +27,300 @@ extra: []const u32,
|
||||
pub const Inst = struct {
|
||||
tag: Tag,
|
||||
ops: Ops,
|
||||
/// The meaning of this depends on `tag` and `ops`.
|
||||
data: Data,
|
||||
|
||||
pub const Tag = enum(u16) {
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg2
|
||||
/// 0b00 reg1, imm32
|
||||
/// 0b01 reg1, [reg2 + imm32]
|
||||
/// 0b01 reg1, [ds:imm32]
|
||||
/// 0b10 [reg1 + imm32], reg2
|
||||
/// Notes:
|
||||
/// * If reg2 is `none` then it means Data field `imm` is used as the immediate.
|
||||
/// * When two imm32 values are required, Data field `payload` points at `ImmPair`.
|
||||
adc,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 byte ptr [reg1 + imm32], imm8
|
||||
/// 0b01 word ptr [reg1 + imm32], imm16
|
||||
/// 0b10 dword ptr [reg1 + imm32], imm32
|
||||
/// 0b11 qword ptr [reg1 + imm32], imm32 (sign-extended to imm64)
|
||||
/// Notes:
|
||||
/// * Uses `ImmPair` as payload
|
||||
adc_mem_imm,
|
||||
|
||||
/// form: reg1, [reg2 + scale*index + imm32]
|
||||
/// ops flags scale
|
||||
/// 0b00 1
|
||||
/// 0b01 2
|
||||
/// 0b10 4
|
||||
/// 0b11 8
|
||||
/// Notes:
|
||||
/// * Uses `IndexRegisterDisp` as payload
|
||||
adc_scale_src,
|
||||
|
||||
/// form: [reg1 + scale*index + imm32], reg2
|
||||
/// ops flags scale
|
||||
/// 0b00 1
|
||||
/// 0b01 2
|
||||
/// 0b10 4
|
||||
/// 0b11 8
|
||||
/// Notes:
|
||||
/// * Uses `IndexRegisterDisp` payload.
|
||||
adc_scale_dst,
|
||||
|
||||
/// form: [reg1 + scale*rax + imm32], imm32
|
||||
/// ops flags scale
|
||||
/// 0b00 1
|
||||
/// 0b01 2
|
||||
/// 0b10 4
|
||||
/// 0b11 8
|
||||
/// Notes:
|
||||
/// * Uses `IndexRegisterDispImm` payload.
|
||||
adc_scale_imm,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 byte ptr [reg1 + index + imm32], imm8
|
||||
/// 0b01 word ptr [reg1 + index + imm32], imm16
|
||||
/// 0b10 dword ptr [reg1 + index + imm32], imm32
|
||||
/// 0b11 qword ptr [reg1 + index + imm32], imm32 (sign-extended to imm64)
|
||||
/// Notes:
|
||||
/// * Uses `IndexRegisterDispImm` payload.
|
||||
adc_mem_index_imm,
|
||||
|
||||
// The following instructions all have the same encoding as `adc`.
|
||||
|
||||
add,
|
||||
add_mem_imm,
|
||||
add_scale_src,
|
||||
add_scale_dst,
|
||||
add_scale_imm,
|
||||
add_mem_index_imm,
|
||||
sub,
|
||||
sub_mem_imm,
|
||||
sub_scale_src,
|
||||
sub_scale_dst,
|
||||
sub_scale_imm,
|
||||
sub_mem_index_imm,
|
||||
xor,
|
||||
xor_mem_imm,
|
||||
xor_scale_src,
|
||||
xor_scale_dst,
|
||||
xor_scale_imm,
|
||||
xor_mem_index_imm,
|
||||
@"and",
|
||||
and_mem_imm,
|
||||
and_scale_src,
|
||||
and_scale_dst,
|
||||
and_scale_imm,
|
||||
and_mem_index_imm,
|
||||
@"or",
|
||||
or_mem_imm,
|
||||
or_scale_src,
|
||||
or_scale_dst,
|
||||
or_scale_imm,
|
||||
or_mem_index_imm,
|
||||
rol,
|
||||
rol_mem_imm,
|
||||
rol_scale_src,
|
||||
rol_scale_dst,
|
||||
rol_scale_imm,
|
||||
rol_mem_index_imm,
|
||||
ror,
|
||||
ror_mem_imm,
|
||||
ror_scale_src,
|
||||
ror_scale_dst,
|
||||
ror_scale_imm,
|
||||
ror_mem_index_imm,
|
||||
rcl,
|
||||
rcl_mem_imm,
|
||||
rcl_scale_src,
|
||||
rcl_scale_dst,
|
||||
rcl_scale_imm,
|
||||
rcl_mem_index_imm,
|
||||
rcr,
|
||||
rcr_mem_imm,
|
||||
rcr_scale_src,
|
||||
rcr_scale_dst,
|
||||
rcr_scale_imm,
|
||||
rcr_mem_index_imm,
|
||||
sbb,
|
||||
sbb_mem_imm,
|
||||
sbb_scale_src,
|
||||
sbb_scale_dst,
|
||||
sbb_scale_imm,
|
||||
sbb_mem_index_imm,
|
||||
cmp,
|
||||
cmp_mem_imm,
|
||||
cmp_scale_src,
|
||||
cmp_scale_dst,
|
||||
cmp_scale_imm,
|
||||
cmp_mem_index_imm,
|
||||
mov,
|
||||
mov_mem_imm,
|
||||
mov_scale_src,
|
||||
mov_scale_dst,
|
||||
mov_scale_imm,
|
||||
mov_mem_index_imm,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg2,
|
||||
/// 0b01 reg1, byte ptr [reg2 + imm32]
|
||||
/// 0b10 reg1, word ptr [reg2 + imm32]
|
||||
/// 0b11 reg1, dword ptr [reg2 + imm32]
|
||||
mov_sign_extend,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg2
|
||||
/// 0b01 reg1, byte ptr [reg2 + imm32]
|
||||
/// 0b10 reg1, word ptr [reg2 + imm32]
|
||||
mov_zero_extend,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, [reg2 + imm32]
|
||||
/// 0b00 reg1, [ds:imm32]
|
||||
/// 0b01 reg1, [rip + imm32]
|
||||
/// 0b10 reg1, [reg2 + index + imm32]
|
||||
/// Notes:
|
||||
/// * 0b10 uses `IndexRegisterDisp` payload
|
||||
lea,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, [rip + reloc] // via GOT PIC
|
||||
/// 0b01 reg1, [rip + reloc] // direct load PIC
|
||||
/// 0b10 reg1, [rip + reloc] // via imports table PIC
|
||||
/// Notes:
|
||||
/// * `Data` contains `relocation`
|
||||
lea_pic,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, 1
|
||||
/// 0b01 reg1, .cl
|
||||
/// 0b10 reg1, imm8
|
||||
/// Notes:
|
||||
/// * If flags == 0b10, uses `imm`.
|
||||
shl,
|
||||
shl_mem_imm,
|
||||
shl_scale_src,
|
||||
shl_scale_dst,
|
||||
shl_scale_imm,
|
||||
shl_mem_index_imm,
|
||||
sal,
|
||||
sal_mem_imm,
|
||||
sal_scale_src,
|
||||
sal_scale_dst,
|
||||
sal_scale_imm,
|
||||
sal_mem_index_imm,
|
||||
shr,
|
||||
shr_mem_imm,
|
||||
shr_scale_src,
|
||||
shr_scale_dst,
|
||||
shr_scale_imm,
|
||||
shr_mem_index_imm,
|
||||
sar,
|
||||
sar_mem_imm,
|
||||
sar_scale_src,
|
||||
sar_scale_dst,
|
||||
sar_scale_imm,
|
||||
sar_mem_index_imm,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1
|
||||
/// 0b00 byte ptr [reg2 + imm32]
|
||||
/// 0b01 word ptr [reg2 + imm32]
|
||||
/// 0b10 dword ptr [reg2 + imm32]
|
||||
/// 0b11 qword ptr [reg2 + imm32]
|
||||
imul,
|
||||
idiv,
|
||||
mul,
|
||||
div,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 AX <- AL
|
||||
/// 0b01 DX:AX <- AX
|
||||
/// 0b10 EDX:EAX <- EAX
|
||||
/// 0b11 RDX:RAX <- RAX
|
||||
cwd,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg2
|
||||
/// 0b01 reg1, [reg2 + imm32]
|
||||
/// 0b01 reg1, [imm32] if reg2 is none
|
||||
/// 0b10 reg1, reg2, imm32
|
||||
/// 0b11 reg1, [reg2 + imm32], imm32
|
||||
imul_complex,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, imm64
|
||||
/// 0b01 rax, moffs64
|
||||
/// Notes:
|
||||
/// * If reg1 is 64-bit, the immediate is 64-bit and stored
|
||||
/// within extra data `Imm64`.
|
||||
/// * For 0b01, reg1 (or reg2) need to be
|
||||
/// a version of rax. If reg1 == .none, then reg2 == .rax,
|
||||
/// or vice versa.
|
||||
movabs,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 word ptr [reg1 + imm32]
|
||||
/// 0b01 dword ptr [reg1 + imm32]
|
||||
/// 0b10 qword ptr [reg1 + imm32]
|
||||
/// Notes:
|
||||
/// * source is always ST(0)
|
||||
/// * only supports memory operands as destination
|
||||
fisttp,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b01 dword ptr [reg1 + imm32]
|
||||
/// 0b10 qword ptr [reg1 + imm32]
|
||||
fld,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 inst
|
||||
/// 0b01 reg1
|
||||
/// 0b01 [imm32] if reg1 is none
|
||||
/// 0b10 [reg1 + imm32]
|
||||
jmp,
|
||||
call,
|
||||
|
||||
/// ops flags:
|
||||
/// unused
|
||||
/// Notes:
|
||||
/// * uses `inst_cc` in Data.
|
||||
cond_jmp,
|
||||
|
||||
/// ops flags:
|
||||
/// 0b00 reg1
|
||||
/// Notes:
|
||||
/// * uses condition code (CC) stored as part of data
|
||||
cond_set_byte,
|
||||
|
||||
/// ops flags:
|
||||
/// 0b00 reg1, reg2,
|
||||
/// 0b01 reg1, word ptr [reg2 + imm]
|
||||
/// 0b10 reg1, dword ptr [reg2 + imm]
|
||||
/// 0b11 reg1, qword ptr [reg2 + imm]
|
||||
/// Notes:
|
||||
/// * uses condition code (CC) stored as part of data
|
||||
cond_mov,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1
|
||||
/// 0b01 [reg1 + imm32]
|
||||
/// 0b10 imm32
|
||||
/// Notes:
|
||||
/// * If 0b10 is specified and the tag is push, pushes immediate onto the stack
|
||||
/// using the mnemonic PUSH imm32.
|
||||
push,
|
||||
pop,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 retf imm16
|
||||
/// 0b01 retf
|
||||
/// 0b10 retn imm16
|
||||
/// 0b11 retn
|
||||
ret,
|
||||
|
||||
/// Fast system call
|
||||
syscall,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, imm32 if reg2 == .none
|
||||
/// 0b00 reg1, reg2
|
||||
/// TODO handle more cases
|
||||
@"test",
|
||||
|
||||
/// Undefined Instruction
|
||||
ud,
|
||||
|
||||
/// Breakpoint form:
|
||||
/// 0b00 int3
|
||||
interrupt,
|
||||
|
||||
/// Nop
|
||||
nop,
|
||||
|
||||
/// SSE instructions
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, qword ptr [reg2 + imm32]
|
||||
/// 0b01 qword ptr [reg1 + imm32], reg2
|
||||
/// 0b10 reg1, reg2
|
||||
mov_f64_sse,
|
||||
mov_f32_sse,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg2
|
||||
add_f64_sse,
|
||||
add_f32_sse,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg2
|
||||
cmp_f64_sse,
|
||||
cmp_f32_sse,
|
||||
|
||||
/// AVX instructions
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, qword ptr [reg2 + imm32]
|
||||
/// 0b01 qword ptr [reg1 + imm32], reg2
|
||||
/// 0b10 reg1, reg1, reg2
|
||||
mov_f64_avx,
|
||||
mov_f32_avx,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg1, reg2
|
||||
add_f64_avx,
|
||||
add_f32_avx,
|
||||
|
||||
/// ops flags: form:
|
||||
/// 0b00 reg1, reg1, reg2
|
||||
cmp_f64_avx,
|
||||
cmp_f32_avx,
|
||||
|
||||
/// Pseudo-instructions
|
||||
/// call extern function
|
||||
/// Notes:
|
||||
/// * target of the call is stored as `relocation` in `Data` union.
|
||||
call_extern,
|
||||
|
||||
/// end of prologue
|
||||
dbg_prologue_end,
|
||||
|
||||
/// start of epilogue
|
||||
dbg_epilogue_begin,
|
||||
|
||||
/// update debug line
|
||||
dbg_line,
|
||||
|
||||
/// push registers
|
||||
/// Uses `payload` field with `SaveRegisterList` as payload.
|
||||
push_regs,
|
||||
|
||||
/// pop registers
|
||||
/// Uses `payload` field with `SaveRegisterList` as payload.
|
||||
pop_regs,
|
||||
};
|
||||
/// The position of an MIR instruction within the `Mir` instructions array.
|
||||
pub const Index = u32;
|
||||
|
||||
pub const Ops = packed struct {
|
||||
reg1: u7,
|
||||
reg2: u7,
|
||||
flags: u2,
|
||||
pub const Tag = enum(u8) {
|
||||
/// Add with carry
|
||||
adc,
|
||||
/// Add
|
||||
add,
|
||||
/// Logical and
|
||||
@"and",
|
||||
/// Call
|
||||
call,
|
||||
/// Convert byte to word
|
||||
cbw,
|
||||
/// Convert word to doubleword
|
||||
cwde,
|
||||
/// Convert doubleword to quadword
|
||||
cdqe,
|
||||
/// Convert word to doubleword
|
||||
cwd,
|
||||
/// Convert doubleword to quadword
|
||||
cdq,
|
||||
/// Convert doubleword to quadword
|
||||
cqo,
|
||||
/// Logical compare
|
||||
cmp,
|
||||
/// Unsigned division
|
||||
div,
|
||||
/// Store integer with truncation
|
||||
fisttp,
|
||||
/// Load floating-point value
|
||||
fld,
|
||||
/// Signed division
|
||||
idiv,
|
||||
/// Signed multiplication
|
||||
imul,
|
||||
///
|
||||
int3,
|
||||
/// Jump
|
||||
jmp,
|
||||
/// Load effective address
|
||||
lea,
|
||||
/// Move
|
||||
mov,
|
||||
/// Move with sign extension
|
||||
movsx,
|
||||
/// Move with zero extension
|
||||
movzx,
|
||||
/// Multiply
|
||||
mul,
|
||||
/// No-op
|
||||
nop,
|
||||
/// Logical or
|
||||
@"or",
|
||||
/// Pop
|
||||
pop,
|
||||
/// Push
|
||||
push,
|
||||
/// Return
|
||||
ret,
|
||||
/// Arithmetic shift left
|
||||
sal,
|
||||
/// Arithmetic shift right
|
||||
sar,
|
||||
/// Integer subtraction with borrow
|
||||
sbb,
|
||||
/// Logical shift left
|
||||
shl,
|
||||
/// Logical shift right
|
||||
shr,
|
||||
/// Subtract
|
||||
sub,
|
||||
/// Syscall
|
||||
syscall,
|
||||
/// Test condition
|
||||
@"test",
|
||||
/// Undefined instruction
|
||||
ud2,
|
||||
/// Logical exclusive-or
|
||||
xor,
|
||||
|
||||
pub fn encode(vals: struct {
|
||||
reg1: Register = .none,
|
||||
reg2: Register = .none,
|
||||
flags: u2 = 0b00,
|
||||
}) Ops {
|
||||
return .{
|
||||
.reg1 = @enumToInt(vals.reg1),
|
||||
.reg2 = @enumToInt(vals.reg2),
|
||||
.flags = vals.flags,
|
||||
};
|
||||
}
|
||||
/// Add single precision floating point
|
||||
addss,
|
||||
/// Compare scalar single-precision floating-point values
|
||||
cmpss,
|
||||
/// Move scalar single-precision floating-point value
|
||||
movss,
|
||||
/// Unordered compare scalar single-precision floating-point values
|
||||
ucomiss,
|
||||
/// Add double precision floating point
|
||||
addsd,
|
||||
/// Compare scalar double-precision floating-point values
|
||||
cmpsd,
|
||||
/// Move scalar double-precision floating-point value
|
||||
movsd,
|
||||
/// Unordered compare scalar double-precision floating-point values
|
||||
ucomisd,
|
||||
|
||||
pub fn decode(ops: Ops) struct {
|
||||
reg1: Register,
|
||||
reg2: Register,
|
||||
flags: u2,
|
||||
} {
|
||||
return .{
|
||||
.reg1 = @intToEnum(Register, ops.reg1),
|
||||
.reg2 = @intToEnum(Register, ops.reg2),
|
||||
.flags = ops.flags,
|
||||
};
|
||||
}
|
||||
/// Conditional move
|
||||
cmovcc,
|
||||
/// Conditional jump
|
||||
jcc,
|
||||
/// Set byte on condition
|
||||
setcc,
|
||||
|
||||
/// Mov absolute to/from memory wrt segment register to/from rax
|
||||
mov_moffs,
|
||||
|
||||
/// Jump with relocation to another local MIR instruction
|
||||
/// Uses `inst` payload.
|
||||
jmp_reloc,
|
||||
|
||||
/// Call to an extern symbol via linker relocation.
|
||||
/// Uses `relocation` payload.
|
||||
call_extern,
|
||||
|
||||
/// Load effective address of a symbol not yet allocated in VM.
|
||||
lea_linker,
|
||||
|
||||
/// End of prologue
|
||||
dbg_prologue_end,
|
||||
/// Start of epilogue
|
||||
dbg_epilogue_begin,
|
||||
/// Update debug line
|
||||
/// Uses `payload` payload with data of type `DbgLineColumn`.
|
||||
dbg_line,
|
||||
/// Push registers
|
||||
/// Uses `payload` payload with data of type `SaveRegisterList`.
|
||||
push_regs,
|
||||
/// Pop registers
|
||||
/// Uses `payload` payload with data of type `SaveRegisterList`.
|
||||
pop_regs,
|
||||
|
||||
/// Tombstone
|
||||
/// Emitter should skip this instruction.
|
||||
dead,
|
||||
};
|
||||
|
||||
pub const Ops = enum(u8) {
|
||||
/// No data associated with this instruction (only mnemonic is used).
|
||||
none,
|
||||
/// Single register operand.
|
||||
/// Uses `r` payload.
|
||||
r,
|
||||
/// Register, register operands.
|
||||
/// Uses `rr` payload.
|
||||
rr,
|
||||
/// Register, register, register operands.
|
||||
/// Uses `rrr` payload.
|
||||
rrr,
|
||||
/// Register, register, immediate (sign-extended) operands.
|
||||
/// Uses `rri` payload.
|
||||
rri_s,
|
||||
/// Register, register, immediate (unsigned) operands.
|
||||
/// Uses `rri` payload.
|
||||
rri_u,
|
||||
/// Register with condition code (CC).
|
||||
/// Uses `r_c` payload.
|
||||
r_c,
|
||||
/// Register, register with condition code (CC).
|
||||
/// Uses `rr_c` payload.
|
||||
rr_c,
|
||||
/// Register, immediate (sign-extended) operands.
|
||||
/// Uses `ri` payload.
|
||||
ri_s,
|
||||
/// Register, immediate (unsigned) operands.
|
||||
/// Uses `ri` payload.
|
||||
ri_u,
|
||||
/// Register, 64-bit unsigned immediate operands.
|
||||
/// Uses `rx` payload with payload type `Imm64`.
|
||||
ri64,
|
||||
/// Immediate (sign-extended) operand.
|
||||
/// Uses `imm` payload.
|
||||
imm_s,
|
||||
/// Immediate (unsigned) operand.
|
||||
/// Uses `imm` payload.
|
||||
imm_u,
|
||||
/// Relative displacement operand.
|
||||
/// Uses `imm` payload.
|
||||
rel,
|
||||
/// Register, memory (SIB) operands.
|
||||
/// Uses `rx` payload.
|
||||
rm_sib,
|
||||
/// Register, memory (RIP) operands.
|
||||
/// Uses `rx` payload.
|
||||
rm_rip,
|
||||
/// Single memory (SIB) operand.
|
||||
/// Uses `payload` with extra data of type `MemorySib`.
|
||||
m_sib,
|
||||
/// Single memory (RIP) operand.
|
||||
/// Uses `payload` with extra data of type `MemoryRip`.
|
||||
m_rip,
|
||||
/// Memory (SIB), immediate (unsigned) operands.
|
||||
/// Uses `xi` payload with extra data of type `MemorySib`.
|
||||
mi_u_sib,
|
||||
/// Memory (RIP), immediate (unsigned) operands.
|
||||
/// Uses `xi` payload with extra data of type `MemoryRip`.
|
||||
mi_u_rip,
|
||||
/// Memory (SIB), immediate (sign-extend) operands.
|
||||
/// Uses `xi` payload with extra data of type `MemorySib`.
|
||||
mi_s_sib,
|
||||
/// Memory (RIP), immediate (sign-extend) operands.
|
||||
/// Uses `xi` payload with extra data of type `MemoryRip`.
|
||||
mi_s_rip,
|
||||
/// Memory (SIB), register operands.
|
||||
/// Uses `rx` payload with extra data of type `MemorySib`.
|
||||
mr_sib,
|
||||
/// Memory (RIP), register operands.
|
||||
/// Uses `rx` payload with extra data of type `MemoryRip`.
|
||||
mr_rip,
|
||||
/// Rax, Memory moffs.
|
||||
/// Uses `payload` with extra data of type `MemoryMoffs`.
|
||||
rax_moffs,
|
||||
/// Memory moffs, rax.
|
||||
/// Uses `payload` with extra data of type `MemoryMoffs`.
|
||||
moffs_rax,
|
||||
/// References another Mir instruction directly.
|
||||
/// Uses `inst` payload.
|
||||
inst,
|
||||
/// References another Mir instruction directly with condition code (CC).
|
||||
/// Uses `inst_cc` payload.
|
||||
inst_cc,
|
||||
/// Uses `payload` payload with data of type `MemoryConditionCode`.
|
||||
m_cc,
|
||||
/// Uses `rx` payload with extra data of type `MemoryConditionCode`.
|
||||
rm_cc,
|
||||
/// Uses `reloc` payload.
|
||||
reloc,
|
||||
/// Linker relocation - GOT indirection.
|
||||
/// Uses `payload` payload with extra data of type `LeaRegisterReloc`.
|
||||
got_reloc,
|
||||
/// Linker relocation - direct reference.
|
||||
/// Uses `payload` payload with extra data of type `LeaRegisterReloc`.
|
||||
direct_reloc,
|
||||
/// Linker relocation - imports table indirection (binding).
|
||||
/// Uses `payload` payload with extra data of type `LeaRegisterReloc`.
|
||||
import_reloc,
|
||||
};
|
||||
|
||||
/// All instructions have a 4-byte payload, which is contained within
|
||||
/// this union. `Tag` determines which union field is active, as well as
|
||||
/// how to interpret the data within.
|
||||
pub const Data = union {
|
||||
/// Another instruction.
|
||||
/// References another Mir instruction.
|
||||
inst: Index,
|
||||
/// A 32-bit immediate value.
|
||||
imm: u32,
|
||||
/// A condition code for use with EFLAGS register.
|
||||
cc: bits.Condition,
|
||||
/// Another instruction with condition code.
|
||||
/// Used by `cond_jmp`.
|
||||
/// Another instruction with condition code (CC).
|
||||
/// Used by `jcc`.
|
||||
inst_cc: struct {
|
||||
/// Another instruction.
|
||||
inst: Index,
|
||||
/// A condition code for use with EFLAGS register.
|
||||
cc: bits.Condition,
|
||||
},
|
||||
/// A 32-bit immediate value.
|
||||
imm: u32,
|
||||
r: Register,
|
||||
rr: struct {
|
||||
r1: Register,
|
||||
r2: Register,
|
||||
},
|
||||
rrr: struct {
|
||||
r1: Register,
|
||||
r2: Register,
|
||||
r3: Register,
|
||||
},
|
||||
rri: struct {
|
||||
r1: Register,
|
||||
r2: Register,
|
||||
imm: u32,
|
||||
},
|
||||
/// Register with condition code (CC).
|
||||
r_c: struct {
|
||||
r1: Register,
|
||||
cc: bits.Condition,
|
||||
},
|
||||
/// Register, register with condition code (CC).
|
||||
rr_c: struct {
|
||||
r1: Register,
|
||||
r2: Register,
|
||||
cc: bits.Condition,
|
||||
},
|
||||
/// Register, immediate.
|
||||
ri: struct {
|
||||
r1: Register,
|
||||
imm: u32,
|
||||
},
|
||||
/// Register, followed by custom payload found in extra.
|
||||
rx: struct {
|
||||
r1: Register,
|
||||
payload: u32,
|
||||
},
|
||||
/// Custom payload followed by an immediate.
|
||||
xi: struct {
|
||||
payload: u32,
|
||||
imm: u32,
|
||||
},
|
||||
/// Relocation for the linker where:
|
||||
/// * `atom_index` is the index of the source
|
||||
/// * `sym_index` is the index of the target
|
||||
@ -471,62 +343,13 @@ pub const Inst = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const IndexRegisterDisp = struct {
|
||||
/// Index register to use with SIB-based encoding
|
||||
index: u32,
|
||||
|
||||
/// Displacement value
|
||||
disp: u32,
|
||||
|
||||
pub fn encode(index: Register, disp: u32) IndexRegisterDisp {
|
||||
return .{
|
||||
.index = @enumToInt(index),
|
||||
.disp = disp,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn decode(this: IndexRegisterDisp) struct {
|
||||
index: Register,
|
||||
disp: u32,
|
||||
} {
|
||||
return .{
|
||||
.index = @intToEnum(Register, this.index),
|
||||
.disp = this.disp,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// TODO: would it be worth making `IndexRegisterDisp` and `IndexRegisterDispImm` a variable length list
|
||||
/// instead of having two structs, one a superset of the other one?
|
||||
pub const IndexRegisterDispImm = struct {
|
||||
/// Index register to use with SIB-based encoding
|
||||
index: u32,
|
||||
|
||||
/// Displacement value
|
||||
disp: u32,
|
||||
|
||||
/// Immediate
|
||||
imm: u32,
|
||||
|
||||
pub fn encode(index: Register, disp: u32, imm: u32) IndexRegisterDispImm {
|
||||
return .{
|
||||
.index = @enumToInt(index),
|
||||
.disp = disp,
|
||||
.imm = imm,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn decode(this: IndexRegisterDispImm) struct {
|
||||
index: Register,
|
||||
disp: u32,
|
||||
imm: u32,
|
||||
} {
|
||||
return .{
|
||||
.index = @intToEnum(Register, this.index),
|
||||
.disp = this.disp,
|
||||
.imm = this.imm,
|
||||
};
|
||||
}
|
||||
pub const LeaRegisterReloc = struct {
|
||||
/// Destination register.
|
||||
reg: u32,
|
||||
/// Index of the containing atom.
|
||||
atom_index: u32,
|
||||
/// Index into the linker's symbol table.
|
||||
sym_index: u32,
|
||||
};
|
||||
|
||||
/// Used in conjunction with `SaveRegisterList` payload to transfer a list of used registers
|
||||
@ -570,16 +393,13 @@ pub const RegisterList = struct {
|
||||
};
|
||||
|
||||
pub const SaveRegisterList = struct {
|
||||
/// Base register
|
||||
base_reg: u32,
|
||||
/// Use `RegisterList` to populate.
|
||||
register_list: u32,
|
||||
stack_end: u32,
|
||||
};
|
||||
|
||||
pub const ImmPair = struct {
|
||||
dest_off: u32,
|
||||
operand: u32,
|
||||
};
|
||||
|
||||
pub const Imm64 = struct {
|
||||
msb: u32,
|
||||
lsb: u32,
|
||||
@ -599,6 +419,90 @@ pub const Imm64 = struct {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO this can be further compacted using packed struct
|
||||
pub const MemorySib = struct {
|
||||
/// Size of the pointer.
|
||||
ptr_size: u32,
|
||||
/// Base register. -1 means null, or no base register.
|
||||
base: i32,
|
||||
/// Scale for index register. -1 means null, or no scale.
|
||||
/// This has to be in sync with `index` field.
|
||||
scale: i32,
|
||||
/// Index register. -1 means null, or no index register.
|
||||
/// This has to be in sync with `scale` field.
|
||||
index: i32,
|
||||
/// Displacement value.
|
||||
disp: i32,
|
||||
|
||||
pub fn encode(mem: Memory) MemorySib {
|
||||
const sib = mem.sib;
|
||||
return .{
|
||||
.ptr_size = @enumToInt(sib.ptr_size),
|
||||
.base = if (sib.base) |r| @enumToInt(r) else -1,
|
||||
.scale = if (sib.scale_index) |si| si.scale else -1,
|
||||
.index = if (sib.scale_index) |si| @enumToInt(si.index) else -1,
|
||||
.disp = sib.disp,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn decode(msib: MemorySib) Memory {
|
||||
const base: ?Register = if (msib.base == -1) null else @intToEnum(Register, msib.base);
|
||||
const scale_index: ?Memory.ScaleIndex = if (msib.index == -1) null else .{
|
||||
.scale = @intCast(u4, msib.scale),
|
||||
.index = @intToEnum(Register, msib.index),
|
||||
};
|
||||
const mem: Memory = .{ .sib = .{
|
||||
.ptr_size = @intToEnum(Memory.PtrSize, msib.ptr_size),
|
||||
.base = base,
|
||||
.scale_index = scale_index,
|
||||
.disp = msib.disp,
|
||||
} };
|
||||
return mem;
|
||||
}
|
||||
};
|
||||
|
||||
pub const MemoryRip = struct {
|
||||
/// Size of the pointer.
|
||||
ptr_size: u32,
|
||||
/// Displacement value.
|
||||
disp: i32,
|
||||
|
||||
pub fn encode(mem: Memory) MemoryRip {
|
||||
return .{
|
||||
.ptr_size = @enumToInt(mem.rip.ptr_size),
|
||||
.disp = mem.rip.disp,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn decode(mrip: MemoryRip) Memory {
|
||||
return .{ .rip = .{
|
||||
.ptr_size = @intToEnum(Memory.PtrSize, mrip.ptr_size),
|
||||
.disp = mrip.disp,
|
||||
} };
|
||||
}
|
||||
};
|
||||
|
||||
pub const MemoryMoffs = struct {
|
||||
/// Segment register.
|
||||
seg: u32,
|
||||
/// Absolute offset wrt to the segment register split between MSB and LSB parts much like
|
||||
/// `Imm64` payload.
|
||||
msb: u32,
|
||||
lsb: u32,
|
||||
|
||||
pub fn encodeOffset(moffs: *MemoryMoffs, v: u64) void {
|
||||
moffs.msb = @truncate(u32, v >> 32);
|
||||
moffs.lsb = @truncate(u32, v);
|
||||
}
|
||||
|
||||
pub fn decodeOffset(moffs: *const MemoryMoffs) u64 {
|
||||
var res: u64 = 0;
|
||||
res |= (@intCast(u64, moffs.msb) << 32);
|
||||
res |= @intCast(u64, moffs.lsb);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
pub const DbgLineColumn = struct {
|
||||
line: u32,
|
||||
column: u32,
|
||||
@ -610,9 +514,9 @@ pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
|
||||
mir.* = undefined;
|
||||
}
|
||||
|
||||
pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
|
||||
pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end: u32 } {
|
||||
const fields = std.meta.fields(T);
|
||||
var i: usize = index;
|
||||
var i: u32 = index;
|
||||
var result: T = undefined;
|
||||
inline for (fields) |field| {
|
||||
@field(result, field.name) = switch (field.type) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2275
src/arch/x86_64/encoder.zig
Normal file
2275
src/arch/x86_64/encoder.zig
Normal file
File diff suppressed because it is too large
Load Diff
621
src/arch/x86_64/encodings.zig
Normal file
621
src/arch/x86_64/encodings.zig
Normal file
@ -0,0 +1,621 @@
|
||||
const Encoding = @import("Encoding.zig");
|
||||
const Mnemonic = Encoding.Mnemonic;
|
||||
const OpEn = Encoding.OpEn;
|
||||
const Op = Encoding.Op;
|
||||
const Mode = Encoding.Mode;
|
||||
|
||||
const opcode_len = u2;
|
||||
const modrm_ext = u3;
|
||||
|
||||
const Entry = struct { Mnemonic, OpEn, Op, Op, Op, Op, opcode_len, u8, u8, u8, modrm_ext, Mode };
|
||||
|
||||
// TODO move this into a .zon file when Zig is capable of importing .zon files
|
||||
// zig fmt: off
|
||||
pub const table = &[_]Entry{
|
||||
// General-purpose
|
||||
.{ .adc, .zi, .al, .imm8, .none, .none, 1, 0x14, 0x00, 0x00, 0, .none },
|
||||
.{ .adc, .zi, .ax, .imm16, .none, .none, 1, 0x15, 0x00, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
.{ .adc, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 2, .none },
|
||||
.{ .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 },
|
||||
|
||||
.{ .add, .zi, .al, .imm8, .none, .none, 1, 0x04, 0x00, 0x00, 0, .none },
|
||||
.{ .add, .zi, .ax, .imm16, .none, .none, 1, 0x05, 0x00, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
.{ .add, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
|
||||
.{ .@"and", .zi, .al, .imm8, .none, .none, 1, 0x24, 0x00, 0x00, 0, .none },
|
||||
.{ .@"and", .zi, .ax, .imm16, .none, .none, 1, 0x25, 0x00, 0x00, 0, .none },
|
||||
.{ .@"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 },
|
||||
.{ .@"and", .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 4, .none },
|
||||
.{ .@"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 },
|
||||
|
||||
// This is M encoding according to Intel, but D makes more sense here.
|
||||
.{ .call, .d, .rel32, .none, .none, .none, 1, 0xe8, 0x00, 0x00, 0, .none },
|
||||
.{ .call, .m, .rm64, .none, .none, .none, 1, 0xff, 0x00, 0x00, 2, .none },
|
||||
|
||||
.{ .cbw, .np, .o16, .none, .none, .none, 1, 0x98, 0x00, 0x00, 0, .none },
|
||||
.{ .cwde, .np, .o32, .none, .none, .none, 1, 0x98, 0x00, 0x00, 0, .none },
|
||||
.{ .cdqe, .np, .o64, .none, .none, .none, 1, 0x98, 0x00, 0x00, 0, .long },
|
||||
|
||||
.{ .cwd, .np, .o16, .none, .none, .none, 1, 0x99, 0x00, 0x00, 0, .none },
|
||||
.{ .cdq, .np, .o32, .none, .none, .none, 1, 0x99, 0x00, 0x00, 0, .none },
|
||||
.{ .cqo, .np, .o64, .none, .none, .none, 1, 0x99, 0x00, 0x00, 0, .long },
|
||||
|
||||
.{ .cmova, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .none },
|
||||
.{ .cmova, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .none },
|
||||
.{ .cmova, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .long },
|
||||
.{ .cmovae, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none },
|
||||
.{ .cmovae, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none },
|
||||
.{ .cmovae, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .long },
|
||||
.{ .cmovb, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none },
|
||||
.{ .cmovb, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none },
|
||||
.{ .cmovb, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .long },
|
||||
.{ .cmovbe, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .none },
|
||||
.{ .cmovbe, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .none },
|
||||
.{ .cmovbe, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .long },
|
||||
.{ .cmovc, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none },
|
||||
.{ .cmovc, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none },
|
||||
.{ .cmovc, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .long },
|
||||
.{ .cmove, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none },
|
||||
.{ .cmove, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none },
|
||||
.{ .cmove, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .long },
|
||||
.{ .cmovg, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .none },
|
||||
.{ .cmovg, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .none },
|
||||
.{ .cmovg, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .long },
|
||||
.{ .cmovge, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .none },
|
||||
.{ .cmovge, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .none },
|
||||
.{ .cmovge, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .long },
|
||||
.{ .cmovl, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .none },
|
||||
.{ .cmovl, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .none },
|
||||
.{ .cmovl, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .long },
|
||||
.{ .cmovle, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .none },
|
||||
.{ .cmovle, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .none },
|
||||
.{ .cmovle, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .long },
|
||||
.{ .cmovna, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .none },
|
||||
.{ .cmovna, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .none },
|
||||
.{ .cmovna, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x46, 0x00, 0, .long },
|
||||
.{ .cmovnae, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none },
|
||||
.{ .cmovnae, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .none },
|
||||
.{ .cmovnae, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x42, 0x00, 0, .long },
|
||||
.{ .cmovnb, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none },
|
||||
.{ .cmovnb, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none },
|
||||
.{ .cmovnb, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .long },
|
||||
.{ .cmovnbe, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .none },
|
||||
.{ .cmovnbe, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .none },
|
||||
.{ .cmovnbe, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x47, 0x00, 0, .long },
|
||||
.{ .cmovnc, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none },
|
||||
.{ .cmovnc, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .none },
|
||||
.{ .cmovnc, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x43, 0x00, 0, .long },
|
||||
.{ .cmovne, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .none },
|
||||
.{ .cmovne, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .none },
|
||||
.{ .cmovne, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .long },
|
||||
.{ .cmovng, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .none },
|
||||
.{ .cmovng, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .none },
|
||||
.{ .cmovng, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4e, 0x00, 0, .long },
|
||||
.{ .cmovnge, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .none },
|
||||
.{ .cmovnge, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .none },
|
||||
.{ .cmovnge, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4c, 0x00, 0, .long },
|
||||
.{ .cmovnl, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .none },
|
||||
.{ .cmovnl, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .none },
|
||||
.{ .cmovnl, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4d, 0x00, 0, .long },
|
||||
.{ .cmovnle, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .none },
|
||||
.{ .cmovnle, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .none },
|
||||
.{ .cmovnle, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4f, 0x00, 0, .long },
|
||||
.{ .cmovno, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x41, 0x00, 0, .none },
|
||||
.{ .cmovno, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x41, 0x00, 0, .none },
|
||||
.{ .cmovno, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x41, 0x00, 0, .long },
|
||||
.{ .cmovnp, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .none },
|
||||
.{ .cmovnp, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .none },
|
||||
.{ .cmovnp, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .long },
|
||||
.{ .cmovns, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x49, 0x00, 0, .none },
|
||||
.{ .cmovns, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x49, 0x00, 0, .none },
|
||||
.{ .cmovns, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x49, 0x00, 0, .long },
|
||||
.{ .cmovnz, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .none },
|
||||
.{ .cmovnz, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .none },
|
||||
.{ .cmovnz, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x45, 0x00, 0, .long },
|
||||
.{ .cmovo, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x40, 0x00, 0, .none },
|
||||
.{ .cmovo, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x40, 0x00, 0, .none },
|
||||
.{ .cmovo, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x40, 0x00, 0, .long },
|
||||
.{ .cmovp, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .none },
|
||||
.{ .cmovp, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .none },
|
||||
.{ .cmovp, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .long },
|
||||
.{ .cmovpe, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .none },
|
||||
.{ .cmovpe, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .none },
|
||||
.{ .cmovpe, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4a, 0x00, 0, .long },
|
||||
.{ .cmovpo, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .none },
|
||||
.{ .cmovpo, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .none },
|
||||
.{ .cmovpo, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x4b, 0x00, 0, .long },
|
||||
.{ .cmovs, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x48, 0x00, 0, .none },
|
||||
.{ .cmovs, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x48, 0x00, 0, .none },
|
||||
.{ .cmovs, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x48, 0x00, 0, .long },
|
||||
.{ .cmovz, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none },
|
||||
.{ .cmovz, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .none },
|
||||
.{ .cmovz, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0x44, 0x00, 0, .long },
|
||||
|
||||
.{ .cmp, .zi, .al, .imm8, .none, .none, 1, 0x3c, 0x00, 0x00, 0, .none },
|
||||
.{ .cmp, .zi, .ax, .imm16, .none, .none, 1, 0x3d, 0x00, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
.{ .cmp, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 7, .none },
|
||||
.{ .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 },
|
||||
|
||||
.{ .fisttp, .m, .m16, .none, .none, .none, 1, 0xdf, 0x00, 0x00, 1, .fpu },
|
||||
.{ .fisttp, .m, .m32, .none, .none, .none, 1, 0xdb, 0x00, 0x00, 1, .fpu },
|
||||
.{ .fisttp, .m, .m64, .none, .none, .none, 1, 0xdd, 0x00, 0x00, 1, .fpu },
|
||||
|
||||
.{ .fld, .m, .m32, .none, .none, .none, 1, 0xd9, 0x00, 0x00, 0, .fpu },
|
||||
.{ .fld, .m, .m64, .none, .none, .none, 1, 0xdd, 0x00, 0x00, 0, .fpu },
|
||||
.{ .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 },
|
||||
.{ .imul, .rm, .r16, .rm16, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },
|
||||
.{ .imul, .rm, .r32, .rm32, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .none },
|
||||
.{ .imul, .rm, .r64, .rm64, .none, .none, 2, 0x0f, 0xaf, 0x00, 0, .long },
|
||||
.{ .imul, .rmi, .r16, .rm16, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .none },
|
||||
.{ .imul, .rmi, .r32, .rm32, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .none },
|
||||
.{ .imul, .rmi, .r64, .rm64, .imm8s, .none, 1, 0x6b, 0x00, 0x00, 0, .long },
|
||||
.{ .imul, .rmi, .r16, .rm16, .imm16, .none, 1, 0x69, 0x00, 0x00, 0, .none },
|
||||
.{ .imul, .rmi, .r32, .rm32, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .none },
|
||||
.{ .imul, .rmi, .r64, .rm64, .imm32, .none, 1, 0x69, 0x00, 0x00, 0, .long },
|
||||
|
||||
.{ .int3, .np, .none, .none, .none, .none, 1, 0xcc, 0x00, 0x00, 0, .none },
|
||||
|
||||
.{ .ja, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x87, 0x00, 0, .none },
|
||||
.{ .jae, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x83, 0x00, 0, .none },
|
||||
.{ .jb, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x82, 0x00, 0, .none },
|
||||
.{ .jbe, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x86, 0x00, 0, .none },
|
||||
.{ .jc, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x82, 0x00, 0, .none },
|
||||
.{ .jrcxz, .d, .rel32, .none, .none, .none, 1, 0xe3, 0x00, 0x00, 0, .none },
|
||||
.{ .je, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x84, 0x00, 0, .none },
|
||||
.{ .jg, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8f, 0x00, 0, .none },
|
||||
.{ .jge, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8d, 0x00, 0, .none },
|
||||
.{ .jl, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8c, 0x00, 0, .none },
|
||||
.{ .jle, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8e, 0x00, 0, .none },
|
||||
.{ .jna, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x86, 0x00, 0, .none },
|
||||
.{ .jnae, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x82, 0x00, 0, .none },
|
||||
.{ .jnb, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x83, 0x00, 0, .none },
|
||||
.{ .jnbe, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x87, 0x00, 0, .none },
|
||||
.{ .jnc, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x83, 0x00, 0, .none },
|
||||
.{ .jne, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x85, 0x00, 0, .none },
|
||||
.{ .jng, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8e, 0x00, 0, .none },
|
||||
.{ .jnge, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8c, 0x00, 0, .none },
|
||||
.{ .jnl, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8d, 0x00, 0, .none },
|
||||
.{ .jnle, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8f, 0x00, 0, .none },
|
||||
.{ .jno, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x81, 0x00, 0, .none },
|
||||
.{ .jnp, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8b, 0x00, 0, .none },
|
||||
.{ .jns, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x89, 0x00, 0, .none },
|
||||
.{ .jnz, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x85, 0x00, 0, .none },
|
||||
.{ .jo, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x80, 0x00, 0, .none },
|
||||
.{ .jp, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8a, 0x00, 0, .none },
|
||||
.{ .jpe, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8a, 0x00, 0, .none },
|
||||
.{ .jpo, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x8b, 0x00, 0, .none },
|
||||
.{ .js, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x88, 0x00, 0, .none },
|
||||
.{ .jz, .d, .rel32, .none, .none, .none, 2, 0x0f, 0x84, 0x00, 0, .none },
|
||||
|
||||
.{ .jmp, .d, .rel32, .none, .none, .none, 1, 0xe9, 0x00, 0x00, 0, .none },
|
||||
.{ .jmp, .m, .rm64, .none, .none, .none, 1, 0xff, 0x00, 0x00, 4, .none },
|
||||
|
||||
.{ .lea, .rm, .r16, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .none },
|
||||
.{ .lea, .rm, .r32, .m, .none, .none, 1, 0x8d, 0x00, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
.{ .mov, .mr, .rm16, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .none },
|
||||
.{ .mov, .mr, .rm64, .sreg, .none, .none, 1, 0x8c, 0x00, 0x00, 0, .long },
|
||||
.{ .mov, .rm, .sreg, .rm16, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .none },
|
||||
.{ .mov, .rm, .sreg, .rm64, .none, .none, 1, 0x8e, 0x00, 0x00, 0, .long },
|
||||
.{ .mov, .fd, .al, .moffs, .none, .none, 1, 0xa0, 0x00, 0x00, 0, .none },
|
||||
.{ .mov, .fd, .ax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },
|
||||
.{ .mov, .fd, .eax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .none },
|
||||
.{ .mov, .fd, .rax, .moffs, .none, .none, 1, 0xa1, 0x00, 0x00, 0, .long },
|
||||
.{ .mov, .td, .moffs, .al, .none, .none, 1, 0xa2, 0x00, 0x00, 0, .none },
|
||||
.{ .mov, .td, .moffs, .ax, .none, .none, 1, 0xa3, 0x00, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
|
||||
// This instruction is discouraged.
|
||||
.{ .movsxd, .rm, .r32, .rm32, .none, .none, 1, 0x63, 0x00, 0x00, 0, .none },
|
||||
.{ .movsxd, .rm, .r64, .rm32, .none, .none, 1, 0x63, 0x00, 0x00, 0, .long },
|
||||
|
||||
.{ .movzx, .rm, .r16, .rm8, .none, .none, 2, 0x0f, 0xb6, 0x00, 0, .none },
|
||||
.{ .movzx, .rm, .r32, .rm8, .none, .none, 2, 0x0f, 0xb6, 0x00, 0, .none },
|
||||
.{ .movzx, .rm, .r64, .rm8, .none, .none, 2, 0x0f, 0xb6, 0x00, 0, .long },
|
||||
.{ .movzx, .rm, .r32, .rm16, .none, .none, 2, 0x0f, 0xb7, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
|
||||
.{ .nop, .np, .none, .none, .none, .none, 1, 0x90, 0x00, 0x00, 0, .none },
|
||||
|
||||
.{ .@"or", .zi, .al, .imm8, .none, .none, 1, 0x0c, 0x00, 0x00, 0, .none },
|
||||
.{ .@"or", .zi, .ax, .imm16, .none, .none, 1, 0x0d, 0x00, 0x00, 0, .none },
|
||||
.{ .@"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 },
|
||||
.{ .@"or", .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 1, .none },
|
||||
.{ .@"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 },
|
||||
|
||||
.{ .pop, .o, .r16, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none },
|
||||
.{ .pop, .o, .r64, .none, .none, .none, 1, 0x58, 0x00, 0x00, 0, .none },
|
||||
.{ .pop, .m, .rm16, .none, .none, .none, 1, 0x8f, 0x00, 0x00, 0, .none },
|
||||
.{ .pop, .m, .rm64, .none, .none, .none, 1, 0x8f, 0x00, 0x00, 0, .none },
|
||||
|
||||
.{ .push, .o, .r16, .none, .none, .none, 1, 0x50, 0x00, 0x00, 0, .none },
|
||||
.{ .push, .o, .r64, .none, .none, .none, 1, 0x50, 0x00, 0x00, 0, .none },
|
||||
.{ .push, .m, .rm16, .none, .none, .none, 1, 0xff, 0x00, 0x00, 6, .none },
|
||||
.{ .push, .m, .rm64, .none, .none, .none, 1, 0xff, 0x00, 0x00, 6, .none },
|
||||
.{ .push, .i, .imm8, .none, .none, .none, 1, 0x6a, 0x00, 0x00, 0, .none },
|
||||
.{ .push, .i, .imm16, .none, .none, .none, 1, 0x68, 0x00, 0x00, 0, .none },
|
||||
.{ .push, .i, .imm32, .none, .none, .none, 1, 0x68, 0x00, 0x00, 0, .none },
|
||||
|
||||
.{ .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 },
|
||||
|
||||
.{ .sbb, .zi, .al, .imm8, .none, .none, 1, 0x1c, 0x00, 0x00, 0, .none },
|
||||
.{ .sbb, .zi, .ax, .imm16, .none, .none, 1, 0x1d, 0x00, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
.{ .sbb, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 3, .none },
|
||||
.{ .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 },
|
||||
|
||||
.{ .sub, .zi, .al, .imm8, .none, .none, 1, 0x2c, 0x00, 0x00, 0, .none },
|
||||
.{ .sub, .zi, .ax, .imm16, .none, .none, 1, 0x2d, 0x00, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
.{ .sub, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 5, .none },
|
||||
.{ .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 },
|
||||
|
||||
.{ .syscall, .np, .none, .none, .none, .none, 2, 0x0f, 0x05, 0x00, 0, .none },
|
||||
|
||||
.{ .@"test", .zi, .al, .imm8, .none, .none, 1, 0xa8, 0x00, 0x00, 0, .none },
|
||||
.{ .@"test", .zi, .ax, .imm16, .none, .none, 1, 0xa9, 0x00, 0x00, 0, .none },
|
||||
.{ .@"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 },
|
||||
|
||||
.{ .ud2, .np, .none, .none, .none, .none, 2, 0x0f, 0x0b, 0x00, 0, .none },
|
||||
|
||||
.{ .xor, .zi, .al, .imm8, .none, .none, 1, 0x34, 0x00, 0x00, 0, .none },
|
||||
.{ .xor, .zi, .ax, .imm16, .none, .none, 1, 0x35, 0x00, 0x00, 0, .none },
|
||||
.{ .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 },
|
||||
.{ .xor, .mi, .rm16, .imm8s, .none, .none, 1, 0x83, 0x00, 0x00, 6, .none },
|
||||
.{ .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 },
|
||||
|
||||
// SSE
|
||||
.{ .addss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x58, 0, .sse },
|
||||
|
||||
.{ .cmpss, .rmi, .xmm, .xmm_m32, .imm8, .none, 3, 0xf3, 0x0f, 0xc2, 0, .sse },
|
||||
|
||||
.{ .movss, .rm, .xmm, .xmm_m32, .none, .none, 3, 0xf3, 0x0f, 0x10, 0, .sse },
|
||||
.{ .movss, .mr, .xmm_m32, .xmm, .none, .none, 3, 0xf3, 0x0f, 0x11, 0, .sse },
|
||||
|
||||
.{ .ucomiss, .rm, .xmm, .xmm_m32, .none, .none, 2, 0x0f, 0x2e, 0x00, 0, .sse },
|
||||
|
||||
// SSE2
|
||||
.{ .addsd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf2, 0x0f, 0x58, 0, .sse2 },
|
||||
|
||||
.{ .cmpsd, .rmi, .xmm, .xmm_m64, .imm8, .none, 3, 0xf2, 0x0f, 0xc2, 0, .sse2 },
|
||||
|
||||
.{ .movq, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf3, 0x0f, 0x7e, 0, .sse2 },
|
||||
.{ .movq, .mr, .xmm_m64, .xmm, .none, .none, 3, 0x66, 0x0f, 0xd6, 0, .sse2 },
|
||||
|
||||
.{ .movsd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0xf2, 0x0f, 0x10, 0, .sse2 },
|
||||
.{ .movsd, .mr, .xmm_m64, .xmm, .none, .none, 3, 0xf2, 0x0f, 0x11, 0, .sse2 },
|
||||
|
||||
.{ .ucomisd, .rm, .xmm, .xmm_m64, .none, .none, 3, 0x66, 0x0f, 0x2e, 0, .sse2 },
|
||||
};
|
||||
// zig fmt: on
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user