예제 #1
0
 public OpCodeFormatter(OpCodeInfo opCode, StringBuilder sb, LKind lkind, bool hasModrmInfo)
 {
     this.opCode       = opCode;
     this.sb           = sb;
     this.lkind        = lkind;
     this.hasModrmInfo = hasModrmInfo;
 }
예제 #2
0
 public OpCodeFormatter(OpCodeInfo opCode, StringBuilder sb, LKind lkind)
 {
     this.opCode = opCode;
     this.sb     = sb;
     this.lkind  = lkind;
 }
예제 #3
0
        internal OpCodeInfo(Code code, uint dword3, uint dword2, uint dword1, StringBuilder sb)
        {
            Debug.Assert((uint)code < (uint)IcedConstants.NumberOfCodeValues);
            Debug.Assert((uint)code <= ushort.MaxValue);
            this.code = (ushort)code;
            if (code <= Code.DeclareQword)
            {
                flags |= Flags.NoInstruction;
            }
            opCode = (ushort)(dword1 >> (int)EncFlags1.OpCodeShift);

#if HAS_SPAN
            ReadOnlySpan <byte> opKinds;
#else
            byte[] opKinds;
#endif
            encoding = (byte)((dword1 >> (int)EncFlags1.EncodingShift) & (uint)EncFlags1.EncodingMask);
            switch ((EncodingKind)encoding)
            {
            case EncodingKind.Legacy:
                opKinds = OpCodeOperandKinds.LegacyOpKinds;
                op0Kind = opKinds[(int)((dword3 >> (int)LegacyFlags3.Op0Shift) & (uint)LegacyFlags3.OpMask)];
                op1Kind = opKinds[(int)((dword3 >> (int)LegacyFlags3.Op1Shift) & (uint)LegacyFlags3.OpMask)];
                op2Kind = opKinds[(int)((dword3 >> (int)LegacyFlags3.Op2Shift) & (uint)LegacyFlags3.OpMask)];
                op3Kind = opKinds[(int)((dword3 >> (int)LegacyFlags3.Op3Shift) & (uint)LegacyFlags3.OpMask)];

                mandatoryPrefix = (MandatoryPrefixByte)((dword2 >> (int)LegacyFlags.MandatoryPrefixByteShift) & (uint)LegacyFlags.MandatoryPrefixByteMask) switch {
                    MandatoryPrefixByte.None => (byte)((dword2 & (uint)LegacyFlags.HasMandatoryPrefix) != 0 ? MandatoryPrefix.PNP : MandatoryPrefix.None),
                    MandatoryPrefixByte.P66 => (byte)MandatoryPrefix.P66,
                    MandatoryPrefixByte.PF3 => (byte)MandatoryPrefix.PF3,
                    MandatoryPrefixByte.PF2 => (byte)MandatoryPrefix.PF2,
                    _ => throw new InvalidOperationException(),
                };

                table = (LegacyOpCodeTable)((dword2 >> (int)LegacyFlags.LegacyOpCodeTableShift) & (uint)LegacyFlags.LegacyOpCodeTableMask) switch {
                    LegacyOpCodeTable.Normal => (byte)OpCodeTableKind.Normal,
                    LegacyOpCodeTable.Table0F => (byte)OpCodeTableKind.T0F,
                    LegacyOpCodeTable.Table0F38 => (byte)OpCodeTableKind.T0F38,
                    LegacyOpCodeTable.Table0F3A => (byte)OpCodeTableKind.T0F3A,
                    _ => throw new InvalidOperationException(),
                };

                groupIndex = (sbyte)((dword2 & (uint)LegacyFlags.HasGroupIndex) == 0 ? -1 : (int)((dword2 >> (int)LegacyFlags.GroupShift) & 7));
                tupleType  = (byte)TupleType.None;

                if (!IsInstruction)
                {
                    flags |= Flags.Mode16 | Flags.Mode32 | Flags.Mode64;
                }
                else
                {
                    flags |= (Encodable)((dword2 >> (int)LegacyFlags.EncodableShift) & (uint)LegacyFlags.EncodableMask) switch {
                        Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                        Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                        Encodable.Only64 => Flags.Mode64,
                        _ => throw new InvalidOperationException(),
                    };
                }

                flags |= (AllowedPrefixes)((dword2 >> (int)LegacyFlags.AllowedPrefixesShift) & (uint)LegacyFlags.AllowedPrefixesMask) switch {
                    // GENERATOR-BEGIN: AllowedPrefixes
                    // ⚠️This was generated by GENERATOR!🦹‍♂️
                    AllowedPrefixes.None => Flags.None,
                    AllowedPrefixes.Bnd => Flags.BndPrefix,
                    AllowedPrefixes.BndNotrack => Flags.BndPrefix | Flags.NotrackPrefix,
                    AllowedPrefixes.HintTakenBnd => Flags.BndPrefix | Flags.HintTakenPrefix,
                    AllowedPrefixes.Lock => Flags.LockPrefix,
                    AllowedPrefixes.Rep => Flags.RepPrefix,
                    AllowedPrefixes.RepRepne => Flags.RepPrefix | Flags.RepnePrefix,
                    AllowedPrefixes.XacquireXreleaseLock => Flags.LockPrefix | Flags.XacquirePrefix | Flags.XreleasePrefix,
                    AllowedPrefixes.Xrelease => Flags.XreleasePrefix,
                    // GENERATOR-END: AllowedPrefixes
                    _ => throw new InvalidOperationException(),
                };
                if ((dword2 & (uint)LegacyFlags.Fwait) != 0)
                {
                    flags |= Flags.Fwait;
                }

                operandSize = ((OperandSize)((dword2 >> (int)LegacyFlags.OperandSizeShift) & (uint)LegacyFlags.OperandSizeMask)) switch {
                    EncoderInternal.OperandSize.None => 0,
                    EncoderInternal.OperandSize.Size16 => 16,
                    EncoderInternal.OperandSize.Size32 => 32,
                    EncoderInternal.OperandSize.Size64 => 64,
                    _ => throw new InvalidOperationException(),
                };

                addressSize = ((AddressSize)((dword2 >> (int)LegacyFlags.AddressSizeShift) & (uint)LegacyFlags.AddressSizeMask)) switch {
                    EncoderInternal.AddressSize.None => 0,
                    EncoderInternal.AddressSize.Size16 => 16,
                    EncoderInternal.AddressSize.Size32 => 32,
                    EncoderInternal.AddressSize.Size64 => 64,
                    _ => throw new InvalidOperationException(),
                };

                l     = 0;
                lkind = LKind.None;
                break;

            case EncodingKind.VEX:
                opKinds = OpCodeOperandKinds.VexOpKinds;
                op0Kind = opKinds[(int)((dword3 >> (int)VexFlags3.Op0Shift) & (uint)VexFlags3.OpMask)];
                op1Kind = opKinds[(int)((dword3 >> (int)VexFlags3.Op1Shift) & (uint)VexFlags3.OpMask)];
                op2Kind = opKinds[(int)((dword3 >> (int)VexFlags3.Op2Shift) & (uint)VexFlags3.OpMask)];
                op3Kind = opKinds[(int)((dword3 >> (int)VexFlags3.Op3Shift) & (uint)VexFlags3.OpMask)];
                op4Kind = opKinds[(int)((dword3 >> (int)VexFlags3.Op4Shift) & (uint)VexFlags3.OpMask)];

                mandatoryPrefix = (MandatoryPrefixByte)((dword2 >> (int)VexFlags.MandatoryPrefixByteShift) & (uint)VexFlags.MandatoryPrefixByteMask) switch {
                    MandatoryPrefixByte.None => (byte)MandatoryPrefix.PNP,
                    MandatoryPrefixByte.P66 => (byte)MandatoryPrefix.P66,
                    MandatoryPrefixByte.PF3 => (byte)MandatoryPrefix.PF3,
                    MandatoryPrefixByte.PF2 => (byte)MandatoryPrefix.PF2,
                    _ => throw new InvalidOperationException(),
                };

                table = (VexOpCodeTable)((dword2 >> (int)VexFlags.VexOpCodeTableShift) & (uint)VexFlags.VexOpCodeTableMask) switch {
                    VexOpCodeTable.Table0F => (byte)OpCodeTableKind.T0F,
                    VexOpCodeTable.Table0F38 => (byte)OpCodeTableKind.T0F38,
                    VexOpCodeTable.Table0F3A => (byte)OpCodeTableKind.T0F3A,
                    _ => throw new InvalidOperationException(),
                };

                groupIndex = (sbyte)((dword2 & (uint)VexFlags.HasGroupIndex) == 0 ? -1 : (int)((dword2 >> (int)VexFlags.GroupShift) & 7));
                tupleType  = (byte)TupleType.None;

                flags |= (Encodable)((dword2 >> (int)VexFlags.EncodableShift) & (uint)VexFlags.EncodableMask) switch {
                    Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                    Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                    Encodable.Only64 => Flags.Mode64,
                    _ => throw new InvalidOperationException(),
                };
                operandSize = 0;
                addressSize = 0;
                switch ((VexVectorLength)((dword2 >> (int)VexFlags.VexVectorLengthShift) & (int)VexFlags.VexVectorLengthMask))
                {
                case VexVectorLength.LZ:
                    lkind = LKind.LZ;
                    l     = 0;
                    break;

                case VexVectorLength.L0:
                    lkind = LKind.L0;
                    l     = 0;
                    break;

                case VexVectorLength.L1:
                    lkind = LKind.L0;
                    l     = 1;
                    break;

                case VexVectorLength.L128:
                    lkind = LKind.L128;
                    l     = 0;
                    break;

                case VexVectorLength.L256:
                    lkind = LKind.L128;
                    l     = 1;
                    break;

                case VexVectorLength.LIG:
                    lkind  = LKind.None;
                    l      = 0;
                    flags |= Flags.LIG;
                    break;

                default:
                    throw new InvalidOperationException();
                }

                switch ((WBit)((dword2 >> (int)VexFlags.WBitShift) & (uint)VexFlags.WBitMask))
                {
                case WBit.W1:
                    flags |= Flags.W;
                    break;

                case WBit.WIG:
                    flags |= Flags.WIG;
                    break;

                case WBit.WIG32:
                    flags |= Flags.WIG32;
                    break;
                }
                break;

            case EncodingKind.EVEX:
                opKinds = OpCodeOperandKinds.EvexOpKinds;
                op0Kind = opKinds[(int)((dword3 >> (int)EvexFlags3.Op0Shift) & (uint)EvexFlags3.OpMask)];
                op1Kind = opKinds[(int)((dword3 >> (int)EvexFlags3.Op1Shift) & (uint)EvexFlags3.OpMask)];
                op2Kind = opKinds[(int)((dword3 >> (int)EvexFlags3.Op2Shift) & (uint)EvexFlags3.OpMask)];
                op3Kind = opKinds[(int)((dword3 >> (int)EvexFlags3.Op3Shift) & (uint)EvexFlags3.OpMask)];

                mandatoryPrefix = (MandatoryPrefixByte)((dword2 >> (int)EvexFlags.MandatoryPrefixByteShift) & (uint)EvexFlags.MandatoryPrefixByteMask) switch {
                    MandatoryPrefixByte.None => (byte)MandatoryPrefix.PNP,
                    MandatoryPrefixByte.P66 => (byte)MandatoryPrefix.P66,
                    MandatoryPrefixByte.PF3 => (byte)MandatoryPrefix.PF3,
                    MandatoryPrefixByte.PF2 => (byte)MandatoryPrefix.PF2,
                    _ => throw new InvalidOperationException(),
                };

                table = (EvexOpCodeTable)((dword2 >> (int)EvexFlags.EvexOpCodeTableShift) & (uint)EvexFlags.EvexOpCodeTableMask) switch {
                    EvexOpCodeTable.Table0F => (byte)OpCodeTableKind.T0F,
                    EvexOpCodeTable.Table0F38 => (byte)OpCodeTableKind.T0F38,
                    EvexOpCodeTable.Table0F3A => (byte)OpCodeTableKind.T0F3A,
                    _ => throw new InvalidOperationException(),
                };

                groupIndex = (sbyte)((dword2 & (uint)EvexFlags.HasGroupIndex) == 0 ? -1 : (int)((dword2 >> (int)EvexFlags.GroupShift) & 7));
                tupleType  = (byte)((dword2 >> (int)EvexFlags.TupleTypeShift) & (uint)EvexFlags.TupleTypeMask);

                flags |= (Encodable)((dword2 >> (int)EvexFlags.EncodableShift) & (uint)EvexFlags.EncodableMask) switch {
                    Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                    Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                    Encodable.Only64 => Flags.Mode64,
                    _ => throw new InvalidOperationException(),
                };
                operandSize = 0;
                addressSize = 0;
                l           = (byte)((dword2 >> (int)EvexFlags.EvexVectorLengthShift) & (uint)EvexFlags.EvexVectorLengthMask);

                switch ((WBit)((dword2 >> (int)EvexFlags.WBitShift) & (uint)EvexFlags.WBitMask))
                {
                case WBit.W1:
                    flags |= Flags.W;
                    break;

                case WBit.WIG:
                    flags |= Flags.WIG;
                    break;

                case WBit.WIG32:
                    flags |= Flags.WIG32;
                    break;
                }
                if ((dword2 & (uint)EvexFlags.LIG) != 0)
                {
                    flags |= Flags.LIG;
                }
                if ((dword2 & (uint)EvexFlags.b) != 0)
                {
                    flags |= Flags.Broadcast;
                }
                if ((dword2 & (uint)EvexFlags.er) != 0)
                {
                    flags |= Flags.RoundingControl;
                }
                if ((dword2 & (uint)EvexFlags.sae) != 0)
                {
                    flags |= Flags.SuppressAllExceptions;
                }
                if ((dword2 & (uint)EvexFlags.k1) != 0)
                {
                    flags |= Flags.OpMaskRegister;
                }
                if ((dword2 & (uint)EvexFlags.z) != 0)
                {
                    flags |= Flags.ZeroingMasking;
                }
                lkind = LKind.L128;
                switch (code)
                {
                // GENERATOR-BEGIN: NonZeroOpMaskRegister
                // ⚠️This was generated by GENERATOR!🦹‍♂️
                case Code.EVEX_Vpgatherdd_xmm_k1_vm32x:
                case Code.EVEX_Vpgatherdd_ymm_k1_vm32y:
                case Code.EVEX_Vpgatherdd_zmm_k1_vm32z:
                case Code.EVEX_Vpgatherdq_xmm_k1_vm32x:
                case Code.EVEX_Vpgatherdq_ymm_k1_vm32x:
                case Code.EVEX_Vpgatherdq_zmm_k1_vm32y:
                case Code.EVEX_Vpgatherqd_xmm_k1_vm64x:
                case Code.EVEX_Vpgatherqd_xmm_k1_vm64y:
                case Code.EVEX_Vpgatherqd_ymm_k1_vm64z:
                case Code.EVEX_Vpgatherqq_xmm_k1_vm64x:
                case Code.EVEX_Vpgatherqq_ymm_k1_vm64y:
                case Code.EVEX_Vpgatherqq_zmm_k1_vm64z:
                case Code.EVEX_Vgatherdps_xmm_k1_vm32x:
                case Code.EVEX_Vgatherdps_ymm_k1_vm32y:
                case Code.EVEX_Vgatherdps_zmm_k1_vm32z:
                case Code.EVEX_Vgatherdpd_xmm_k1_vm32x:
                case Code.EVEX_Vgatherdpd_ymm_k1_vm32x:
                case Code.EVEX_Vgatherdpd_zmm_k1_vm32y:
                case Code.EVEX_Vgatherqps_xmm_k1_vm64x:
                case Code.EVEX_Vgatherqps_xmm_k1_vm64y:
                case Code.EVEX_Vgatherqps_ymm_k1_vm64z:
                case Code.EVEX_Vgatherqpd_xmm_k1_vm64x:
                case Code.EVEX_Vgatherqpd_ymm_k1_vm64y:
                case Code.EVEX_Vgatherqpd_zmm_k1_vm64z:
                case Code.EVEX_Vpscatterdd_vm32x_k1_xmm:
                case Code.EVEX_Vpscatterdd_vm32y_k1_ymm:
                case Code.EVEX_Vpscatterdd_vm32z_k1_zmm:
                case Code.EVEX_Vpscatterdq_vm32x_k1_xmm:
                case Code.EVEX_Vpscatterdq_vm32x_k1_ymm:
                case Code.EVEX_Vpscatterdq_vm32y_k1_zmm:
                case Code.EVEX_Vpscatterqd_vm64x_k1_xmm:
                case Code.EVEX_Vpscatterqd_vm64y_k1_xmm:
                case Code.EVEX_Vpscatterqd_vm64z_k1_ymm:
                case Code.EVEX_Vpscatterqq_vm64x_k1_xmm:
                case Code.EVEX_Vpscatterqq_vm64y_k1_ymm:
                case Code.EVEX_Vpscatterqq_vm64z_k1_zmm:
                case Code.EVEX_Vscatterdps_vm32x_k1_xmm:
                case Code.EVEX_Vscatterdps_vm32y_k1_ymm:
                case Code.EVEX_Vscatterdps_vm32z_k1_zmm:
                case Code.EVEX_Vscatterdpd_vm32x_k1_xmm:
                case Code.EVEX_Vscatterdpd_vm32x_k1_ymm:
                case Code.EVEX_Vscatterdpd_vm32y_k1_zmm:
                case Code.EVEX_Vscatterqps_vm64x_k1_xmm:
                case Code.EVEX_Vscatterqps_vm64y_k1_xmm:
                case Code.EVEX_Vscatterqps_vm64z_k1_ymm:
                case Code.EVEX_Vscatterqpd_vm64x_k1_xmm:
                case Code.EVEX_Vscatterqpd_vm64y_k1_ymm:
                case Code.EVEX_Vscatterqpd_vm64z_k1_zmm:
                case Code.EVEX_Vgatherpf0dps_vm32z_k1:
                case Code.EVEX_Vgatherpf0dpd_vm32y_k1:
                case Code.EVEX_Vgatherpf1dps_vm32z_k1:
                case Code.EVEX_Vgatherpf1dpd_vm32y_k1:
                case Code.EVEX_Vscatterpf0dps_vm32z_k1:
                case Code.EVEX_Vscatterpf0dpd_vm32y_k1:
                case Code.EVEX_Vscatterpf1dps_vm32z_k1:
                case Code.EVEX_Vscatterpf1dpd_vm32y_k1:
                case Code.EVEX_Vgatherpf0qps_vm64z_k1:
                case Code.EVEX_Vgatherpf0qpd_vm64z_k1:
                case Code.EVEX_Vgatherpf1qps_vm64z_k1:
                case Code.EVEX_Vgatherpf1qpd_vm64z_k1:
                case Code.EVEX_Vscatterpf0qps_vm64z_k1:
                case Code.EVEX_Vscatterpf0qpd_vm64z_k1:
                case Code.EVEX_Vscatterpf1qps_vm64z_k1:
                case Code.EVEX_Vscatterpf1qpd_vm64z_k1:
                    // GENERATOR-END: NonZeroOpMaskRegister
                    flags |= Flags.NonZeroOpMaskRegister;
                    break;
                }
                break;

            case EncodingKind.XOP:
                opKinds = OpCodeOperandKinds.XopOpKinds;
                op0Kind = opKinds[(int)((dword3 >> (int)XopFlags3.Op0Shift) & (uint)XopFlags3.OpMask)];
                op1Kind = opKinds[(int)((dword3 >> (int)XopFlags3.Op1Shift) & (uint)XopFlags3.OpMask)];
                op2Kind = opKinds[(int)((dword3 >> (int)XopFlags3.Op2Shift) & (uint)XopFlags3.OpMask)];
                op3Kind = opKinds[(int)((dword3 >> (int)XopFlags3.Op3Shift) & (uint)XopFlags3.OpMask)];

                mandatoryPrefix = (MandatoryPrefixByte)((dword2 >> (int)XopFlags.MandatoryPrefixByteShift) & (uint)XopFlags.MandatoryPrefixByteMask) switch {
                    MandatoryPrefixByte.None => (byte)MandatoryPrefix.PNP,
                    MandatoryPrefixByte.P66 => (byte)MandatoryPrefix.P66,
                    MandatoryPrefixByte.PF3 => (byte)MandatoryPrefix.PF3,
                    MandatoryPrefixByte.PF2 => (byte)MandatoryPrefix.PF2,
                    _ => throw new InvalidOperationException(),
                };

                table = (XopOpCodeTable)((dword2 >> (int)XopFlags.XopOpCodeTableShift) & (uint)XopFlags.XopOpCodeTableMask) switch {
                    XopOpCodeTable.XOP8 => (byte)OpCodeTableKind.XOP8,
                    XopOpCodeTable.XOP9 => (byte)OpCodeTableKind.XOP9,
                    XopOpCodeTable.XOPA => (byte)OpCodeTableKind.XOPA,
                    _ => throw new InvalidOperationException(),
                };

                groupIndex = (sbyte)((dword2 & (uint)XopFlags.HasGroupIndex) == 0 ? -1 : (int)((dword2 >> (int)XopFlags.GroupShift) & 7));
                tupleType  = (byte)TupleType.None;

                flags |= (Encodable)((dword2 >> (int)XopFlags.EncodableShift) & (uint)XopFlags.EncodableMask) switch {
                    Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                    Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                    Encodable.Only64 => Flags.Mode64,
                    _ => throw new InvalidOperationException(),
                };
                operandSize = 0;
                addressSize = 0;

                switch ((WBit)((dword2 >> (int)XopFlags.WBitShift) & (uint)XopFlags.WBitMask))
                {
                case WBit.W1:
                    flags |= Flags.W;
                    break;

                case WBit.WIG:
                    flags |= Flags.WIG;
                    break;

                case WBit.WIG32:
                    flags |= Flags.WIG32;
                    break;
                }
                switch ((XopVectorLength)((dword2 >> (int)XopFlags.XopVectorLengthShift) & (uint)XopFlags.XopVectorLengthMask))
                {
                case XopVectorLength.L128:
                    l     = 0;
                    lkind = LKind.L128;
                    break;

                case XopVectorLength.L256:
                    l     = 1;
                    lkind = LKind.L128;
                    break;

                case XopVectorLength.L0:
                    l     = 0;
                    lkind = LKind.L0;
                    break;

                case XopVectorLength.L1:
                    l     = 1;
                    lkind = LKind.L0;
                    break;

                default:
                    throw new InvalidOperationException();
                }
                break;

            case EncodingKind.D3NOW:
                op0Kind         = (byte)OpCodeOperandKind.mm_reg;
                op1Kind         = (byte)OpCodeOperandKind.mm_or_mem;
                mandatoryPrefix = (byte)MandatoryPrefix.None;
                table           = (byte)OpCodeTableKind.T0F;
                groupIndex      = -1;
                tupleType       = (byte)TupleType.None;

                flags |= (Encodable)((dword2 >> (int)D3nowFlags.EncodableShift) & (uint)D3nowFlags.EncodableMask) switch {
                    Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                    Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                    Encodable.Only64 => Flags.Mode64,
                    _ => throw new InvalidOperationException(),
                };
                operandSize = 0;
                addressSize = 0;
                l           = 0;
                lkind       = LKind.None;
                break;

            default:
                throw new InvalidOperationException();
            }

            toOpCodeStringValue      = new OpCodeFormatter(this, sb, lkind).Format();
            toInstructionStringValue = new InstructionFormatter(this, sb).Format();
        }
예제 #4
0
        internal OpCodeInfo(uint dword3, uint dword2, uint dword1, StringBuilder sb)
        {
            var code = (Code)(dword1 & (uint)EncFlags1.CodeMask);

            Debug.Assert((uint)code < (uint)DecoderConstants.NumberOfCodeValues);
            Debug.Assert((uint)code <= ushort.MaxValue);
            this.code = (ushort)code;
            if (!(code == Code.INVALID || code >= Code.DeclareByte))
            {
                flags |= Flags.IsInstruction;
            }
            opCode = (ushort)(dword1 >> (int)EncFlags1.OpCodeShift);

            byte[] opKinds;
            encoding = (byte)((dword1 >> (int)EncFlags1.EncodingShift) & (uint)EncFlags1.EncodingMask);
            switch ((EncodingKind)encoding)
            {
            case EncodingKind.Legacy:
                opKinds = OpCodeOperandKinds.LegacyOpKinds;
                op0Kind = opKinds[(int)(dword3 & (uint)LegacyFlags3.OpMask)];
                op1Kind = opKinds[(int)((dword3 >> (int)LegacyFlags3.Op1Shift) & (uint)LegacyFlags3.OpMask)];
                op2Kind = opKinds[(int)((dword3 >> (int)LegacyFlags3.Op2Shift) & (uint)LegacyFlags3.OpMask)];
                op3Kind = opKinds[(int)((dword3 >> (int)LegacyFlags3.Op3Shift) & (uint)LegacyFlags3.OpMask)];

                mandatoryPrefix = (MandatoryPrefixByte)((dword2 >> (int)LegacyFlags.MandatoryPrefixShift) & (uint)LegacyFlags.MandatoryPrefixMask) switch {
                    MandatoryPrefixByte.None => (byte)((dword2 & (uint)LegacyFlags.HasMandatoryPrefix) != 0 ? MandatoryPrefix.PNP : MandatoryPrefix.None),
                    MandatoryPrefixByte.P66 => (byte)MandatoryPrefix.P66,
                    MandatoryPrefixByte.PF3 => (byte)MandatoryPrefix.PF3,
                    MandatoryPrefixByte.PF2 => (byte)MandatoryPrefix.PF2,
                    _ => throw new InvalidOperationException(),
                };

                table = (LegacyOpCodeTable)((dword2 >> (int)LegacyFlags.OpCodeTableShift) & (uint)LegacyFlags.OpCodeTableMask) switch {
                    LegacyOpCodeTable.Normal => (byte)OpCodeTableKind.Normal,
                    LegacyOpCodeTable.Table0F => (byte)OpCodeTableKind.T0F,
                    LegacyOpCodeTable.Table0F38 => (byte)OpCodeTableKind.T0F38,
                    LegacyOpCodeTable.Table0F3A => (byte)OpCodeTableKind.T0F3A,
                    _ => throw new InvalidOperationException(),
                };

                groupIndex = (sbyte)((dword2 & (uint)LegacyFlags.HasGroupIndex) == 0 ? -1 : (int)((dword2 >> (int)LegacyFlags.GroupShift) & 7));
                tupleType  = (byte)TupleType.None;

                if (!IsInstruction)
                {
                    flags |= Flags.Mode16 | Flags.Mode32 | Flags.Mode64;
                }
                else
                {
                    flags |= (Encodable)((dword2 >> (int)LegacyFlags.EncodableShift) & (uint)LegacyFlags.EncodableMask) switch {
                        Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                        Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                        Encodable.Only64 => Flags.Mode64,
                        _ => throw new InvalidOperationException(),
                    };
                }

                flags |= (AllowedPrefixes)((dword2 >> (int)LegacyFlags.AllowedPrefixesShift) & (uint)LegacyFlags.AllowedPrefixesMask) switch {
                    AllowedPrefixes.None => Flags.None,
                    AllowedPrefixes.Bnd => Flags.BndPrefix,
                    AllowedPrefixes.BndNotrack => Flags.BndPrefix | Flags.NotrackPrefix,
                    AllowedPrefixes.HintTakenBnd => Flags.HintTakenPrefix | Flags.BndPrefix,
                    AllowedPrefixes.Lock => Flags.LockPrefix,
                    AllowedPrefixes.Rep => Flags.RepPrefix,
                    AllowedPrefixes.RepeRepne => Flags.RepPrefix | Flags.RepnePrefix,
                    AllowedPrefixes.XacquireXreleaseLock => Flags.XacquirePrefix | Flags.XreleasePrefix | Flags.LockPrefix,
                    AllowedPrefixes.Xrelease => Flags.XreleasePrefix,
                    _ => throw new InvalidOperationException(),
                };
                if ((dword2 & (uint)LegacyFlags.Fwait) != 0)
                {
                    flags |= Flags.Fwait;
                }

                switch ((OperandSize)((dword2 >> (int)LegacyFlags.Legacy_OpSizeShift) & (uint)LegacyFlags.Legacy_OperandSizeMask))
                {
                case EncoderInternal.OperandSize.None:
                    operandSize = 0;
                    break;

                case EncoderInternal.OperandSize.Size16:
                    operandSize = 16;
                    break;

                case EncoderInternal.OperandSize.Size32:
                    operandSize = 32;
                    break;

                case EncoderInternal.OperandSize.Size64:
                    operandSize = 64;
                    break;
                }

                switch ((AddressSize)((dword2 >> (int)LegacyFlags.Legacy_AddrSizeShift) & (uint)LegacyFlags.Legacy_AddressSizeMask))
                {
                case EncoderInternal.AddressSize.None:
                    addressSize = 0;
                    break;

                case EncoderInternal.AddressSize.Size16:
                    addressSize = 16;
                    break;

                case EncoderInternal.AddressSize.Size32:
                    addressSize = 32;
                    break;

                case EncoderInternal.AddressSize.Size64:
                    addressSize = 64;
                    break;
                }

                l     = 0;
                lkind = LKind.None;
                break;

            case EncodingKind.VEX:
                opKinds = OpCodeOperandKinds.VexOpKinds;
                op0Kind = opKinds[(int)(dword3 & (uint)VexFlags3.OpMask)];
                op1Kind = opKinds[(int)((dword3 >> (int)VexFlags3.Op1Shift) & (uint)VexFlags3.OpMask)];
                op2Kind = opKinds[(int)((dword3 >> (int)VexFlags3.Op2Shift) & (uint)VexFlags3.OpMask)];
                op3Kind = opKinds[(int)((dword3 >> (int)VexFlags3.Op3Shift) & (uint)VexFlags3.OpMask)];
                op4Kind = opKinds[(int)((dword3 >> (int)VexFlags3.Op4Shift) & (uint)VexFlags3.OpMask)];

                mandatoryPrefix = (MandatoryPrefixByte)((dword2 >> (int)VexFlags.MandatoryPrefixShift) & (uint)VexFlags.MandatoryPrefixMask) switch {
                    MandatoryPrefixByte.None => (byte)MandatoryPrefix.PNP,
                    MandatoryPrefixByte.P66 => (byte)MandatoryPrefix.P66,
                    MandatoryPrefixByte.PF3 => (byte)MandatoryPrefix.PF3,
                    MandatoryPrefixByte.PF2 => (byte)MandatoryPrefix.PF2,
                    _ => throw new InvalidOperationException(),
                };

                table = (VexOpCodeTable)((dword2 >> (int)VexFlags.OpCodeTableShift) & (uint)VexFlags.OpCodeTableMask) switch {
                    VexOpCodeTable.Table0F => (byte)OpCodeTableKind.T0F,
                    VexOpCodeTable.Table0F38 => (byte)OpCodeTableKind.T0F38,
                    VexOpCodeTable.Table0F3A => (byte)OpCodeTableKind.T0F3A,
                    _ => throw new InvalidOperationException(),
                };

                groupIndex = (sbyte)((dword2 & (uint)VexFlags.HasGroupIndex) == 0 ? -1 : (int)((dword2 >> (int)VexFlags.GroupShift) & 7));
                tupleType  = (byte)TupleType.None;

                flags |= (Encodable)((dword2 >> (int)VexFlags.EncodableShift) & (uint)VexFlags.EncodableMask) switch {
                    Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                    Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                    Encodable.Only64 => Flags.Mode64,
                    _ => throw new InvalidOperationException(),
                };
                operandSize = 0;
                addressSize = 0;
                switch ((VexFlags)((dword2 >> (int)VexFlags.VEX_LShift) & (int)VexFlags.VEX_LMask))
                {
                case VexFlags.LZ:
                    lkind = LKind.LZ;
                    l     = 0;
                    break;

                case VexFlags.L0:
                    lkind = LKind.L0;
                    l     = 0;
                    break;

                case VexFlags.L1:
                    lkind = LKind.L0;
                    l     = 1;
                    break;

                case VexFlags.L128:
                    lkind = LKind.L128;
                    l     = 0;
                    break;

                case VexFlags.L256:
                    lkind = LKind.L128;
                    l     = 1;
                    break;

                case VexFlags.LIG:
                    lkind  = LKind.None;
                    l      = 0;
                    flags |= Flags.LIG;
                    break;

                default:
                    throw new InvalidOperationException();
                }

                if ((dword2 & (uint)VexFlags.VEX_W1) != 0)
                {
                    flags |= Flags.W;
                }
                if ((dword2 & (uint)VexFlags.VEX_WIG) != 0)
                {
                    flags |= Flags.WIG;
                }
                if ((dword2 & (uint)VexFlags.VEX_WIG32) != 0)
                {
                    flags |= Flags.WIG32;
                }
                break;

            case EncodingKind.EVEX:
                opKinds = OpCodeOperandKinds.EvexOpKinds;
                op0Kind = opKinds[(int)(dword3 & (uint)EvexFlags3.OpMask)];
                op1Kind = opKinds[(int)((dword3 >> (int)EvexFlags3.Op1Shift) & (uint)EvexFlags3.OpMask)];
                op2Kind = opKinds[(int)((dword3 >> (int)EvexFlags3.Op2Shift) & (uint)EvexFlags3.OpMask)];
                op3Kind = opKinds[(int)((dword3 >> (int)EvexFlags3.Op3Shift) & (uint)EvexFlags3.OpMask)];

                mandatoryPrefix = (MandatoryPrefixByte)((dword2 >> (int)EvexFlags.MandatoryPrefixShift) & (uint)EvexFlags.MandatoryPrefixMask) switch {
                    MandatoryPrefixByte.None => (byte)MandatoryPrefix.PNP,
                    MandatoryPrefixByte.P66 => (byte)MandatoryPrefix.P66,
                    MandatoryPrefixByte.PF3 => (byte)MandatoryPrefix.PF3,
                    MandatoryPrefixByte.PF2 => (byte)MandatoryPrefix.PF2,
                    _ => throw new InvalidOperationException(),
                };

                table = (EvexOpCodeTable)((dword2 >> (int)EvexFlags.OpCodeTableShift) & (uint)EvexFlags.OpCodeTableMask) switch {
                    EvexOpCodeTable.Table0F => (byte)OpCodeTableKind.T0F,
                    EvexOpCodeTable.Table0F38 => (byte)OpCodeTableKind.T0F38,
                    EvexOpCodeTable.Table0F3A => (byte)OpCodeTableKind.T0F3A,
                    _ => throw new InvalidOperationException(),
                };

                groupIndex = (sbyte)((dword2 & (uint)EvexFlags.HasGroupIndex) == 0 ? -1 : (int)((dword2 >> (int)EvexFlags.GroupShift) & 7));
                tupleType  = (byte)((dword2 >> (int)EvexFlags.TupleTypeShift) & (uint)EvexFlags.TupleTypeMask);

                flags |= (Encodable)((dword2 >> (int)EvexFlags.EncodableShift) & (uint)EvexFlags.EncodableMask) switch {
                    Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                    Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                    Encodable.Only64 => Flags.Mode64,
                    _ => throw new InvalidOperationException(),
                };
                operandSize = 0;
                addressSize = 0;
                l           = (byte)((dword2 >> (int)EvexFlags.EVEX_LShift) & 3);

                if ((dword2 & (uint)EvexFlags.EVEX_W1) != 0)
                {
                    flags |= Flags.W;
                }
                if ((dword2 & (uint)EvexFlags.EVEX_LIG) != 0)
                {
                    flags |= Flags.LIG;
                }
                if ((dword2 & (uint)EvexFlags.EVEX_WIG) != 0)
                {
                    flags |= Flags.WIG;
                }
                if ((dword2 & (uint)EvexFlags.EVEX_WIG32) != 0)
                {
                    flags |= Flags.WIG32;
                }
                if ((dword2 & (uint)EvexFlags.EVEX_b) != 0)
                {
                    flags |= Flags.Broadcast;
                }
                if ((dword2 & (uint)EvexFlags.EVEX_er) != 0)
                {
                    flags |= Flags.RoundingControl;
                }
                if ((dword2 & (uint)EvexFlags.EVEX_sae) != 0)
                {
                    flags |= Flags.SuppressAllExceptions;
                }
                if ((dword2 & (uint)EvexFlags.EVEX_k1) != 0)
                {
                    flags |= Flags.OpMaskRegister;
                }
                if ((dword2 & (uint)EvexFlags.EVEX_z) != 0)
                {
                    flags |= Flags.ZeroingMasking;
                }
                lkind = LKind.L128;
                switch (code)
                {
                case Code.EVEX_Vpgatherdd_xmm_k1_vm32x:
                case Code.EVEX_Vpgatherdd_ymm_k1_vm32y:
                case Code.EVEX_Vpgatherdd_zmm_k1_vm32z:
                case Code.EVEX_Vpgatherdq_xmm_k1_vm32x:
                case Code.EVEX_Vpgatherdq_ymm_k1_vm32x:
                case Code.EVEX_Vpgatherdq_zmm_k1_vm32y:
                case Code.EVEX_Vpgatherqd_xmm_k1_vm64x:
                case Code.EVEX_Vpgatherqd_xmm_k1_vm64y:
                case Code.EVEX_Vpgatherqd_ymm_k1_vm64z:
                case Code.EVEX_Vpgatherqq_xmm_k1_vm64x:
                case Code.EVEX_Vpgatherqq_ymm_k1_vm64y:
                case Code.EVEX_Vpgatherqq_zmm_k1_vm64z:
                case Code.EVEX_Vgatherdps_xmm_k1_vm32x:
                case Code.EVEX_Vgatherdps_ymm_k1_vm32y:
                case Code.EVEX_Vgatherdps_zmm_k1_vm32z:
                case Code.EVEX_Vgatherdpd_xmm_k1_vm32x:
                case Code.EVEX_Vgatherdpd_ymm_k1_vm32x:
                case Code.EVEX_Vgatherdpd_zmm_k1_vm32y:
                case Code.EVEX_Vgatherqps_xmm_k1_vm64x:
                case Code.EVEX_Vgatherqps_xmm_k1_vm64y:
                case Code.EVEX_Vgatherqps_ymm_k1_vm64z:
                case Code.EVEX_Vgatherqpd_xmm_k1_vm64x:
                case Code.EVEX_Vgatherqpd_ymm_k1_vm64y:
                case Code.EVEX_Vgatherqpd_zmm_k1_vm64z:
                case Code.EVEX_Vpscatterdd_vm32x_k1_xmm:
                case Code.EVEX_Vpscatterdd_vm32y_k1_ymm:
                case Code.EVEX_Vpscatterdd_vm32z_k1_zmm:
                case Code.EVEX_Vpscatterdq_vm32x_k1_xmm:
                case Code.EVEX_Vpscatterdq_vm32x_k1_ymm:
                case Code.EVEX_Vpscatterdq_vm32y_k1_zmm:
                case Code.EVEX_Vpscatterqd_vm64x_k1_xmm:
                case Code.EVEX_Vpscatterqd_vm64y_k1_xmm:
                case Code.EVEX_Vpscatterqd_vm64z_k1_ymm:
                case Code.EVEX_Vpscatterqq_vm64x_k1_xmm:
                case Code.EVEX_Vpscatterqq_vm64y_k1_ymm:
                case Code.EVEX_Vpscatterqq_vm64z_k1_zmm:
                case Code.EVEX_Vscatterdps_vm32x_k1_xmm:
                case Code.EVEX_Vscatterdps_vm32y_k1_ymm:
                case Code.EVEX_Vscatterdps_vm32z_k1_zmm:
                case Code.EVEX_Vscatterdpd_vm32x_k1_xmm:
                case Code.EVEX_Vscatterdpd_vm32x_k1_ymm:
                case Code.EVEX_Vscatterdpd_vm32y_k1_zmm:
                case Code.EVEX_Vscatterqps_vm64x_k1_xmm:
                case Code.EVEX_Vscatterqps_vm64y_k1_xmm:
                case Code.EVEX_Vscatterqps_vm64z_k1_ymm:
                case Code.EVEX_Vscatterqpd_vm64x_k1_xmm:
                case Code.EVEX_Vscatterqpd_vm64y_k1_ymm:
                case Code.EVEX_Vscatterqpd_vm64z_k1_zmm:
                case Code.EVEX_Vgatherpf0dps_vm32z_k1:
                case Code.EVEX_Vgatherpf0dpd_vm32y_k1:
                case Code.EVEX_Vgatherpf1dps_vm32z_k1:
                case Code.EVEX_Vgatherpf1dpd_vm32y_k1:
                case Code.EVEX_Vscatterpf0dps_vm32z_k1:
                case Code.EVEX_Vscatterpf0dpd_vm32y_k1:
                case Code.EVEX_Vscatterpf1dps_vm32z_k1:
                case Code.EVEX_Vscatterpf1dpd_vm32y_k1:
                case Code.EVEX_Vgatherpf0qps_vm64z_k1:
                case Code.EVEX_Vgatherpf0qpd_vm64z_k1:
                case Code.EVEX_Vgatherpf1qps_vm64z_k1:
                case Code.EVEX_Vgatherpf1qpd_vm64z_k1:
                case Code.EVEX_Vscatterpf0qps_vm64z_k1:
                case Code.EVEX_Vscatterpf0qpd_vm64z_k1:
                case Code.EVEX_Vscatterpf1qps_vm64z_k1:
                case Code.EVEX_Vscatterpf1qpd_vm64z_k1:
                    flags |= Flags.NonZeroOpMaskRegister;
                    break;
                }
                break;

            case EncodingKind.XOP:
                opKinds = OpCodeOperandKinds.XopOpKinds;
                op0Kind = opKinds[(int)(dword3 & (uint)XopFlags3.OpMask)];
                op1Kind = opKinds[(int)((dword3 >> (int)XopFlags3.Op1Shift) & (uint)XopFlags3.OpMask)];
                op2Kind = opKinds[(int)((dword3 >> (int)XopFlags3.Op2Shift) & (uint)XopFlags3.OpMask)];
                op3Kind = opKinds[(int)((dword3 >> (int)XopFlags3.Op3Shift) & (uint)XopFlags3.OpMask)];

                mandatoryPrefix = (MandatoryPrefixByte)((dword2 >> (int)XopFlags.MandatoryPrefixShift) & (uint)XopFlags.MandatoryPrefixMask) switch {
                    MandatoryPrefixByte.None => (byte)MandatoryPrefix.PNP,
                    MandatoryPrefixByte.P66 => (byte)MandatoryPrefix.P66,
                    MandatoryPrefixByte.PF3 => (byte)MandatoryPrefix.PF3,
                    MandatoryPrefixByte.PF2 => (byte)MandatoryPrefix.PF2,
                    _ => throw new InvalidOperationException(),
                };

                table = (XopOpCodeTable)((dword2 >> (int)XopFlags.OpCodeTableShift) & (uint)XopFlags.OpCodeTableMask) switch {
                    XopOpCodeTable.XOP8 => (byte)OpCodeTableKind.XOP8,
                    XopOpCodeTable.XOP9 => (byte)OpCodeTableKind.XOP9,
                    XopOpCodeTable.XOPA => (byte)OpCodeTableKind.XOPA,
                    _ => throw new InvalidOperationException(),
                };

                groupIndex = (sbyte)((dword2 & (uint)XopFlags.HasGroupIndex) == 0 ? -1 : (int)((dword2 >> (int)XopFlags.GroupShift) & 7));
                tupleType  = (byte)TupleType.None;

                flags |= (Encodable)((dword2 >> (int)XopFlags.EncodableShift) & (uint)XopFlags.EncodableMask) switch {
                    Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                    Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                    Encodable.Only64 => Flags.Mode64,
                    _ => throw new InvalidOperationException(),
                };
                operandSize = 0;
                addressSize = 0;
                l           = (byte)((dword2 >> (int)XopFlags.XOP_LShift) & 1);

                if ((dword2 & (uint)XopFlags.XOP_W1) != 0)
                {
                    flags |= Flags.W;
                }
                if ((dword2 & (uint)XopFlags.XOP_WIG32) != 0)
                {
                    flags |= Flags.WIG32;
                }
                lkind = (dword2 & (uint)XopFlags.XOP_L0_L1) != 0 ? LKind.L0 : LKind.L128;
                break;

            case EncodingKind.D3NOW:
                op0Kind         = (byte)OpCodeOperandKind.mm_reg;
                op1Kind         = (byte)OpCodeOperandKind.mm_or_mem;
                mandatoryPrefix = (byte)MandatoryPrefix.None;
                table           = (byte)OpCodeTableKind.T0F;
                groupIndex      = -1;
                tupleType       = (byte)TupleType.None;

                flags |= (Encodable)((dword2 >> (int)D3nowFlags.EncodableShift) & (uint)D3nowFlags.EncodableMask) switch {
                    Encodable.Any => Flags.Mode16 | Flags.Mode32 | Flags.Mode64,
                    Encodable.Only1632 => Flags.Mode16 | Flags.Mode32,
                    Encodable.Only64 => Flags.Mode64,
                    _ => throw new InvalidOperationException(),
                };
                operandSize = 0;
                addressSize = 0;
                l           = 0;
                lkind       = LKind.None;
                break;

            default:
                throw new InvalidOperationException();
            }

            toOpCodeStringValue      = new OpCodeFormatter(this, sb, lkind).Format();
            toInstructionStringValue = new InstructionFormatter(this, sb).Format();
        }