Beispiel #1
0
        static DecoderTestCase ReadTestCase(int bitness, string line, int lineNumber)
        {
            var parts = line.Split(seps);

            if (parts.Length != 5)
            {
                throw new InvalidOperationException($"Invalid number of commas ({parts.Length - 1} commas)");
            }

            var tc = new DecoderTestCase();

            tc.LineNumber      = lineNumber;
            tc.TestOptions     = DecoderTestOptions.None;
            tc.Bitness         = bitness;
            tc.HexBytes        = ToHexBytes(parts[0].Trim());
            tc.EncodedHexBytes = tc.HexBytes;
            var code = parts[1].Trim();

            if (CodeUtils.IsIgnored(code))
            {
                return(null);
            }
            tc.Code         = ToCode(code);
            tc.Mnemonic     = ToMnemonic(parts[2].Trim());
            tc.OpCount      = NumberConverter.ToInt32(parts[3].Trim());
            tc.DecoderError = tc.Code == Code.INVALID ? DecoderError.InvalidInstruction : DecoderError.None;

            bool foundCode = false;

            foreach (var tmp in parts[4].Split(extraSeps))
            {
                if (tmp == string.Empty)
                {
                    continue;
                }
                var    key = tmp;
                string value;
                int    index = key.IndexOf('=');
                if (index >= 0)
                {
                    value = key.Substring(index + 1);
                    key   = key.Substring(0, index);
                }
                else
                {
                    value = null;
                }
                switch (key)
                {
                case DecoderTestParserConstants.DecoderError:
                    if (value is null)
                    {
                        throw new InvalidOperationException($"Missing decoder error value");
                    }
                    if (!ToEnumConverter.TryDecoderError(value, out tc.DecoderError))
                    {
                        throw new InvalidOperationException($"Invalid decoder error value: {value}");
                    }
                    break;

                case DecoderTestParserConstants.Broadcast:
                    tc.IsBroadcast = true;
                    break;

                case DecoderTestParserConstants.Xacquire:
                    tc.HasXacquirePrefix = true;
                    break;

                case DecoderTestParserConstants.Xrelease:
                    tc.HasXreleasePrefix = true;
                    break;

                case DecoderTestParserConstants.Rep:
                case DecoderTestParserConstants.Repe:
                    tc.HasRepePrefix = true;
                    break;

                case DecoderTestParserConstants.Repne:
                    tc.HasRepnePrefix = true;
                    break;

                case DecoderTestParserConstants.Lock:
                    tc.HasLockPrefix = true;
                    break;

                case DecoderTestParserConstants.ZeroingMasking:
                    tc.ZeroingMasking = true;
                    break;

                case DecoderTestParserConstants.SuppressAllExceptions:
                    tc.SuppressAllExceptions = true;
                    break;

                case DecoderTestParserConstants.Vsib32:
                    tc.VsibBitness = 32;
                    break;

                case DecoderTestParserConstants.Vsib64:
                    tc.VsibBitness = 64;
                    break;

                case DecoderTestParserConstants.RoundToNearest:
                    tc.RoundingControl = RoundingControl.RoundToNearest;
                    break;

                case DecoderTestParserConstants.RoundDown:
                    tc.RoundingControl = RoundingControl.RoundDown;
                    break;

                case DecoderTestParserConstants.RoundUp:
                    tc.RoundingControl = RoundingControl.RoundUp;
                    break;

                case DecoderTestParserConstants.RoundTowardZero:
                    tc.RoundingControl = RoundingControl.RoundTowardZero;
                    break;

                case DecoderTestParserConstants.Op0Kind:
                    if (tc.OpCount < 1)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 1");
                    }
                    ReadOpKind(tc, 0, value);
                    break;

                case DecoderTestParserConstants.Op1Kind:
                    if (tc.OpCount < 2)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 2");
                    }
                    ReadOpKind(tc, 1, value);
                    break;

                case DecoderTestParserConstants.Op2Kind:
                    if (tc.OpCount < 3)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 3");
                    }
                    ReadOpKind(tc, 2, value);
                    break;

                case DecoderTestParserConstants.Op3Kind:
                    if (tc.OpCount < 4)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 4");
                    }
                    ReadOpKind(tc, 3, value);
                    break;

                case DecoderTestParserConstants.Op4Kind:
                    if (tc.OpCount < 5)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 5");
                    }
                    ReadOpKind(tc, 4, value);
                    break;

                case DecoderTestParserConstants.EncodedHexBytes:
                    if (string.IsNullOrWhiteSpace(value))
                    {
                        throw new InvalidOperationException($"Invalid encoded hex bytes: '{value}'");
                    }
                    tc.EncodedHexBytes = ToHexBytes(value);
                    break;

                case DecoderTestParserConstants.Code:
                    if (string.IsNullOrWhiteSpace(value))
                    {
                        throw new InvalidOperationException($"Invalid Code value: '{value}'");
                    }
                    if (CodeUtils.IsIgnored(value))
                    {
                        return(null);
                    }
                    foundCode = true;
                    break;

                case DecoderTestParserConstants.DecoderOptions_AMD:
                    tc.DecoderOptions |= DecoderOptions.AMD;
                    break;

                case DecoderTestParserConstants.DecoderOptions_ForceReservedNop:
                    tc.DecoderOptions |= DecoderOptions.ForceReservedNop;
                    break;

                case DecoderTestParserConstants.DecoderOptions_Umov:
                    tc.DecoderOptions |= DecoderOptions.Umov;
                    break;

                case DecoderTestParserConstants.DecoderOptions_Xbts:
                    tc.DecoderOptions |= DecoderOptions.Xbts;
                    break;

                case DecoderTestParserConstants.DecoderOptions_Cmpxchg486A:
                    tc.DecoderOptions |= DecoderOptions.Cmpxchg486A;
                    break;

                case DecoderTestParserConstants.DecoderOptions_OldFpu:
                    tc.DecoderOptions |= DecoderOptions.OldFpu;
                    break;

                case DecoderTestParserConstants.DecoderOptions_Pcommit:
                    tc.DecoderOptions |= DecoderOptions.Pcommit;
                    break;

                case DecoderTestParserConstants.DecoderOptions_Loadall286:
                    tc.DecoderOptions |= DecoderOptions.Loadall286;
                    break;

                case DecoderTestParserConstants.DecoderOptions_Loadall386:
                    tc.DecoderOptions |= DecoderOptions.Loadall386;
                    break;

                case DecoderTestParserConstants.DecoderOptions_Cl1invmb:
                    tc.DecoderOptions |= DecoderOptions.Cl1invmb;
                    break;

                case DecoderTestParserConstants.DecoderOptions_MovTr:
                    tc.DecoderOptions |= DecoderOptions.MovTr;
                    break;

                case DecoderTestParserConstants.DecoderOptions_Jmpe:
                    tc.DecoderOptions |= DecoderOptions.Jmpe;
                    break;

                case DecoderTestParserConstants.DecoderOptions_NoPause:
                    tc.DecoderOptions |= DecoderOptions.NoPause;
                    break;

                case DecoderTestParserConstants.DecoderOptions_NoWbnoinvd:
                    tc.DecoderOptions |= DecoderOptions.NoWbnoinvd;
                    break;

                case DecoderTestParserConstants.DecoderOptions_NoLockMovCR0:
                    tc.DecoderOptions |= DecoderOptions.NoLockMovCR0;
                    break;

                case DecoderTestParserConstants.DecoderOptions_NoMPFX_0FBC:
                    tc.DecoderOptions |= DecoderOptions.NoMPFX_0FBC;
                    break;

                case DecoderTestParserConstants.DecoderOptions_NoMPFX_0FBD:
                    tc.DecoderOptions |= DecoderOptions.NoMPFX_0FBD;
                    break;

                case DecoderTestParserConstants.DecoderOptions_NoLahfSahf64:
                    tc.DecoderOptions |= DecoderOptions.NoLahfSahf64;
                    break;

                case DecoderTestParserConstants.DecoderOptions_NoInvalidCheck:
                    tc.DecoderOptions |= DecoderOptions.NoInvalidCheck;
                    break;

                case DecoderTestParserConstants.DecoderOptions_MPX:
                    tc.DecoderOptions |= DecoderOptions.MPX;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_ES:
                    tc.SegmentPrefix = Register.ES;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_CS:
                    tc.SegmentPrefix = Register.CS;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_SS:
                    tc.SegmentPrefix = Register.SS;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_DS:
                    tc.SegmentPrefix = Register.DS;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_FS:
                    tc.SegmentPrefix = Register.FS;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_GS:
                    tc.SegmentPrefix = Register.GS;
                    break;

                case DecoderTestParserConstants.OpMask_k1:
                    tc.OpMask = Register.K1;
                    break;

                case DecoderTestParserConstants.OpMask_k2:
                    tc.OpMask = Register.K2;
                    break;

                case DecoderTestParserConstants.OpMask_k3:
                    tc.OpMask = Register.K3;
                    break;

                case DecoderTestParserConstants.OpMask_k4:
                    tc.OpMask = Register.K4;
                    break;

                case DecoderTestParserConstants.OpMask_k5:
                    tc.OpMask = Register.K5;
                    break;

                case DecoderTestParserConstants.OpMask_k6:
                    tc.OpMask = Register.K6;
                    break;

                case DecoderTestParserConstants.OpMask_k7:
                    tc.OpMask = Register.K7;
                    break;

                case DecoderTestParserConstants.ConstantOffsets:
                    if (!TryParseConstantOffsets(value, out tc.ConstantOffsets))
                    {
                        throw new InvalidOperationException($"Invalid ConstantOffsets: '{value}'");
                    }
                    break;

                case DecoderTestParserConstants.DecoderTestOptions_NoEncode:
                    tc.TestOptions |= DecoderTestOptions.NoEncode;
                    break;

                case DecoderTestParserConstants.DecoderTestOptions_NoOptDisableTest:
                    tc.TestOptions |= DecoderTestOptions.NoOptDisableTest;
                    break;

                default:
                    throw new InvalidOperationException($"Invalid key '{key}'");
                }
            }

            if (tc.Code == Code.INVALID && !foundCode)
            {
                throw new InvalidOperationException($"Test case decodes to {nameof(Code.INVALID)} but there's no {DecoderTestParserConstants.Code}=xxx showing the original {nameof(Code)} value so it can be filtered out if needed");
            }

            return(tc);
        }
Beispiel #2
0
        static DecoderTestCase ReadTestCase(int bitness, string line, int lineNumber)
        {
            var parts = line.Split(seps);

            if (parts.Length != 5)
            {
                throw new InvalidOperationException($"Invalid number of commas ({parts.Length - 1} commas)");
            }

            var tc = new DecoderTestCase();

            tc.LineNumber  = lineNumber;
            tc.TestOptions = DecoderTestOptions.None;
            tc.Bitness     = bitness;
            tc.IP          = bitness switch {
                16 => DecoderConstants.DEFAULT_IP16,
                32 => DecoderConstants.DEFAULT_IP32,
                64 => DecoderConstants.DEFAULT_IP64,
                _ => throw new InvalidOperationException(),
            };
            tc.HexBytes        = ToHexBytes(parts[0].Trim());
            tc.EncodedHexBytes = tc.HexBytes;
            var code = parts[1].Trim();

            if (CodeUtils.IsIgnored(code))
            {
                return(null);
            }
            tc.Code         = ToCode(code);
            tc.Mnemonic     = ToMnemonic(parts[2].Trim());
            tc.OpCount      = NumberConverter.ToInt32(parts[3].Trim());
            tc.DecoderError = tc.Code == Code.INVALID ? DecoderError.InvalidInstruction : DecoderError.None;

            bool foundCode = false;

            foreach (var tmp in parts[4].Split(extraSeps))
            {
                if (tmp == string.Empty)
                {
                    continue;
                }
                var    key = tmp;
                string value;
                int    index = key.IndexOf('=');
                if (index >= 0)
                {
                    value = key.Substring(index + 1);
                    key   = key.Substring(0, index);
                }
                else
                {
                    value = null;
                }
                switch (key)
                {
                case DecoderTestParserConstants.DecoderError:
                    if (value is null)
                    {
                        throw new InvalidOperationException($"Missing decoder error value");
                    }
                    if (!ToEnumConverter.TryDecoderError(value, out tc.DecoderError))
                    {
                        throw new InvalidOperationException($"Invalid decoder error value: {value}");
                    }
                    break;

                case DecoderTestParserConstants.Broadcast:
                    tc.IsBroadcast = true;
                    break;

                case DecoderTestParserConstants.Xacquire:
                    tc.HasXacquirePrefix = true;
                    break;

                case DecoderTestParserConstants.Xrelease:
                    tc.HasXreleasePrefix = true;
                    break;

                case DecoderTestParserConstants.Rep:
                case DecoderTestParserConstants.Repe:
                    tc.HasRepePrefix = true;
                    break;

                case DecoderTestParserConstants.Repne:
                    tc.HasRepnePrefix = true;
                    break;

                case DecoderTestParserConstants.Lock:
                    tc.HasLockPrefix = true;
                    break;

                case DecoderTestParserConstants.ZeroingMasking:
                    tc.ZeroingMasking = true;
                    break;

                case DecoderTestParserConstants.SuppressAllExceptions:
                    tc.SuppressAllExceptions = true;
                    break;

                case DecoderTestParserConstants.Vsib32:
                    tc.VsibBitness = 32;
                    break;

                case DecoderTestParserConstants.Vsib64:
                    tc.VsibBitness = 64;
                    break;

                case DecoderTestParserConstants.RoundToNearest:
                    tc.RoundingControl = RoundingControl.RoundToNearest;
                    break;

                case DecoderTestParserConstants.RoundDown:
                    tc.RoundingControl = RoundingControl.RoundDown;
                    break;

                case DecoderTestParserConstants.RoundUp:
                    tc.RoundingControl = RoundingControl.RoundUp;
                    break;

                case DecoderTestParserConstants.RoundTowardZero:
                    tc.RoundingControl = RoundingControl.RoundTowardZero;
                    break;

                case DecoderTestParserConstants.Op0Kind:
                    if (tc.OpCount < 1)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 1");
                    }
                    ReadOpKind(tc, 0, value);
                    break;

                case DecoderTestParserConstants.Op1Kind:
                    if (tc.OpCount < 2)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 2");
                    }
                    ReadOpKind(tc, 1, value);
                    break;

                case DecoderTestParserConstants.Op2Kind:
                    if (tc.OpCount < 3)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 3");
                    }
                    ReadOpKind(tc, 2, value);
                    break;

                case DecoderTestParserConstants.Op3Kind:
                    if (tc.OpCount < 4)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 4");
                    }
                    ReadOpKind(tc, 3, value);
                    break;

                case DecoderTestParserConstants.Op4Kind:
                    if (tc.OpCount < 5)
                    {
                        throw new InvalidOperationException($"Invalid OpCount: {tc.OpCount} < 5");
                    }
                    ReadOpKind(tc, 4, value);
                    break;

                case DecoderTestParserConstants.EncodedHexBytes:
                    if (string.IsNullOrWhiteSpace(value))
                    {
                        throw new InvalidOperationException($"Invalid encoded hex bytes: '{value}'");
                    }
                    tc.EncodedHexBytes = ToHexBytes(value);
                    break;

                case DecoderTestParserConstants.Code:
                    if (string.IsNullOrWhiteSpace(value))
                    {
                        throw new InvalidOperationException($"Invalid Code value: '{value}'");
                    }
                    if (CodeUtils.IsIgnored(value))
                    {
                        return(null);
                    }
                    foundCode = true;
                    break;

                case DecoderTestParserConstants.DecoderOptions:
                    if (string.IsNullOrWhiteSpace(value))
                    {
                        throw new InvalidOperationException($"Invalid DecoderOption value: '{value}'");
                    }
                    if (!TryParseDecoderOptions(value.Split(semicolonSeparator), ref tc.DecoderOptions))
                    {
                        throw new Exception($"Invalid DecoderOptions value, '{value}'");
                    }
                    break;

                case DecoderTestParserConstants.IP:
                    if (string.IsNullOrWhiteSpace(value))
                    {
                        throw new InvalidOperationException($"Invalid IP value: '{value}'");
                    }
                    tc.IP = NumberConverter.ToUInt64(value);
                    break;

                case DecoderTestParserConstants.EvictionHint:
#if MVEX
                    tc.Mvex.EvictionHint = true;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_RegSwizzleNone:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.RegSwizzleNone;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_RegSwizzleCdab:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.RegSwizzleCdab;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_RegSwizzleBadc:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.RegSwizzleBadc;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_RegSwizzleDacb:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.RegSwizzleDacb;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_RegSwizzleAaaa:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.RegSwizzleAaaa;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_RegSwizzleBbbb:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.RegSwizzleBbbb;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_RegSwizzleCccc:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.RegSwizzleCccc;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_RegSwizzleDddd:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.RegSwizzleDddd;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_MemConvNone:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.MemConvNone;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_MemConvBroadcast1:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.MemConvBroadcast1;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_MemConvBroadcast4:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.MemConvBroadcast4;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_MemConvFloat16:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.MemConvFloat16;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_MemConvUint8:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.MemConvUint8;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_MemConvSint8:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.MemConvSint8;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_MemConvUint16:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.MemConvUint16;
                    break;
#else
                    throw new InvalidOperationException();
#endif

                case DecoderTestParserConstants.MVEX_MemConvSint16:
#if MVEX
                    tc.Mvex.RegMemConv = MvexRegMemConv.MemConvSint16;
                    break;
#else
                    throw new InvalidOperationException();
#endif


                case DecoderTestParserConstants.SegmentPrefix_ES:
                    tc.SegmentPrefix = Register.ES;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_CS:
                    tc.SegmentPrefix = Register.CS;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_SS:
                    tc.SegmentPrefix = Register.SS;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_DS:
                    tc.SegmentPrefix = Register.DS;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_FS:
                    tc.SegmentPrefix = Register.FS;
                    break;

                case DecoderTestParserConstants.SegmentPrefix_GS:
                    tc.SegmentPrefix = Register.GS;
                    break;

                case DecoderTestParserConstants.OpMask_k1:
                    tc.OpMask = Register.K1;
                    break;

                case DecoderTestParserConstants.OpMask_k2:
                    tc.OpMask = Register.K2;
                    break;

                case DecoderTestParserConstants.OpMask_k3:
                    tc.OpMask = Register.K3;
                    break;

                case DecoderTestParserConstants.OpMask_k4:
                    tc.OpMask = Register.K4;
                    break;

                case DecoderTestParserConstants.OpMask_k5:
                    tc.OpMask = Register.K5;
                    break;

                case DecoderTestParserConstants.OpMask_k6:
                    tc.OpMask = Register.K6;
                    break;

                case DecoderTestParserConstants.OpMask_k7:
                    tc.OpMask = Register.K7;
                    break;

                case DecoderTestParserConstants.ConstantOffsets:
                    if (!TryParseConstantOffsets(value, out tc.ConstantOffsets))
                    {
                        throw new InvalidOperationException($"Invalid ConstantOffsets: '{value}'");
                    }
                    break;

                case DecoderTestParserConstants.DecoderTestOptions_NoEncode:
                    tc.TestOptions |= DecoderTestOptions.NoEncode;
                    break;

                case DecoderTestParserConstants.DecoderTestOptions_NoOptDisableTest:
                    tc.TestOptions |= DecoderTestOptions.NoOptDisableTest;
                    break;

                default:
                    throw new InvalidOperationException($"Invalid key '{key}'");
                }
            }

            if (tc.Code == Code.INVALID && !foundCode)
            {
                throw new InvalidOperationException($"Test case decodes to {nameof(Code.INVALID)} but there's no {DecoderTestParserConstants.Code}=xxx showing the original {nameof(Code)} value so it can be filtered out if needed");
            }

            return(tc);
        }