diff --git a/Iced/Intel/Instruction.Create.cs b/Iced/Intel/Instruction.Create.cs
new file mode 100644
index 000000000..57905290a
--- /dev/null
+++ b/Iced/Intel/Instruction.Create.cs
@@ -0,0 +1,1383 @@
+/*
+ Copyright (C) 2018 de4dot@gmail.com
+
+ This file is part of Iced.
+
+ Iced is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Iced is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with Iced. If not, see .
+*/
+
+#if !NO_ENCODER
+using System;
+using System.Diagnostics;
+
+namespace Iced.Intel {
+ partial struct Instruction {
+ static OpKind GetImmediateOpKind(Code code, int operand) {
+ var handlers = EncoderInternal.OpCodeHandlers.Handlers;
+ if ((uint)code >= (uint)handlers.Length)
+ throw new ArgumentOutOfRangeException(nameof(code));
+ var operands = handlers[(int)code].Operands;
+ if ((uint)operand >= (uint)operands.Length)
+ throw new ArgumentOutOfRangeException(nameof(operand), $"{code} doesn't have at least {operand + 1} operands");
+ var opKind = operands[operand].GetImmediateOpKind();
+ if (opKind == (OpKind)(-1))
+ throw new ArgumentException($"{code}'s op{operand} isn't an immediate operand");
+ return opKind;
+ }
+
+ static OpKind GetNearBranchOpKind(Code code, int operand) {
+ var handlers = EncoderInternal.OpCodeHandlers.Handlers;
+ if ((uint)code >= (uint)handlers.Length)
+ throw new ArgumentOutOfRangeException(nameof(code));
+ var operands = handlers[(int)code].Operands;
+ if ((uint)operand >= (uint)operands.Length)
+ throw new ArgumentOutOfRangeException(nameof(operand), $"{code} doesn't have at least {operand + 1} operands");
+ var opKind = operands[operand].GetNearBranchOpKind();
+ if (opKind == (OpKind)(-1))
+ throw new ArgumentException($"{code}'s op{operand} isn't a near branch operand");
+ return opKind;
+ }
+
+ static OpKind GetFarBranchOpKind(Code code, int operand) {
+ var handlers = EncoderInternal.OpCodeHandlers.Handlers;
+ if ((uint)code >= (uint)handlers.Length)
+ throw new ArgumentOutOfRangeException(nameof(code));
+ var operands = handlers[(int)code].Operands;
+ if ((uint)operand >= (uint)operands.Length)
+ throw new ArgumentOutOfRangeException(nameof(operand), $"{code} doesn't have at least {operand + 1} operands");
+ var opKind = operands[operand].GetFarBranchOpKind();
+ if (opKind == (OpKind)(-1))
+ throw new ArgumentException($"{code}'s op{operand} isn't a far branch operand");
+ return opKind;
+ }
+
+ ///
+ /// Creates a new with no operands
+ ///
+ /// Code value
+ ///
+ public static Instruction Create(Code code) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(instruction.OpCount == 0);
+ return instruction;
+ }
+
+ ///
+ /// Creates a new near/short branch
+ ///
+ /// Code value
+ /// Target address
+ ///
+ public static Instruction CreateBranch(Code code, ulong target) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.Op0Kind = GetNearBranchOpKind(code, 0);
+ instruction.NearBranch64 = target;
+
+ Debug.Assert(instruction.OpCount == 1);
+ return instruction;
+ }
+
+ ///
+ /// Creates a new far branch
+ ///
+ /// Code value
+ /// Selector/segment value
+ /// Offset
+ ///
+ public static Instruction CreateBranch(Code code, ushort selector, uint offset) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.Op0Kind = GetFarBranchOpKind(code, 0);
+ instruction.FarBranchSelector = selector;
+ instruction.FarBranch32 = offset;
+
+ Debug.Assert(instruction.OpCount == 1);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction with a 64-bit memory offset as the second operand, eg. 'mov al,[123456789ABCDEF0]'
+ ///
+ /// Code value
+ /// Register (al, ax, eax, rax)
+ /// 64-bit address
+ /// Segment override or
+ ///
+ public static Instruction CreateMemory64(Code code, Register register, ulong address, Register prefixSegment = Register.None) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ instruction.InternalOp1Kind = OpKind.Memory64;
+ instruction.MemoryAddress64 = address;
+ instruction.InternalSetMemoryDisplSize(4);
+ instruction.PrefixSegment = prefixSegment;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction with a 64-bit memory offset as the first operand, eg. 'mov [123456789ABCDEF0],al'
+ ///
+ /// Code value
+ /// 64-bit address
+ /// Register (al, ax, eax, rax)
+ /// Segment override or
+ ///
+ public static Instruction CreateMemory64(Code code, ulong address, Register register, Register prefixSegment = Register.None) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.InternalOp0Kind = OpKind.Memory64;
+ instruction.MemoryAddress64 = address;
+ instruction.InternalSetMemoryDisplSize(4);
+ instruction.PrefixSegment = prefixSegment;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ ///
+ public static Instruction Create(Code code, Register register) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ Debug.Assert(instruction.OpCount == 1);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.InternalOp0Kind = GetImmediateOpKind(code, 0);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 1);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, uint immediate) =>
+ Create(code, (int)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Memory operand
+ ///
+ public static Instruction Create(Code code, in MemoryOperand memory) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.InternalOp0Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(instruction.OpCount == 1);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ var opKind = GetImmediateOpKind(code, 1);
+ instruction.InternalOp1Kind = opKind;
+ if (opKind == OpKind.Immediate64)
+ instruction.Immediate64 = (ulong)immediate;
+ else
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register, uint immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ var opKind = GetImmediateOpKind(code, 1);
+ instruction.InternalOp1Kind = opKind;
+ if (opKind == OpKind.Immediate64)
+ instruction.Immediate64 = immediate;
+ else
+ instruction.Immediate32 = immediate;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction with a 64-bit immediate value
+ ///
+ /// Code value
+ /// Register
+ /// 64-bit immediate
+ ///
+ public static Instruction Create(Code code, Register register, long immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ instruction.InternalOp1Kind = OpKind.Immediate64;
+ instruction.Immediate64 = (ulong)immediate;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction with a 64-bit immediate value
+ ///
+ /// Code value
+ /// Register
+ /// 64-bit immediate
+ ///
+ public static Instruction Create(Code code, Register register, ulong immediate) =>
+ Create(code, register, (long)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register (eg. dx, al, ax, eax, rax)
+ /// si, esi, or rsi
+ /// Segment override or
+ ///
+ public static Instruction CreateString_Reg_SegRSI(Code code, Register register, Register rSI, Register prefixSegment = Register.None) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ if (rSI == Register.RSI)
+ instruction.InternalOp1Kind = OpKind.MemorySegRSI;
+ else if (rSI == Register.ESI)
+ instruction.InternalOp1Kind = OpKind.MemorySegESI;
+ else if (rSI == Register.SI)
+ instruction.InternalOp1Kind = OpKind.MemorySegSI;
+ else
+ throw new ArgumentOutOfRangeException(nameof(rSI));
+
+ instruction.PrefixSegment = prefixSegment;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register (eg. al, ax, eax, rax)
+ /// di, edi, or rdi
+ ///
+ public static Instruction CreateString_Reg_ESRDI(Code code, Register register, Register rDI) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ if (rDI == Register.RDI)
+ instruction.InternalOp1Kind = OpKind.MemoryESRDI;
+ else if (rDI == Register.EDI)
+ instruction.InternalOp1Kind = OpKind.MemoryESEDI;
+ else if (rDI == Register.DI)
+ instruction.InternalOp1Kind = OpKind.MemoryESDI;
+ else
+ throw new ArgumentOutOfRangeException(nameof(rDI));
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Memory operand
+ ///
+ public static Instruction Create(Code code, Register register, in MemoryOperand memory) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ instruction.InternalOp1Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Immediate
+ /// Register
+ ///
+ public static Instruction Create(Code code, int immediate, Register register) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.InternalOp0Kind = GetImmediateOpKind(code, 0);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Immediate
+ /// Register
+ ///
+ public static Instruction Create(Code code, uint immediate, Register register) =>
+ Create(code, (int)immediate, register);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Immediate
+ /// Second immediate
+ ///
+ public static Instruction Create(Code code, int immediate, byte immediate2) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.InternalOp0Kind = GetImmediateOpKind(code, 0);
+ instruction.Immediate32 = (uint)immediate;
+
+ instruction.InternalOp1Kind = OpKind.Immediate8_2nd;
+ instruction.Immediate8_2nd = immediate2;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Immediate
+ /// Second immediate
+ ///
+ public static Instruction Create(Code code, uint immediate, byte immediate2) =>
+ Create(code, (int)immediate, immediate2);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// si, esi, or rsi
+ /// di, edi, or rdi
+ /// Segment override or
+ ///
+ public static Instruction CreateString_SegRSI_ESRDI(Code code, Register rSI, Register rDI, Register prefixSegment = Register.None) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ if (rSI == Register.RSI)
+ instruction.InternalOp0Kind = OpKind.MemorySegRSI;
+ else if (rSI == Register.ESI)
+ instruction.InternalOp0Kind = OpKind.MemorySegESI;
+ else if (rSI == Register.SI)
+ instruction.InternalOp0Kind = OpKind.MemorySegSI;
+ else
+ throw new ArgumentOutOfRangeException(nameof(rSI));
+
+ if (rDI == Register.RDI)
+ instruction.InternalOp1Kind = OpKind.MemoryESRDI;
+ else if (rDI == Register.EDI)
+ instruction.InternalOp1Kind = OpKind.MemoryESEDI;
+ else if (rDI == Register.DI)
+ instruction.InternalOp1Kind = OpKind.MemoryESDI;
+ else
+ throw new ArgumentOutOfRangeException(nameof(rDI));
+
+ instruction.PrefixSegment = prefixSegment;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// di, edi, or rdi
+ /// Register (eg. dx, al, ax, eax, rax)
+ ///
+ public static Instruction CreateString_ESRDI_Reg(Code code, Register rDI, Register register) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ if (rDI == Register.RDI)
+ instruction.InternalOp0Kind = OpKind.MemoryESRDI;
+ else if (rDI == Register.EDI)
+ instruction.InternalOp0Kind = OpKind.MemoryESEDI;
+ else if (rDI == Register.DI)
+ instruction.InternalOp0Kind = OpKind.MemoryESDI;
+ else
+ throw new ArgumentOutOfRangeException(nameof(rDI));
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// di, edi, or rdi
+ /// si, esi, or rsi
+ /// Segment override or
+ ///
+ public static Instruction CreateString_ESRDI_SegRSI(Code code, Register rDI, Register rSI, Register prefixSegment = Register.None) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ if (rDI == Register.RDI)
+ instruction.InternalOp0Kind = OpKind.MemoryESRDI;
+ else if (rDI == Register.EDI)
+ instruction.InternalOp0Kind = OpKind.MemoryESEDI;
+ else if (rDI == Register.DI)
+ instruction.InternalOp0Kind = OpKind.MemoryESDI;
+ else
+ throw new ArgumentOutOfRangeException(nameof(rDI));
+
+ if (rSI == Register.RSI)
+ instruction.InternalOp1Kind = OpKind.MemorySegRSI;
+ else if (rSI == Register.ESI)
+ instruction.InternalOp1Kind = OpKind.MemorySegESI;
+ else if (rSI == Register.SI)
+ instruction.InternalOp1Kind = OpKind.MemorySegSI;
+ else
+ throw new ArgumentOutOfRangeException(nameof(rSI));
+
+ instruction.PrefixSegment = prefixSegment;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Memory operand
+ /// Register
+ ///
+ public static Instruction Create(Code code, in MemoryOperand memory, Register register) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.InternalOp0Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Memory operand
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, in MemoryOperand memory, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.InternalOp0Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ instruction.InternalOp1Kind = GetImmediateOpKind(code, 1);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 2);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Memory operand
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, in MemoryOperand memory, uint immediate) =>
+ Create(code, memory, (int)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Register
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, Register register3) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp2Kind = OpKind.Register;
+ instruction.InternalOp2Register = register3;
+
+ Debug.Assert(instruction.OpCount == 3);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ instruction.InternalOp2Kind = GetImmediateOpKind(code, 2);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 3);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, uint immediate) =>
+ Create(code, register1, register2, (int)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Memory operand
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ instruction.InternalOp2Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(instruction.OpCount == 3);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Immediate
+ /// Second immediate
+ ///
+ public static Instruction Create(Code code, Register register, int immediate, byte immediate2) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ instruction.InternalOp1Kind = GetImmediateOpKind(code, 1);
+ instruction.Immediate32 = (uint)immediate;
+
+ instruction.InternalOp2Kind = OpKind.Immediate8_2nd;
+ instruction.Immediate8_2nd = immediate2;
+
+ Debug.Assert(instruction.OpCount == 3);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Immediate
+ /// Second immediate
+ ///
+ public static Instruction Create(Code code, Register register, uint immediate, byte immediate2) =>
+ Create(code, register, (int)immediate, immediate2);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Memory operand
+ /// Register
+ ///
+ public static Instruction Create(Code code, Register register1, in MemoryOperand memory, Register register2) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ instruction.InternalOp1Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp2Kind = OpKind.Register;
+ instruction.InternalOp2Register = register2;
+
+ Debug.Assert(instruction.OpCount == 3);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Memory operand
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register, in MemoryOperand memory, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register;
+
+ instruction.InternalOp1Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ instruction.InternalOp2Kind = GetImmediateOpKind(code, 2);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 3);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Memory operand
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register, in MemoryOperand memory, uint immediate) =>
+ Create(code, register, memory, (int)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// di, edi, or rdi
+ /// Register
+ /// Register
+ /// Segment override or
+ ///
+ public static Instruction CreateMaskmov_SegRDI_Reg_Reg(Code code, Register rDI, Register register1, Register register2, Register prefixSegment = Register.None) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ if (rDI == Register.RDI)
+ instruction.InternalOp0Kind = OpKind.MemorySegRDI;
+ else if (rDI == Register.EDI)
+ instruction.InternalOp0Kind = OpKind.MemorySegEDI;
+ else if (rDI == Register.DI)
+ instruction.InternalOp0Kind = OpKind.MemorySegDI;
+ else
+ throw new ArgumentOutOfRangeException(nameof(rDI));
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp2Kind = OpKind.Register;
+ instruction.InternalOp2Register = register2;
+
+ instruction.PrefixSegment = prefixSegment;
+
+ Debug.Assert(instruction.OpCount == 3);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Memory operand
+ /// Register
+ /// Register
+ ///
+ public static Instruction Create(Code code, in MemoryOperand memory, Register register1, Register register2) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.InternalOp0Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp2Kind = OpKind.Register;
+ instruction.InternalOp2Register = register2;
+
+ Debug.Assert(instruction.OpCount == 3);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Memory operand
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, in MemoryOperand memory, Register register, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ instruction.InternalOp0Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register;
+
+ instruction.InternalOp2Kind = GetImmediateOpKind(code, 2);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 3);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Memory operand
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, in MemoryOperand memory, Register register, uint immediate) =>
+ Create(code, memory, register, (int)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Register
+ /// Register
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, Register register3, Register register4) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp2Kind = OpKind.Register;
+ instruction.InternalOp2Register = register3;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp3Kind = OpKind.Register;
+ instruction.InternalOp3Register = register4;
+
+ Debug.Assert(instruction.OpCount == 4);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, Register register3, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp2Kind = OpKind.Register;
+ instruction.InternalOp2Register = register3;
+
+ instruction.InternalOp3Kind = GetImmediateOpKind(code, 3);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 4);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, Register register3, uint immediate) =>
+ Create(code, register1, register2, register3, (int)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Register
+ /// Memory operand
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, Register register3, in MemoryOperand memory) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp2Kind = OpKind.Register;
+ instruction.InternalOp2Register = register3;
+
+ instruction.InternalOp3Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(instruction.OpCount == 4);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Immediate
+ /// Second immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, int immediate, byte immediate2) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ instruction.InternalOp2Kind = GetImmediateOpKind(code, 2);
+ instruction.Immediate32 = (uint)immediate;
+
+ instruction.InternalOp3Kind = OpKind.Immediate8_2nd;
+ instruction.Immediate8_2nd = immediate2;
+
+ Debug.Assert(instruction.OpCount == 4);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Immediate
+ /// Second immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, uint immediate, byte immediate2) =>
+ Create(code, register1, register2, (int)immediate, immediate2);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Memory operand
+ /// Register
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, Register register3) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ instruction.InternalOp2Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp3Kind = OpKind.Register;
+ instruction.InternalOp3Register = register3;
+
+ Debug.Assert(instruction.OpCount == 4);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Memory operand
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ instruction.InternalOp2Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ instruction.InternalOp3Kind = GetImmediateOpKind(code, 3);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 4);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Memory operand
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, uint immediate) =>
+ Create(code, register1, register2, memory, (int)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Register
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, Register register3, Register register4, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp2Kind = OpKind.Register;
+ instruction.InternalOp2Register = register3;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp3Kind = OpKind.Register;
+ instruction.InternalOp3Register = register4;
+
+ instruction.InternalOp4Kind = GetImmediateOpKind(code, 4);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 5);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Register
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, Register register3, Register register4, uint immediate) =>
+ Create(code, register1, register2, register3, register4, (int)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Register
+ /// Memory operand
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, Register register3, in MemoryOperand memory, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp2Kind = OpKind.Register;
+ instruction.InternalOp2Register = register3;
+
+ instruction.InternalOp3Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ instruction.InternalOp4Kind = GetImmediateOpKind(code, 4);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 5);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Register
+ /// Memory operand
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, Register register3, in MemoryOperand memory, uint immediate) =>
+ Create(code, register1, register2, register3, memory, (int)immediate);
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Memory operand
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, Register register3, int immediate) {
+ Instruction instruction = default;
+ instruction.InternalCode = code;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp0Kind = OpKind.Register;
+ instruction.InternalOp0Register = register1;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp1Kind = OpKind.Register;
+ instruction.InternalOp1Register = register2;
+
+ instruction.InternalOp2Kind = OpKind.Memory;
+ instruction.InternalMemoryBase = memory.Base;
+ instruction.InternalMemoryIndex = memory.Index;
+ instruction.MemoryIndexScale = memory.Scale;
+ instruction.MemoryDisplSize = memory.DisplSize;
+ instruction.MemoryDisplacement = (uint)memory.Displacement;
+ instruction.IsBroadcast = memory.IsBroadcast;
+ instruction.PrefixSegment = memory.PrefixSegment;
+
+ Debug.Assert(OpKind.Register == 0);
+ //instruction.InternalOp3Kind = OpKind.Register;
+ instruction.InternalOp3Register = register3;
+
+ instruction.InternalOp4Kind = GetImmediateOpKind(code, 4);
+ instruction.Immediate32 = (uint)immediate;
+
+ Debug.Assert(instruction.OpCount == 5);
+ return instruction;
+ }
+
+ ///
+ /// Creates an instruction
+ ///
+ /// Code value
+ /// Register
+ /// Register
+ /// Memory operand
+ /// Register
+ /// Immediate
+ ///
+ public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, Register register3, uint immediate) =>
+ Create(code, register1, register2, memory, register3, (int)immediate);
+ }
+}
+#endif
diff --git a/Iced/Intel/Instruction.Info.cs b/Iced/Intel/Instruction.Info.cs
new file mode 100644
index 000000000..f8678f008
--- /dev/null
+++ b/Iced/Intel/Instruction.Info.cs
@@ -0,0 +1,359 @@
+/*
+ Copyright (C) 2018 de4dot@gmail.com
+
+ This file is part of Iced.
+
+ Iced is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Iced is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with Iced. If not, see .
+*/
+
+#if !NO_INSTR_INFO
+using System.Diagnostics;
+
+namespace Iced.Intel {
+ partial struct Instruction {
+ ///
+ /// Gets the number of bytes added to SP/ESP/RSP or 0 if it's not an instruction that pushes or pops data. This method
+ /// assumes the instruction doesn't change privilege (eg. iret/d/q). If it's the leave instruction, this method returns 0.
+ ///
+ ///
+ public int StackPointerIncrement {
+ get {
+ switch (Code) {
+ case Code.Pushw_ES:
+ case Code.Pushw_CS:
+ case Code.Pushw_SS:
+ case Code.Pushw_DS:
+ case Code.Push_r16:
+ case Code.Push_imm16:
+ case Code.Pushw_imm8:
+ case Code.Pushfw:
+ case Code.Push_rm16:
+ case Code.Pushw_FS:
+ case Code.Pushw_GS:
+ return -2;
+
+ case Code.Pushd_ES:
+ case Code.Pushd_CS:
+ case Code.Pushd_SS:
+ case Code.Pushd_DS:
+ case Code.Push_r32:
+ case Code.Pushd_imm32:
+ case Code.Pushd_imm8:
+ case Code.Pushfd:
+ case Code.Push_rm32:
+ case Code.Pushd_FS:
+ case Code.Pushd_GS:
+ return -4;
+
+ case Code.Push_r64:
+ case Code.Pushq_imm32:
+ case Code.Pushq_imm8:
+ case Code.Pushfq:
+ case Code.Push_rm64:
+ case Code.Pushq_FS:
+ case Code.Pushq_GS:
+ return -8;
+
+ case Code.Pushaw:
+ return -2 * 8;
+
+ case Code.Pushad:
+ return -4 * 8;
+
+ case Code.Popw_ES:
+ case Code.Popw_SS:
+ case Code.Popw_DS:
+ case Code.Pop_r16:
+ case Code.Pop_rm16:
+ case Code.Popfw:
+ case Code.Popw_FS:
+ case Code.Popw_GS:
+ return 2;
+
+ case Code.Popd_ES:
+ case Code.Popd_SS:
+ case Code.Popd_DS:
+ case Code.Pop_r32:
+ case Code.Pop_rm32:
+ case Code.Popfd:
+ case Code.Popd_FS:
+ case Code.Popd_GS:
+ return 4;
+
+ case Code.Pop_r64:
+ case Code.Pop_rm64:
+ case Code.Popfq:
+ case Code.Popq_FS:
+ case Code.Popq_GS:
+ return 8;
+
+ case Code.Popaw:
+ return 2 * 8;
+
+ case Code.Popad:
+ return 4 * 8;
+
+ case Code.Call_ptr1616:
+ case Code.Call_m1616:
+ return -(2 + 2);
+
+ case Code.Call_ptr3216:
+ case Code.Call_m3216:
+ return -(4 + 4);
+
+ case Code.Call_m6416:
+ return -(8 + 8);
+
+ case Code.Call_rel16:
+ case Code.Call_rm16:
+ return -2;
+
+ case Code.Call_rel32_32:
+ case Code.Call_rm32:
+ return -4;
+
+ case Code.Call_rel32_64:
+ case Code.Call_rm64:
+ return -8;
+
+ case Code.Retnw_imm16:
+ return 2 + Immediate16;
+
+ case Code.Retnd_imm16:
+ return 4 + Immediate16;
+
+ case Code.Retnq_imm16:
+ return 8 + Immediate16;
+
+ case Code.Retnw:
+ return 2;
+
+ case Code.Retnd:
+ return 4;
+
+ case Code.Retnq:
+ return 8;
+
+ case Code.Retfw_imm16:
+ return 2 + 2 + Immediate16;
+
+ case Code.Retfd_imm16:
+ return 4 + 4 + Immediate16;
+
+ case Code.Retfq_imm16:
+ return 8 + 8 + Immediate16;
+
+ case Code.Retfw:
+ return 2 + 2;
+
+ case Code.Retfd:
+ return 4 + 4;
+
+ case Code.Retfq:
+ return 8 + 8;
+
+ case Code.Iretw:
+ if (CodeSize == CodeSize.Code64)
+ return 2 * 5;
+ return 2 * 3;
+
+ case Code.Iretd:
+ if (CodeSize == CodeSize.Code64)
+ return 4 * 5;
+ return 4 * 3;
+
+ case Code.Iretq:
+ return 8 * 5;
+
+ case Code.Enterw_imm16_imm8:
+ return -(2 + (Immediate8_2nd & 0x1F) * 2 + Immediate16);
+
+ case Code.Enterd_imm16_imm8:
+ return -(4 + (Immediate8_2nd & 0x1F) * 4 + Immediate16);
+
+ case Code.Enterq_imm16_imm8:
+ return -(8 + (Immediate8_2nd & 0x1F) * 8 + Immediate16);
+
+ case Code.Leavew:
+ case Code.Leaved:
+ case Code.Leaveq:
+ return 0;
+
+ default:
+ return 0;
+ }
+ }
+ }
+
+ ///
+ /// (This method allocates and is slower than using an .)
+ ///
+ /// Gets instruction info such as which register is read and written etc.
+ ///
+ ///
+ public InstructionInfo GetInfo() {
+ var usedRegisters = InstructionInfoInternal.SimpleList.Empty;
+ var usedMemoryLocations = InstructionInfoInternal.SimpleList.Empty;
+ return InstructionInfoFactory.Create(ref this, ref usedRegisters, ref usedMemoryLocations, InstructionInfoOptions.None);
+ }
+
+ ///
+ /// (This method allocates and is slower than using an .)
+ ///
+ /// Gets instruction info such as which register is read and written etc.
+ ///
+ /// Options
+ ///
+ public InstructionInfo GetInfo(InstructionInfoOptions options) {
+ var usedRegisters = InstructionInfoInternal.SimpleList.Empty;
+ var usedMemoryLocations = InstructionInfoInternal.SimpleList.Empty;
+ return InstructionInfoFactory.Create(ref this, ref usedRegisters, ref usedMemoryLocations, options);
+ }
+
+ ///
+ /// (This method allocates and is slower than using an .)
+ ///
+ /// Gets a struct iterator that returns all read and written registers. There are some exceptions, this method doesn't return all used registers:
+ ///
+ /// 1) If is true, or
+ ///
+ /// 2) If it's a or instruction (call, sysenter, int n etc), it can read and write any register (including RFLAGS).
+ ///
+ ///
+ public InstructionInfo.UsedRegisterIterator GetUsedRegisters() {
+ var usedRegisters = InstructionInfoInternal.SimpleList.Empty;
+ var usedMemoryLocations = InstructionInfoInternal.SimpleList.Empty;
+ return InstructionInfoFactory.Create(ref this, ref usedRegisters, ref usedMemoryLocations, InstructionInfoOptions.NoMemoryUsage).GetUsedRegisters();
+ }
+
+ ///
+ /// (This method allocates and is slower than using an .)
+ ///
+ /// Gets a struct iterator that returns all read and written memory locations
+ ///
+ ///
+ public InstructionInfo.UsedMemoryIterator GetUsedMemory() {
+ var usedRegisters = InstructionInfoInternal.SimpleList.Empty;
+ var usedMemoryLocations = InstructionInfoInternal.SimpleList.Empty;
+ return InstructionInfoFactory.Create(ref this, ref usedRegisters, ref usedMemoryLocations, InstructionInfoOptions.NoRegisterUsage).GetUsedMemory();
+ }
+
+ ///
+ /// Instruction encoding, eg. legacy, VEX, EVEX, ...
+ ///
+ public EncodingKind Encoding => Code.Encoding();
+
+ ///
+ /// CPU or CPUID feature flag
+ ///
+ public CpuidFeature CpuidFeature {
+ get {
+ var code = Code;
+ var cpuidFeature = code.CpuidFeature();
+ if (cpuidFeature == CpuidFeature.AVX && Op1Kind == OpKind.Register && (code == Code.VEX_Vbroadcastss_xmm_xmmm32 || code == Code.VEX_Vbroadcastss_ymm_xmmm32 || code == Code.VEX_Vbroadcastsd_ymm_xmmm64))
+ return CpuidFeature.AVX2;
+ return cpuidFeature;
+ }
+ }
+
+ ///
+ /// Flow control info
+ ///
+ public FlowControl FlowControl => Code.FlowControl();
+
+ ///
+ /// true if the instruction isn't available in real mode or virtual 8086 mode
+ ///
+ public bool ProtectedMode => Code.ProtectedMode();
+
+ ///
+ /// true if this is a privileged instruction
+ ///
+ public bool Privileged => Code.Privileged();
+
+ ///
+ /// true if this is an instruction that implicitly uses the stack pointer (SP/ESP/RSP), eg. call, push, pop, ret, etc.
+ /// See also
+ ///
+ public bool StackInstruction => Code.StackInstruction();
+
+ ///
+ /// true if it's an instruction that saves or restores too many registers (eg. fxrstor, xsave, etc).
+ ///
+ public bool SaveRestoreInstruction => Code.SaveRestoreInstruction();
+
+ InstructionInfoInternal.RflagsInfo GetRflagsInfo() {
+ var flags1 = InstructionInfoInternal.InfoHandlers.Data[(int)Code << 1];
+ var codeInfo = (InstructionInfoInternal.CodeInfo)((flags1 >> (int)InstructionInfoInternal.InfoFlags1.CodeInfoShift) & (uint)InstructionInfoInternal.InfoFlags1.CodeInfoMask);
+ Debug.Assert(InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9 + 1 == InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD11);
+ Debug.Assert(InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9 + 2 == InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1F);
+ Debug.Assert(InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9 + 3 == InstructionInfoInternal.CodeInfo.Shift_Ib_MASK3F);
+ if ((uint)(codeInfo - InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9) <= 3) {
+ switch (codeInfo) {
+ case InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9:
+ if ((Immediate8 & 0x1F) % 9 == 0)
+ return InstructionInfoInternal.RflagsInfo.None;
+ break;
+
+ case InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD11:
+ if ((Immediate8 & 0x1F) % 17 == 0)
+ return InstructionInfoInternal.RflagsInfo.None;
+ break;
+
+ case InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1F:
+ if ((Immediate8 & 0x1F) == 0)
+ return InstructionInfoInternal.RflagsInfo.None;
+ break;
+
+ case InstructionInfoInternal.CodeInfo.Shift_Ib_MASK3F:
+ if ((Immediate8 & 0x3F) == 0)
+ return InstructionInfoInternal.RflagsInfo.None;
+ break;
+ }
+ }
+ return (InstructionInfoInternal.RflagsInfo)((flags1 >> (int)InstructionInfoInternal.InfoFlags1.RflagsInfoShift) & (uint)InstructionInfoInternal.InfoFlags1.RflagsInfoMask);
+ }
+
+ ///
+ /// All flags that are read by the CPU when executing the instruction
+ ///
+ public RflagsBits RflagsRead => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsRead[(int)GetRflagsInfo()];
+
+ ///
+ /// All flags that are written by the CPU, except those flags that are known to be undefined, always set or always cleared. See also
+ ///
+ public RflagsBits RflagsWritten => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsWritten[(int)GetRflagsInfo()];
+
+ ///
+ /// All flags that are always cleared by the CPU
+ ///
+ public RflagsBits RflagsCleared => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsCleared[(int)GetRflagsInfo()];
+
+ ///
+ /// All flags that are always set by the CPU
+ ///
+ public RflagsBits RflagsSet => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsSet[(int)GetRflagsInfo()];
+
+ ///
+ /// All flags that are undefined after executing the instruction
+ ///
+ public RflagsBits RflagsUndefined => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsUndefined[(int)GetRflagsInfo()];
+
+ ///
+ /// All flags that are modified by the CPU. This is + + +
+ ///
+ public RflagsBits RflagsModified => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsModified[(int)GetRflagsInfo()];
+ }
+}
+#endif
diff --git a/Iced/Intel/Instruction.cs b/Iced/Intel/Instruction.cs
index 906ffa58f..0d577b907 100644
--- a/Iced/Intel/Instruction.cs
+++ b/Iced/Intel/Instruction.cs
@@ -26,7 +26,7 @@ namespace Iced.Intel {
///
/// A 16/32/64-bit instruction
///
- public struct Instruction {
+ public partial struct Instruction {
internal const int TEST_OpKindBits = (int)OpKindFlags.OpKindBits;
internal const int TEST_CodeBits = (int)CodeFlags.CodeBits;
internal const int TEST_RegisterBits = 8;
@@ -1290,1699 +1290,6 @@ namespace Iced.Intel {
}
}
-#if !NO_INSTR_INFO
- ///
- /// Gets the number of bytes added to SP/ESP/RSP or 0 if it's not an instruction that pushes or pops data. This method
- /// assumes the instruction doesn't change privilege (eg. iret/d/q). If it's the leave instruction, this method returns 0.
- ///
- ///
- public int StackPointerIncrement {
- get {
- switch (Code) {
- case Code.Pushw_ES:
- case Code.Pushw_CS:
- case Code.Pushw_SS:
- case Code.Pushw_DS:
- case Code.Push_r16:
- case Code.Push_imm16:
- case Code.Pushw_imm8:
- case Code.Pushfw:
- case Code.Push_rm16:
- case Code.Pushw_FS:
- case Code.Pushw_GS:
- return -2;
-
- case Code.Pushd_ES:
- case Code.Pushd_CS:
- case Code.Pushd_SS:
- case Code.Pushd_DS:
- case Code.Push_r32:
- case Code.Pushd_imm32:
- case Code.Pushd_imm8:
- case Code.Pushfd:
- case Code.Push_rm32:
- case Code.Pushd_FS:
- case Code.Pushd_GS:
- return -4;
-
- case Code.Push_r64:
- case Code.Pushq_imm32:
- case Code.Pushq_imm8:
- case Code.Pushfq:
- case Code.Push_rm64:
- case Code.Pushq_FS:
- case Code.Pushq_GS:
- return -8;
-
- case Code.Pushaw:
- return -2 * 8;
-
- case Code.Pushad:
- return -4 * 8;
-
- case Code.Popw_ES:
- case Code.Popw_SS:
- case Code.Popw_DS:
- case Code.Pop_r16:
- case Code.Pop_rm16:
- case Code.Popfw:
- case Code.Popw_FS:
- case Code.Popw_GS:
- return 2;
-
- case Code.Popd_ES:
- case Code.Popd_SS:
- case Code.Popd_DS:
- case Code.Pop_r32:
- case Code.Pop_rm32:
- case Code.Popfd:
- case Code.Popd_FS:
- case Code.Popd_GS:
- return 4;
-
- case Code.Pop_r64:
- case Code.Pop_rm64:
- case Code.Popfq:
- case Code.Popq_FS:
- case Code.Popq_GS:
- return 8;
-
- case Code.Popaw:
- return 2 * 8;
-
- case Code.Popad:
- return 4 * 8;
-
- case Code.Call_ptr1616:
- case Code.Call_m1616:
- return -(2 + 2);
-
- case Code.Call_ptr3216:
- case Code.Call_m3216:
- return -(4 + 4);
-
- case Code.Call_m6416:
- return -(8 + 8);
-
- case Code.Call_rel16:
- case Code.Call_rm16:
- return -2;
-
- case Code.Call_rel32_32:
- case Code.Call_rm32:
- return -4;
-
- case Code.Call_rel32_64:
- case Code.Call_rm64:
- return -8;
-
- case Code.Retnw_imm16:
- return 2 + Immediate16;
-
- case Code.Retnd_imm16:
- return 4 + Immediate16;
-
- case Code.Retnq_imm16:
- return 8 + Immediate16;
-
- case Code.Retnw:
- return 2;
-
- case Code.Retnd:
- return 4;
-
- case Code.Retnq:
- return 8;
-
- case Code.Retfw_imm16:
- return 2 + 2 + Immediate16;
-
- case Code.Retfd_imm16:
- return 4 + 4 + Immediate16;
-
- case Code.Retfq_imm16:
- return 8 + 8 + Immediate16;
-
- case Code.Retfw:
- return 2 + 2;
-
- case Code.Retfd:
- return 4 + 4;
-
- case Code.Retfq:
- return 8 + 8;
-
- case Code.Iretw:
- if (CodeSize == CodeSize.Code64)
- return 2 * 5;
- return 2 * 3;
-
- case Code.Iretd:
- if (CodeSize == CodeSize.Code64)
- return 4 * 5;
- return 4 * 3;
-
- case Code.Iretq:
- return 8 * 5;
-
- case Code.Enterw_imm16_imm8:
- return -(2 + (Immediate8_2nd & 0x1F) * 2 + Immediate16);
-
- case Code.Enterd_imm16_imm8:
- return -(4 + (Immediate8_2nd & 0x1F) * 4 + Immediate16);
-
- case Code.Enterq_imm16_imm8:
- return -(8 + (Immediate8_2nd & 0x1F) * 8 + Immediate16);
-
- case Code.Leavew:
- case Code.Leaved:
- case Code.Leaveq:
- return 0;
-
- default:
- return 0;
- }
- }
- }
-
- ///
- /// (This method allocates and is slower than using an .)
- ///
- /// Gets instruction info such as which register is read and written etc.
- ///
- ///
- public InstructionInfo GetInfo() {
- var usedRegisters = InstructionInfoInternal.SimpleList.Empty;
- var usedMemoryLocations = InstructionInfoInternal.SimpleList.Empty;
- return InstructionInfoFactory.Create(ref this, ref usedRegisters, ref usedMemoryLocations, InstructionInfoOptions.None);
- }
-
- ///
- /// (This method allocates and is slower than using an .)
- ///
- /// Gets instruction info such as which register is read and written etc.
- ///
- /// Options
- ///
- public InstructionInfo GetInfo(InstructionInfoOptions options) {
- var usedRegisters = InstructionInfoInternal.SimpleList.Empty;
- var usedMemoryLocations = InstructionInfoInternal.SimpleList.Empty;
- return InstructionInfoFactory.Create(ref this, ref usedRegisters, ref usedMemoryLocations, options);
- }
-
- ///
- /// (This method allocates and is slower than using an .)
- ///
- /// Gets a struct iterator that returns all read and written registers. There are some exceptions, this method doesn't return all used registers:
- ///
- /// 1) If is true, or
- ///
- /// 2) If it's a or instruction (call, sysenter, int n etc), it can read and write any register (including RFLAGS).
- ///
- ///
- public InstructionInfo.UsedRegisterIterator GetUsedRegisters() {
- var usedRegisters = InstructionInfoInternal.SimpleList.Empty;
- var usedMemoryLocations = InstructionInfoInternal.SimpleList.Empty;
- return InstructionInfoFactory.Create(ref this, ref usedRegisters, ref usedMemoryLocations, InstructionInfoOptions.NoMemoryUsage).GetUsedRegisters();
- }
-
- ///
- /// (This method allocates and is slower than using an .)
- ///
- /// Gets a struct iterator that returns all read and written memory locations
- ///
- ///
- public InstructionInfo.UsedMemoryIterator GetUsedMemory() {
- var usedRegisters = InstructionInfoInternal.SimpleList.Empty;
- var usedMemoryLocations = InstructionInfoInternal.SimpleList.Empty;
- return InstructionInfoFactory.Create(ref this, ref usedRegisters, ref usedMemoryLocations, InstructionInfoOptions.NoRegisterUsage).GetUsedMemory();
- }
-
- ///
- /// Instruction encoding, eg. legacy, VEX, EVEX, ...
- ///
- public EncodingKind Encoding => Code.Encoding();
-
- ///
- /// CPU or CPUID feature flag
- ///
- public CpuidFeature CpuidFeature {
- get {
- var code = Code;
- var cpuidFeature = code.CpuidFeature();
- if (cpuidFeature == CpuidFeature.AVX && Op1Kind == OpKind.Register && (code == Code.VEX_Vbroadcastss_xmm_xmmm32 || code == Code.VEX_Vbroadcastss_ymm_xmmm32 || code == Code.VEX_Vbroadcastsd_ymm_xmmm64))
- return CpuidFeature.AVX2;
- return cpuidFeature;
- }
- }
-
- ///
- /// Flow control info
- ///
- public FlowControl FlowControl => Code.FlowControl();
-
- ///
- /// true if the instruction isn't available in real mode or virtual 8086 mode
- ///
- public bool ProtectedMode => Code.ProtectedMode();
-
- ///
- /// true if this is a privileged instruction
- ///
- public bool Privileged => Code.Privileged();
-
- ///
- /// true if this is an instruction that implicitly uses the stack pointer (SP/ESP/RSP), eg. call, push, pop, ret, etc.
- /// See also
- ///
- public bool StackInstruction => Code.StackInstruction();
-
- ///
- /// true if it's an instruction that saves or restores too many registers (eg. fxrstor, xsave, etc).
- ///
- public bool SaveRestoreInstruction => Code.SaveRestoreInstruction();
-
- InstructionInfoInternal.RflagsInfo GetRflagsInfo() {
- var flags1 = InstructionInfoInternal.InfoHandlers.Data[(int)Code << 1];
- var codeInfo = (InstructionInfoInternal.CodeInfo)((flags1 >> (int)InstructionInfoInternal.InfoFlags1.CodeInfoShift) & (uint)InstructionInfoInternal.InfoFlags1.CodeInfoMask);
- Debug.Assert(InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9 + 1 == InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD11);
- Debug.Assert(InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9 + 2 == InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1F);
- Debug.Assert(InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9 + 3 == InstructionInfoInternal.CodeInfo.Shift_Ib_MASK3F);
- if ((uint)(codeInfo - InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9) <= 3) {
- switch (codeInfo) {
- case InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD9:
- if ((Immediate8 & 0x1F) % 9 == 0)
- return InstructionInfoInternal.RflagsInfo.None;
- break;
-
- case InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1FMOD11:
- if ((Immediate8 & 0x1F) % 17 == 0)
- return InstructionInfoInternal.RflagsInfo.None;
- break;
-
- case InstructionInfoInternal.CodeInfo.Shift_Ib_MASK1F:
- if ((Immediate8 & 0x1F) == 0)
- return InstructionInfoInternal.RflagsInfo.None;
- break;
-
- case InstructionInfoInternal.CodeInfo.Shift_Ib_MASK3F:
- if ((Immediate8 & 0x3F) == 0)
- return InstructionInfoInternal.RflagsInfo.None;
- break;
- }
- }
- return (InstructionInfoInternal.RflagsInfo)((flags1 >> (int)InstructionInfoInternal.InfoFlags1.RflagsInfoShift) & (uint)InstructionInfoInternal.InfoFlags1.RflagsInfoMask);
- }
-
- ///
- /// All flags that are read by the CPU when executing the instruction
- ///
- public RflagsBits RflagsRead => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsRead[(int)GetRflagsInfo()];
-
- ///
- /// All flags that are written by the CPU, except those flags that are known to be undefined, always set or always cleared. See also
- ///
- public RflagsBits RflagsWritten => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsWritten[(int)GetRflagsInfo()];
-
- ///
- /// All flags that are always cleared by the CPU
- ///
- public RflagsBits RflagsCleared => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsCleared[(int)GetRflagsInfo()];
-
- ///
- /// All flags that are always set by the CPU
- ///
- public RflagsBits RflagsSet => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsSet[(int)GetRflagsInfo()];
-
- ///
- /// All flags that are undefined after executing the instruction
- ///
- public RflagsBits RflagsUndefined => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsUndefined[(int)GetRflagsInfo()];
-
- ///
- /// All flags that are modified by the CPU. This is + + +
- ///
- public RflagsBits RflagsModified => (RflagsBits)InstructionInfoInternal.RflagsInfoConstants.flagsModified[(int)GetRflagsInfo()];
-#endif
-
-#if !NO_ENCODER
- static OpKind GetImmediateOpKind(Code code, int operand) {
- var handlers = EncoderInternal.OpCodeHandlers.Handlers;
- if ((uint)code >= (uint)handlers.Length)
- throw new ArgumentOutOfRangeException(nameof(code));
- var operands = handlers[(int)code].Operands;
- if ((uint)operand >= (uint)operands.Length)
- throw new ArgumentOutOfRangeException(nameof(operand), $"{code} doesn't have at least {operand + 1} operands");
- var opKind = operands[operand].GetImmediateOpKind();
- if (opKind == (OpKind)(-1))
- throw new ArgumentException($"{code}'s op{operand} isn't an immediate operand");
- return opKind;
- }
-
- static OpKind GetNearBranchOpKind(Code code, int operand) {
- var handlers = EncoderInternal.OpCodeHandlers.Handlers;
- if ((uint)code >= (uint)handlers.Length)
- throw new ArgumentOutOfRangeException(nameof(code));
- var operands = handlers[(int)code].Operands;
- if ((uint)operand >= (uint)operands.Length)
- throw new ArgumentOutOfRangeException(nameof(operand), $"{code} doesn't have at least {operand + 1} operands");
- var opKind = operands[operand].GetNearBranchOpKind();
- if (opKind == (OpKind)(-1))
- throw new ArgumentException($"{code}'s op{operand} isn't a near branch operand");
- return opKind;
- }
-
- static OpKind GetFarBranchOpKind(Code code, int operand) {
- var handlers = EncoderInternal.OpCodeHandlers.Handlers;
- if ((uint)code >= (uint)handlers.Length)
- throw new ArgumentOutOfRangeException(nameof(code));
- var operands = handlers[(int)code].Operands;
- if ((uint)operand >= (uint)operands.Length)
- throw new ArgumentOutOfRangeException(nameof(operand), $"{code} doesn't have at least {operand + 1} operands");
- var opKind = operands[operand].GetFarBranchOpKind();
- if (opKind == (OpKind)(-1))
- throw new ArgumentException($"{code}'s op{operand} isn't a far branch operand");
- return opKind;
- }
-
- ///
- /// Creates a new with no operands
- ///
- /// Code value
- ///
- public static Instruction Create(Code code) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(instruction.OpCount == 0);
- return instruction;
- }
-
- ///
- /// Creates a new near/short branch
- ///
- /// Code value
- /// Target address
- ///
- public static Instruction CreateBranch(Code code, ulong target) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.Op0Kind = GetNearBranchOpKind(code, 0);
- instruction.NearBranch64 = target;
-
- Debug.Assert(instruction.OpCount == 1);
- return instruction;
- }
-
- ///
- /// Creates a new far branch
- ///
- /// Code value
- /// Selector/segment value
- /// Offset
- ///
- public static Instruction CreateBranch(Code code, ushort selector, uint offset) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.Op0Kind = GetFarBranchOpKind(code, 0);
- instruction.FarBranchSelector = selector;
- instruction.FarBranch32 = offset;
-
- Debug.Assert(instruction.OpCount == 1);
- return instruction;
- }
-
- ///
- /// Creates an instruction with a 64-bit memory offset as the second operand, eg. 'mov al,[123456789ABCDEF0]'
- ///
- /// Code value
- /// Register (al, ax, eax, rax)
- /// 64-bit address
- /// Segment override or
- ///
- public static Instruction CreateMemory64(Code code, Register register, ulong address, Register prefixSegment = Register.None) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- instruction.InternalOp1Kind = OpKind.Memory64;
- instruction.MemoryAddress64 = address;
- instruction.InternalSetMemoryDisplSize(4);
- instruction.PrefixSegment = prefixSegment;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction with a 64-bit memory offset as the first operand, eg. 'mov [123456789ABCDEF0],al'
- ///
- /// Code value
- /// 64-bit address
- /// Register (al, ax, eax, rax)
- /// Segment override or
- ///
- public static Instruction CreateMemory64(Code code, ulong address, Register register, Register prefixSegment = Register.None) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.InternalOp0Kind = OpKind.Memory64;
- instruction.MemoryAddress64 = address;
- instruction.InternalSetMemoryDisplSize(4);
- instruction.PrefixSegment = prefixSegment;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- ///
- public static Instruction Create(Code code, Register register) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- Debug.Assert(instruction.OpCount == 1);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Immediate
- ///
- public static Instruction Create(Code code, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.InternalOp0Kind = GetImmediateOpKind(code, 0);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 1);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Immediate
- ///
- public static Instruction Create(Code code, uint immediate) =>
- Create(code, (int)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Memory operand
- ///
- public static Instruction Create(Code code, in MemoryOperand memory) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.InternalOp0Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(instruction.OpCount == 1);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- ///
- public static Instruction Create(Code code, Register register1, Register register2) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- var opKind = GetImmediateOpKind(code, 1);
- instruction.InternalOp1Kind = opKind;
- if (opKind == OpKind.Immediate64)
- instruction.Immediate64 = (ulong)immediate;
- else
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register, uint immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- var opKind = GetImmediateOpKind(code, 1);
- instruction.InternalOp1Kind = opKind;
- if (opKind == OpKind.Immediate64)
- instruction.Immediate64 = immediate;
- else
- instruction.Immediate32 = immediate;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction with a 64-bit immediate value
- ///
- /// Code value
- /// Register
- /// 64-bit immediate
- ///
- public static Instruction Create(Code code, Register register, long immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- instruction.InternalOp1Kind = OpKind.Immediate64;
- instruction.Immediate64 = (ulong)immediate;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction with a 64-bit immediate value
- ///
- /// Code value
- /// Register
- /// 64-bit immediate
- ///
- public static Instruction Create(Code code, Register register, ulong immediate) =>
- Create(code, register, (long)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register (eg. dx, al, ax, eax, rax)
- /// si, esi, or rsi
- /// Segment override or
- ///
- public static Instruction CreateString_Reg_SegRSI(Code code, Register register, Register rSI, Register prefixSegment = Register.None) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- if (rSI == Register.RSI)
- instruction.InternalOp1Kind = OpKind.MemorySegRSI;
- else if (rSI == Register.ESI)
- instruction.InternalOp1Kind = OpKind.MemorySegESI;
- else if (rSI == Register.SI)
- instruction.InternalOp1Kind = OpKind.MemorySegSI;
- else
- throw new ArgumentOutOfRangeException(nameof(rSI));
-
- instruction.PrefixSegment = prefixSegment;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register (eg. al, ax, eax, rax)
- /// di, edi, or rdi
- ///
- public static Instruction CreateString_Reg_ESRDI(Code code, Register register, Register rDI) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- if (rDI == Register.RDI)
- instruction.InternalOp1Kind = OpKind.MemoryESRDI;
- else if (rDI == Register.EDI)
- instruction.InternalOp1Kind = OpKind.MemoryESEDI;
- else if (rDI == Register.DI)
- instruction.InternalOp1Kind = OpKind.MemoryESDI;
- else
- throw new ArgumentOutOfRangeException(nameof(rDI));
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Memory operand
- ///
- public static Instruction Create(Code code, Register register, in MemoryOperand memory) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- instruction.InternalOp1Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Immediate
- /// Register
- ///
- public static Instruction Create(Code code, int immediate, Register register) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.InternalOp0Kind = GetImmediateOpKind(code, 0);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Immediate
- /// Register
- ///
- public static Instruction Create(Code code, uint immediate, Register register) =>
- Create(code, (int)immediate, register);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Immediate
- /// Second immediate
- ///
- public static Instruction Create(Code code, int immediate, byte immediate2) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.InternalOp0Kind = GetImmediateOpKind(code, 0);
- instruction.Immediate32 = (uint)immediate;
-
- instruction.InternalOp1Kind = OpKind.Immediate8_2nd;
- instruction.Immediate8_2nd = immediate2;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Immediate
- /// Second immediate
- ///
- public static Instruction Create(Code code, uint immediate, byte immediate2) =>
- Create(code, (int)immediate, immediate2);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// si, esi, or rsi
- /// di, edi, or rdi
- /// Segment override or
- ///
- public static Instruction CreateString_SegRSI_ESRDI(Code code, Register rSI, Register rDI, Register prefixSegment = Register.None) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- if (rSI == Register.RSI)
- instruction.InternalOp0Kind = OpKind.MemorySegRSI;
- else if (rSI == Register.ESI)
- instruction.InternalOp0Kind = OpKind.MemorySegESI;
- else if (rSI == Register.SI)
- instruction.InternalOp0Kind = OpKind.MemorySegSI;
- else
- throw new ArgumentOutOfRangeException(nameof(rSI));
-
- if (rDI == Register.RDI)
- instruction.InternalOp1Kind = OpKind.MemoryESRDI;
- else if (rDI == Register.EDI)
- instruction.InternalOp1Kind = OpKind.MemoryESEDI;
- else if (rDI == Register.DI)
- instruction.InternalOp1Kind = OpKind.MemoryESDI;
- else
- throw new ArgumentOutOfRangeException(nameof(rDI));
-
- instruction.PrefixSegment = prefixSegment;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// di, edi, or rdi
- /// Register (eg. dx, al, ax, eax, rax)
- ///
- public static Instruction CreateString_ESRDI_Reg(Code code, Register rDI, Register register) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- if (rDI == Register.RDI)
- instruction.InternalOp0Kind = OpKind.MemoryESRDI;
- else if (rDI == Register.EDI)
- instruction.InternalOp0Kind = OpKind.MemoryESEDI;
- else if (rDI == Register.DI)
- instruction.InternalOp0Kind = OpKind.MemoryESDI;
- else
- throw new ArgumentOutOfRangeException(nameof(rDI));
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// di, edi, or rdi
- /// si, esi, or rsi
- /// Segment override or
- ///
- public static Instruction CreateString_ESRDI_SegRSI(Code code, Register rDI, Register rSI, Register prefixSegment = Register.None) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- if (rDI == Register.RDI)
- instruction.InternalOp0Kind = OpKind.MemoryESRDI;
- else if (rDI == Register.EDI)
- instruction.InternalOp0Kind = OpKind.MemoryESEDI;
- else if (rDI == Register.DI)
- instruction.InternalOp0Kind = OpKind.MemoryESDI;
- else
- throw new ArgumentOutOfRangeException(nameof(rDI));
-
- if (rSI == Register.RSI)
- instruction.InternalOp1Kind = OpKind.MemorySegRSI;
- else if (rSI == Register.ESI)
- instruction.InternalOp1Kind = OpKind.MemorySegESI;
- else if (rSI == Register.SI)
- instruction.InternalOp1Kind = OpKind.MemorySegSI;
- else
- throw new ArgumentOutOfRangeException(nameof(rSI));
-
- instruction.PrefixSegment = prefixSegment;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Memory operand
- /// Register
- ///
- public static Instruction Create(Code code, in MemoryOperand memory, Register register) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.InternalOp0Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Memory operand
- /// Immediate
- ///
- public static Instruction Create(Code code, in MemoryOperand memory, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.InternalOp0Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- instruction.InternalOp1Kind = GetImmediateOpKind(code, 1);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 2);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Memory operand
- /// Immediate
- ///
- public static Instruction Create(Code code, in MemoryOperand memory, uint immediate) =>
- Create(code, memory, (int)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Register
- ///
- public static Instruction Create(Code code, Register register1, Register register2, Register register3) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp2Kind = OpKind.Register;
- instruction.InternalOp2Register = register3;
-
- Debug.Assert(instruction.OpCount == 3);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- instruction.InternalOp2Kind = GetImmediateOpKind(code, 2);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 3);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, uint immediate) =>
- Create(code, register1, register2, (int)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Memory operand
- ///
- public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- instruction.InternalOp2Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(instruction.OpCount == 3);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Immediate
- /// Second immediate
- ///
- public static Instruction Create(Code code, Register register, int immediate, byte immediate2) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- instruction.InternalOp1Kind = GetImmediateOpKind(code, 1);
- instruction.Immediate32 = (uint)immediate;
-
- instruction.InternalOp2Kind = OpKind.Immediate8_2nd;
- instruction.Immediate8_2nd = immediate2;
-
- Debug.Assert(instruction.OpCount == 3);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Immediate
- /// Second immediate
- ///
- public static Instruction Create(Code code, Register register, uint immediate, byte immediate2) =>
- Create(code, register, (int)immediate, immediate2);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Memory operand
- /// Register
- ///
- public static Instruction Create(Code code, Register register1, in MemoryOperand memory, Register register2) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- instruction.InternalOp1Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp2Kind = OpKind.Register;
- instruction.InternalOp2Register = register2;
-
- Debug.Assert(instruction.OpCount == 3);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Memory operand
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register, in MemoryOperand memory, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register;
-
- instruction.InternalOp1Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- instruction.InternalOp2Kind = GetImmediateOpKind(code, 2);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 3);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Memory operand
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register, in MemoryOperand memory, uint immediate) =>
- Create(code, register, memory, (int)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// di, edi, or rdi
- /// Register
- /// Register
- /// Segment override or
- ///
- public static Instruction CreateMaskmov_SegRDI_Reg_Reg(Code code, Register rDI, Register register1, Register register2, Register prefixSegment = Register.None) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- if (rDI == Register.RDI)
- instruction.InternalOp0Kind = OpKind.MemorySegRDI;
- else if (rDI == Register.EDI)
- instruction.InternalOp0Kind = OpKind.MemorySegEDI;
- else if (rDI == Register.DI)
- instruction.InternalOp0Kind = OpKind.MemorySegDI;
- else
- throw new ArgumentOutOfRangeException(nameof(rDI));
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp2Kind = OpKind.Register;
- instruction.InternalOp2Register = register2;
-
- instruction.PrefixSegment = prefixSegment;
-
- Debug.Assert(instruction.OpCount == 3);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Memory operand
- /// Register
- /// Register
- ///
- public static Instruction Create(Code code, in MemoryOperand memory, Register register1, Register register2) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.InternalOp0Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp2Kind = OpKind.Register;
- instruction.InternalOp2Register = register2;
-
- Debug.Assert(instruction.OpCount == 3);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Memory operand
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, in MemoryOperand memory, Register register, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- instruction.InternalOp0Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register;
-
- instruction.InternalOp2Kind = GetImmediateOpKind(code, 2);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 3);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Memory operand
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, in MemoryOperand memory, Register register, uint immediate) =>
- Create(code, memory, register, (int)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Register
- /// Register
- ///
- public static Instruction Create(Code code, Register register1, Register register2, Register register3, Register register4) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp2Kind = OpKind.Register;
- instruction.InternalOp2Register = register3;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp3Kind = OpKind.Register;
- instruction.InternalOp3Register = register4;
-
- Debug.Assert(instruction.OpCount == 4);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, Register register3, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp2Kind = OpKind.Register;
- instruction.InternalOp2Register = register3;
-
- instruction.InternalOp3Kind = GetImmediateOpKind(code, 3);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 4);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, Register register3, uint immediate) =>
- Create(code, register1, register2, register3, (int)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Register
- /// Memory operand
- ///
- public static Instruction Create(Code code, Register register1, Register register2, Register register3, in MemoryOperand memory) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp2Kind = OpKind.Register;
- instruction.InternalOp2Register = register3;
-
- instruction.InternalOp3Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(instruction.OpCount == 4);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Immediate
- /// Second immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, int immediate, byte immediate2) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- instruction.InternalOp2Kind = GetImmediateOpKind(code, 2);
- instruction.Immediate32 = (uint)immediate;
-
- instruction.InternalOp3Kind = OpKind.Immediate8_2nd;
- instruction.Immediate8_2nd = immediate2;
-
- Debug.Assert(instruction.OpCount == 4);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Immediate
- /// Second immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, uint immediate, byte immediate2) =>
- Create(code, register1, register2, (int)immediate, immediate2);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Memory operand
- /// Register
- ///
- public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, Register register3) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- instruction.InternalOp2Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp3Kind = OpKind.Register;
- instruction.InternalOp3Register = register3;
-
- Debug.Assert(instruction.OpCount == 4);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Memory operand
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- instruction.InternalOp2Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- instruction.InternalOp3Kind = GetImmediateOpKind(code, 3);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 4);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Memory operand
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, uint immediate) =>
- Create(code, register1, register2, memory, (int)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Register
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, Register register3, Register register4, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp2Kind = OpKind.Register;
- instruction.InternalOp2Register = register3;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp3Kind = OpKind.Register;
- instruction.InternalOp3Register = register4;
-
- instruction.InternalOp4Kind = GetImmediateOpKind(code, 4);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 5);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Register
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, Register register3, Register register4, uint immediate) =>
- Create(code, register1, register2, register3, register4, (int)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Register
- /// Memory operand
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, Register register3, in MemoryOperand memory, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp2Kind = OpKind.Register;
- instruction.InternalOp2Register = register3;
-
- instruction.InternalOp3Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- instruction.InternalOp4Kind = GetImmediateOpKind(code, 4);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 5);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Register
- /// Memory operand
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, Register register3, in MemoryOperand memory, uint immediate) =>
- Create(code, register1, register2, register3, memory, (int)immediate);
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Memory operand
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, Register register3, int immediate) {
- Instruction instruction = default;
- instruction.InternalCode = code;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp0Kind = OpKind.Register;
- instruction.InternalOp0Register = register1;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp1Kind = OpKind.Register;
- instruction.InternalOp1Register = register2;
-
- instruction.InternalOp2Kind = OpKind.Memory;
- instruction.InternalMemoryBase = memory.Base;
- instruction.InternalMemoryIndex = memory.Index;
- instruction.MemoryIndexScale = memory.Scale;
- instruction.MemoryDisplSize = memory.DisplSize;
- instruction.MemoryDisplacement = (uint)memory.Displacement;
- instruction.IsBroadcast = memory.IsBroadcast;
- instruction.PrefixSegment = memory.PrefixSegment;
-
- Debug.Assert(OpKind.Register == 0);
- //instruction.InternalOp3Kind = OpKind.Register;
- instruction.InternalOp3Register = register3;
-
- instruction.InternalOp4Kind = GetImmediateOpKind(code, 4);
- instruction.Immediate32 = (uint)immediate;
-
- Debug.Assert(instruction.OpCount == 5);
- return instruction;
- }
-
- ///
- /// Creates an instruction
- ///
- /// Code value
- /// Register
- /// Register
- /// Memory operand
- /// Register
- /// Immediate
- ///
- public static Instruction Create(Code code, Register register1, Register register2, in MemoryOperand memory, Register register3, uint immediate) =>
- Create(code, register1, register2, memory, register3, (int)immediate);
-#endif
-
///
/// Formats the instruction using the default formatter with default formatter options
///