Exemplo n.º 1
0
        public static HashSet <Code> Read(string name)
        {
            var filename   = PathUtils.GetTestTextFilename(name, "Decoder");
            int lineNumber = 0;
            var hash       = new HashSet <Code>();

            foreach (var line in File.ReadLines(filename))
            {
                lineNumber++;
                if (line.Length == 0 || line[0] == '#')
                {
                    continue;
                }
                var value = line.Trim();
                if (CodeUtils.IsIgnored(value))
                {
                    continue;
                }
                if (!ToEnumConverter.TryCode(value, out var code))
                {
                    throw new InvalidOperationException($"Error parsing Code file '{filename}', line {lineNumber}: Invalid value: {value}");
                }
                hash.Add(code);
            }
            return(hash);
        }
Exemplo n.º 2
0
        protected void TestOptionsBase(FormatterOptions options)
        {
            {
                int min = int.MaxValue, max = int.MinValue;
                foreach (var value in ToEnumConverter.GetNumberBaseValues())
                {
                    min = Math.Min(min, (int)value);
                    max = Math.Max(max, (int)value);
                    options.NumberBase = value;
                }
                Assert.Throws <ArgumentOutOfRangeException>(() => options.NumberBase = (NumberBase)(min - 1));
                Assert.Throws <ArgumentOutOfRangeException>(() => options.NumberBase = (NumberBase)(max + 1));
                Assert.Throws <ArgumentOutOfRangeException>(() => options.NumberBase = (NumberBase)int.MinValue);
                Assert.Throws <ArgumentOutOfRangeException>(() => options.NumberBase = (NumberBase)int.MaxValue);
            }

            {
                int min = int.MaxValue, max = int.MinValue;
                foreach (var value in ToEnumConverter.GetMemorySizeOptionsValues())
                {
                    min = Math.Min(min, (int)value);
                    max = Math.Max(max, (int)value);
                    options.MemorySizeOptions = value;
                }
                Assert.Throws <ArgumentOutOfRangeException>(() => options.MemorySizeOptions = (MemorySizeOptions)(min - 1));
                Assert.Throws <ArgumentOutOfRangeException>(() => options.MemorySizeOptions = (MemorySizeOptions)(max + 1));
                Assert.Throws <ArgumentOutOfRangeException>(() => options.MemorySizeOptions = (MemorySizeOptions)int.MinValue);
                Assert.Throws <ArgumentOutOfRangeException>(() => options.MemorySizeOptions = (MemorySizeOptions)int.MaxValue);
            }
        }
Exemplo n.º 3
0
        void Make_sure_all_Code_values_are_tested_exactly_once()
        {
            var tested = new bool[IcedConstants.CodeEnumCount];

            foreach (var info in OpCodeInfoTestCases.OpCodeInfoTests)
            {
                Assert.False(tested[(int)info.Code]);
                tested[(int)info.Code] = true;
            }
            var sb        = new StringBuilder();
            var codeNames = ToEnumConverter.GetCodeNames();

            for (int i = 0; i < tested.Length; i++)
            {
                if (!tested[i] && !CodeUtils.IsIgnored(codeNames[i]))
                {
                    if (sb.Length > 0)
                    {
                        sb.Append(',');
                    }
                    sb.Append(codeNames[i]);
                }
            }
            Assert.Equal(string.Empty, sb.ToString());
        }
Exemplo n.º 4
0
        static DecoderMemoryTestCase ReadTestCase(int bitness, string line, int lineNumber)
        {
            var parts = line.Split(colSep, StringSplitOptions.None);

            if (parts.Length != 11 && parts.Length != 12)
            {
                throw new InvalidOperationException();
            }
            var tc = new DecoderMemoryTestCase();

            tc.LineNumber       = lineNumber;
            tc.Bitness          = bitness;
            tc.HexBytes         = parts[0].Trim();
            tc.Code             = ToEnumConverter.GetCode(parts[1].Trim());
            tc.Register         = ToEnumConverter.GetRegister(parts[2].Trim());
            tc.SegmentPrefix    = ToEnumConverter.GetRegister(parts[3].Trim());
            tc.SegmentRegister  = ToEnumConverter.GetRegister(parts[4].Trim());
            tc.BaseRegister     = ToEnumConverter.GetRegister(parts[5].Trim());
            tc.IndexRegister    = ToEnumConverter.GetRegister(parts[6].Trim());
            tc.Scale            = (int)ParseUInt32(parts[7].Trim());
            tc.Displacement     = ParseUInt32(parts[8].Trim());
            tc.DisplacementSize = (int)ParseUInt32(parts[9].Trim());
            var coStr = parts[10].Trim();

            if (!DecoderTestParser.TryParseConstantOffsets(coStr, out tc.ConstantOffsets))
            {
                throw new InvalidOperationException($"Invalid ConstantOffsets: '{coStr}'");
            }
            tc.EncodedHexBytes = parts.Length > 11 ? parts[11].Trim() : tc.HexBytes;
            tc.DecoderOptions  = DecoderOptions.None;
            tc.CanEncode       = true;
            return(tc);
        }
Exemplo n.º 5
0
        static MnemonicOptionsTestCase ParseLine(string line)
        {
            var elems = line.Split(commaSeparator);

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

            var hexBytes        = elems[0].Trim();
            var code            = ToEnumConverter.GetCode(elems[1].Trim());
            var bitness         = NumberConverter.ToInt32(elems[2].Trim());
            var formattedString = elems[3].Trim().Replace('|', ',');
            var flags           = FormatMnemonicOptions.None;

            foreach (var value in elems[4].Split(spaceSeparator, StringSplitOptions.RemoveEmptyEntries))
            {
                if (!Dicts.ToFormatMnemonicOptions.TryGetValue(value, out var f))
                {
                    throw new InvalidOperationException($"Invalid flags value: {value}");
                }
                flags |= f;
            }
            return(new MnemonicOptionsTestCase(hexBytes, code, bitness, formattedString, flags));
        }
Exemplo n.º 6
0
        void Verify_encoding_is_part_of_Code_name()
        {
            var codeNames = ToEnumConverter.GetCodeNames();

            for (int i = 0; i < IcedConstants.NumberOfCodeValues; i++)
            {
                var codeName = codeNames[i];
                if (CodeUtils.IsIgnored(codeName))
                {
                    continue;
                }
                var code   = (Code)i;
                var prefix = code.ToOpCode().Encoding switch {
                    EncodingKind.Legacy => string.Empty,
                    EncodingKind.VEX => "VEX_",
                    EncodingKind.EVEX => "EVEX_",
                    EncodingKind.XOP => "XOP_",
                    EncodingKind.D3NOW => "D3NOW_",
                    _ => throw new InvalidOperationException(),
                };
                if (prefix != string.Empty)
                {
                    Assert.StartsWith(prefix, codeName, StringComparison.Ordinal);
                }
            }
        }
Exemplo n.º 7
0
        static MemorySizeInfoTestCase ParseLine(string line, int lineNo)
        {
            Static.Assert(MiscInstrInfoTestConstants.MemorySizeElemsPerLine == 6 ? 0 : -1);
            var elems = line.Split(commaSeparator, MiscInstrInfoTestConstants.MemorySizeElemsPerLine);

            if (elems.Length != MiscInstrInfoTestConstants.MemorySizeElemsPerLine)
            {
                throw new Exception($"Expected {MiscInstrInfoTestConstants.MemorySizeElemsPerLine - 1} commas");
            }

            var tc = new MemorySizeInfoTestCase();

            tc.LineNumber   = lineNo;
            tc.MemorySize   = ToEnumConverter.GetMemorySize(elems[0].Trim());
            tc.Size         = NumberConverter.ToInt32(elems[1].Trim());
            tc.ElementSize  = NumberConverter.ToInt32(elems[2].Trim());
            tc.ElementType  = ToEnumConverter.GetMemorySize(elems[3].Trim());
            tc.ElementCount = NumberConverter.ToInt32(elems[4].Trim());
            foreach (var value in elems[5].Split(spaceSeparator, StringSplitOptions.RemoveEmptyEntries))
            {
                if (!InstructionInfoDicts.MemorySizeFlagsTable.TryGetValue(value, out var flags))
                {
                    throw new InvalidOperationException($"Invalid flags value: {value}");
                }
                tc.Flags |= flags;
            }
            return(tc);
        }
Exemplo n.º 8
0
        public static IEnumerable <object[]> GetTestCases(int bitness, int stackAddressSize)
        {
            var toRegister = ToEnumConverter.CloneRegisterDict();

            switch (stackAddressSize)
            {
            case 16:
                toRegister.Add(MiscInstrInfoTestConstants.XSP, Register.SP);
                toRegister.Add(MiscInstrInfoTestConstants.XBP, Register.BP);
                break;

            case 32:
                toRegister.Add(MiscInstrInfoTestConstants.XSP, Register.ESP);
                toRegister.Add(MiscInstrInfoTestConstants.XBP, Register.EBP);
                break;

            case 64:
                toRegister.Add(MiscInstrInfoTestConstants.XSP, Register.RSP);
                toRegister.Add(MiscInstrInfoTestConstants.XBP, Register.RBP);
                break;

            default:
                throw new InvalidOperationException();
            }

            for (int i = 0; i < IcedConstants.VMM_count; i++)
            {
                toRegister.Add(MiscInstrInfoTestConstants.VMM_prefix + i.ToString(), IcedConstants.VMM_first + i);
            }

            var filename = PathUtils.GetTestTextFilename($"InstructionInfoTest_{bitness}.txt", "InstructionInfo");

            Debug.Assert(File.Exists(filename));
            int lineNo = 0;

            foreach (var line in File.ReadLines(filename))
            {
                lineNo++;
                if (line.Length == 0 || line.StartsWith("#"))
                {
                    continue;
                }

                (string hexBytes, Code code, DecoderOptions options, InstructionInfoTestCase testCase)info;
                try {
                    info = ParseLine(line, bitness, toRegister);
                }
                catch (Exception ex) {
                    throw new Exception($"Invalid line {lineNo} ({filename}): {ex.Message}");
                }
                if (info.testCase is object)
                {
                    yield return new object[5] {
                               info.hexBytes, info.code, info.options, lineNo, info.testCase
                    }
                }
                ;
            }
        }
Exemplo n.º 9
0
        static SymbolResolverTestCase ParseLine(string line)
        {
            var       elems         = line.Split(commaSeparator);
            const int SYM_RES_INDEX = 4;

            if (elems.Length < SYM_RES_INDEX)
            {
                throw new Exception($"Invalid number of commas: {elems.Length - 1}");
            }

            var bitness  = NumberConverter.ToInt32(elems[0].Trim());
            var hexBytes = elems[1].Trim();
            var code     = ToEnumConverter.GetCode(elems[2].Trim());

            var options = new List <(OptionsProps property, object value)>();

            foreach (var part in elems[3].Split(spaceSeparator, StringSplitOptions.RemoveEmptyEntries))
            {
                options.Add(OptionsParser.ParseOption(part));
            }

            var symbolResults = new SymbolResultTestCase[elems.Length - SYM_RES_INDEX];

            for (int i = 0; i < symbolResults.Length; i++)
            {
                var symParts = elems[SYM_RES_INDEX + i].Split(semicolonSeparator);
                if (symParts.Length != 5)
                {
                    throw new Exception($"Invalid number of semicolons: {symParts.Length - 1}");
                }

                var address       = NumberConverter.ToUInt64(symParts[0].Trim());
                var symbolAddress = NumberConverter.ToUInt64(symParts[1].Trim());
                var addressSize   = NumberConverter.ToInt32(symParts[2].Trim());
                var symbolParts   = symParts[3].Split(barSeparator);

                MemorySize?memorySize = null;
                var        flags      = SymbolFlags.None;
                foreach (var value in symParts[4].Split(spaceSeparator, StringSplitOptions.RemoveEmptyEntries))
                {
                    if (Dicts.ToSymbolFlags.TryGetValue(value, out var f))
                    {
                        flags |= f;
                    }
                    else
                    {
                        if (!ToEnumConverter.TryMemorySize(value, out var memSize))
                        {
                            throw new Exception($"Invalid value: {value}");
                        }
                        memorySize = memSize;
                    }
                }

                symbolResults[i] = new SymbolResultTestCase(address, symbolAddress, addressSize, flags, memorySize, symbolParts);
            }

            return(new SymbolResolverTestCase(bitness, hexBytes, code, options.ToArray(), symbolResults));
        }
Exemplo n.º 10
0
 static MvexConvFn ToMvexConvFn(string value)
 {
     if (!ToEnumConverter.TryMvexConvFn(value, out var mvexConvFn))
     {
         throw new InvalidOperationException($"Invalid MvexConvFn value: '{value}'");
     }
     return(mvexConvFn);
 }
Exemplo n.º 11
0
 static DecoderOptions ToDecoderOptions(string value)
 {
     if (!ToEnumConverter.TryDecoderOptions(value, out var code))
     {
         throw new InvalidOperationException($"Invalid DecoderOptions value: '{value}'");
     }
     return(code);
 }
Exemplo n.º 12
0
 static MemorySize ToMemorySize(string value)
 {
     if (!ToEnumConverter.TryMemorySize(value, out var memSize))
     {
         throw new InvalidOperationException($"Invalid MemorySize value: '{value}'");
     }
     return(memSize);
 }
Exemplo n.º 13
0
 static Code ToCode(string value)
 {
     if (!ToEnumConverter.TryCode(value, out var code))
     {
         throw new InvalidOperationException($"Invalid Code value: '{value}'");
     }
     return(code);
 }
Exemplo n.º 14
0
 static TupleType ToTupleType(string value)
 {
     if (!ToEnumConverter.TryTupleType(value, out var code))
     {
         throw new InvalidOperationException($"Invalid TupleType value: '{value}'");
     }
     return(code);
 }
Exemplo n.º 15
0
 static MvexTupleTypeLutKind ToMvexTupleTypeLutKind(string value)
 {
     if (!ToEnumConverter.TryMvexTupleTypeLutKind(value, out var result))
     {
         throw new InvalidOperationException($"Invalid MvexTupleTypeLutKind value: '{value}'");
     }
     return(result);
 }
Exemplo n.º 16
0
 static OpCodeOperandKind ToOpCodeOperandKind(string value)
 {
     if (!ToEnumConverter.TryOpCodeOperandKind(value, out var code))
     {
         throw new InvalidOperationException($"Invalid OpCodeOperandKind value: '{value}'");
     }
     return(code);
 }
Exemplo n.º 17
0
 static Mnemonic ToMnemonic(string value)
 {
     if (!ToEnumConverter.TryMnemonic(value, out var mnemonic))
     {
         throw new InvalidOperationException($"Invalid Mnemonic value: '{value}'");
     }
     return(mnemonic);
 }
Exemplo n.º 18
0
        static VirtualAddressTestCase?ParseLine(string line)
        {
            var elems = line.Split(commaSeparator);

            if (elems.Length != 7)
            {
                throw new Exception($"Invalid number of commas: {elems.Length - 1}");
            }

            var bitness = NumberConverter.ToInt32(elems[0].Trim());

            if (CodeUtils.IsIgnored(elems[1].Trim()))
            {
                return(null);
            }
            var hexBytes      = elems[2].Trim();
            var operand       = NumberConverter.ToInt32(elems[3].Trim());
            var elementIndex  = NumberConverter.ToInt32(elems[4].Trim());
            var expectedValue = NumberConverter.ToUInt64(elems[5].Trim());

            var registerValues = new List <(Register register, int elementIndex, int elementSize, ulong value)>();

            foreach (var tmp in elems[6].Split(spaceSeparator, StringSplitOptions.RemoveEmptyEntries))
            {
                var kv = tmp.Split(equalSeparator);
                if (kv.Length != 2)
                {
                    throw new Exception($"Expected key=value: {tmp}");
                }
                var key      = kv[0];
                var valueStr = kv[1];

                Register register;
                int      expectedElementIndex;
                int      expectedElementSize;
                if (key.IndexOf(';') >= 0)
                {
                    var parts = key.Split(semicolonSeparator);
                    if (parts.Length != 3)
                    {
                        throw new Exception($"Invalid number of semicolons: {parts.Length - 1}");
                    }
                    register             = ToEnumConverter.GetRegister(parts[0]);
                    expectedElementIndex = NumberConverter.ToInt32(parts[1]);
                    expectedElementSize  = NumberConverter.ToInt32(parts[2]);
                }
                else
                {
                    register             = ToEnumConverter.GetRegister(key);
                    expectedElementIndex = 0;
                    expectedElementSize  = 0;
                }
                ulong value = NumberConverter.ToUInt64(valueStr);
                registerValues.Add((register, expectedElementIndex, expectedElementSize, value));
            }

            return(new VirtualAddressTestCase(bitness, hexBytes, operand, elementIndex, expectedValue, registerValues.ToArray()));
        }
Exemplo n.º 19
0
 static Register ToRegister(string value)
 {
     if (value == string.Empty)
     {
         return(Register.None);
     }
     if (!ToEnumConverter.TryRegister(value, out var reg))
     {
         throw new InvalidOperationException($"Invalid Register value: '{value}'");
     }
     return(reg);
 }
Exemplo n.º 20
0
 static bool TryParseDecoderOptions(string[] stringOptions, ref DecoderOptions options)
 {
     foreach (var opt in stringOptions)
     {
         if (!ToEnumConverter.TryDecoderOptions(opt.Trim(), out var decOpts))
         {
             return(false);
         }
         options |= decOpts;
     }
     return(true);
 }
Exemplo n.º 21
0
        static bool AddMemory(int bitness, Dictionary <string, Register> toRegister, string value, OpAccess access, InstructionInfoTestCase testCase)
        {
            var elems = value.Split(semicolonSeparator);

            if (elems.Length != 2)
            {
                return(false);
            }
            var expr = elems[0].Trim();

            if (!ToEnumConverter.TryMemorySize(elems[1].Trim(), out var memorySize))
            {
                return(false);
            }

            if (!TryParseMemExpr(toRegister, expr, out var segReg, out var baseReg, out var indexReg, out int scale, out ulong displ))
            {
                return(false);
            }

            switch (bitness)
            {
            case 16:
                if (!(short.MinValue <= (long)displ && (long)displ <= short.MaxValue) && displ > ushort.MaxValue)
                {
                    return(false);
                }
                displ = (ushort)displ;
                break;

            case 32:
                if (!(int.MinValue <= (long)displ && (long)displ <= int.MaxValue) && displ > uint.MaxValue)
                {
                    return(false);
                }
                displ = (uint)displ;
                break;

            case 64:
                break;

            default:
                throw new InvalidOperationException();
            }

            if (access != OpAccess.NoMemAccess)
            {
                testCase.UsedMemory.Add(new UsedMemory(segReg, baseReg, indexReg, scale, displ, memorySize, access));
            }

            return(true);
        }
Exemplo n.º 22
0
        static DecoderMemoryTestCase ReadTestCase(int bitness, string line, int lineNumber)
        {
            var parts = line.Split(colSep, StringSplitOptions.None);

            if (parts.Length != 11 && parts.Length != 12)
            {
                throw new InvalidOperationException();
            }
            var tc = new DecoderMemoryTestCase();

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

            if (CodeUtils.IsIgnored(code))
            {
                return(null);
            }
            tc.Code             = ToEnumConverter.GetCode(code);
            tc.Register         = ToEnumConverter.GetRegister(parts[2].Trim());
            tc.SegmentPrefix    = ToEnumConverter.GetRegister(parts[3].Trim());
            tc.SegmentRegister  = ToEnumConverter.GetRegister(parts[4].Trim());
            tc.BaseRegister     = ToEnumConverter.GetRegister(parts[5].Trim());
            tc.IndexRegister    = ToEnumConverter.GetRegister(parts[6].Trim());
            tc.Scale            = (int)NumberConverter.ToUInt32(parts[7].Trim());
            tc.Displacement     = NumberConverter.ToUInt64(parts[8].Trim());
            tc.DisplacementSize = (int)NumberConverter.ToUInt32(parts[9].Trim());
            var coStr = parts[10].Trim();

            if (!DecoderTestParser.TryParseConstantOffsets(coStr, out tc.ConstantOffsets))
            {
                throw new InvalidOperationException($"Invalid ConstantOffsets: '{coStr}'");
            }
            tc.EncodedHexBytes = parts.Length > 11 ? parts[11].Trim() : tc.HexBytes;
            tc.DecoderOptions  = DecoderOptions.None;
            tc.TestOptions     = DecoderTestOptions.None;
            return(tc);
        }
Exemplo n.º 23
0
        static MnemonicOptionsTestCase?ParseLine(string line)
        {
            var elems = line.Split(commaSeparator);

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

            var hexBytes = elems[0].Trim();
            var codeStr  = elems[1].Trim();

            if (CodeUtils.IsIgnored(codeStr))
            {
                return(null);
            }
            var code    = ToEnumConverter.GetCode(codeStr);
            var bitness = NumberConverter.ToInt32(elems[2].Trim());
            var ip      = bitness switch {
                16 => DecoderConstants.DEFAULT_IP16,
                32 => DecoderConstants.DEFAULT_IP32,
                64 => DecoderConstants.DEFAULT_IP64,
                _ => throw new InvalidOperationException(),
            };
            var formattedString = elems[3].Trim().Replace('|', ',');
            var flags           = FormatMnemonicOptions.None;

            foreach (var value in elems[4].Split(spaceSeparator, StringSplitOptions.RemoveEmptyEntries))
            {
                if (!Dicts.ToFormatMnemonicOptions.TryGetValue(value, out var f))
                {
                    throw new InvalidOperationException($"Invalid flags value: {value}");
                }
                flags |= f;
            }
            return(new MnemonicOptionsTestCase(hexBytes, code, bitness, ip, formattedString, flags));
        }
Exemplo n.º 24
0
        void Make_sure_all_Code_values_are_tested()
        {
            var tested = new bool[IcedConstants.NumberOfCodeValues];

            foreach (var info in GetTests())
            {
                tested[(int)(Code)info[1]] = true;
            }

            var sb        = new StringBuilder();
            int missing   = 0;
            var codeNames = ToEnumConverter.GetCodeNames().ToArray();

            Assert.Equal(tested.Length, codeNames.Length);
            for (int i = 0; i < tested.Length; i++)
            {
                if (!tested[i])
                {
                    sb.Append(codeNames[i] + " ");
                    missing++;
                }
            }
            Assert.Equal("0 ins ", $"{missing} ins " + sb.ToString());
        }
Exemplo n.º 25
0
        void Make_sure_all_Code_values_are_tested_in_16_32_64_bit_modes()
        {
            const byte T16    = 0x01;
            const byte T32    = 0x02;
            const byte T64    = 0x04;
            var        tested = new byte[IcedConstants.NumberOfCodeValues];

            tested[(int)Code.INVALID] = T16 | T32 | T64;

            foreach (var info in DecoderTestUtils.GetDecoderTests(includeOtherTests: false, includeInvalid: false))
            {
                Assert.False(DecoderTestUtils.NotDecoded.Contains(info.Code), $"{info.Code} has a decoder test but it shouldn't be decoded");

                tested[(int)info.Code] |= info.Bitness switch {
                    16 => T16,
                    32 => T32,
                    64 => T64,
                    _ => throw new InvalidOperationException(),
                };
            }

#if ENCODER
            foreach (var info in NonDecodedInstructions.GetTests())
            {
                tested[(int)info.instruction.Code] |= info.bitness switch {
                    16 => T16,
                    32 => T32,
                    64 => T64,
                    _ => throw new InvalidOperationException(),
                };
            }
#else
            foreach (var code in NonDecodedCodeValues1632)
            {
                tested[(int)code] |= T16 | T32;
            }
            foreach (var code in NonDecodedCodeValues)
            {
                tested[(int)code] |= T16 | T32 | T64;
            }
#endif

            foreach (var c in DecoderTestUtils.NotDecoded)
            {
                Assert.DoesNotContain(c, DecoderTestUtils.Code32Only);
                Assert.DoesNotContain(c, DecoderTestUtils.Code64Only);
            }

            foreach (var c in DecoderTestUtils.NotDecoded32Only)
            {
                tested[(int)c] ^= T64;
            }
            foreach (var c in DecoderTestUtils.NotDecoded64Only)
            {
                tested[(int)c] ^= T16 | T32;
            }

            foreach (var c in DecoderTestUtils.Code32Only)
            {
                Assert.DoesNotContain(c, DecoderTestUtils.Code64Only);
                tested[(int)c] ^= T64;
            }

            foreach (var c in DecoderTestUtils.Code64Only)
            {
                Assert.DoesNotContain(c, DecoderTestUtils.Code32Only);
                tested[(int)c] ^= T16 | T32;
            }

            var sb16 = new StringBuilder();
            var sb32 = new StringBuilder();
            var sb64 = new StringBuilder();
            int missing16 = 0, missing32 = 0, missing64 = 0;
            var codeNames = ToEnumConverter.GetCodeNames();
            Assert.Equal(tested.Length, codeNames.Length);
            for (int i = 0; i < tested.Length; i++)
            {
                if (tested[i] != (T16 | T32 | T64) && !CodeUtils.IsIgnored(codeNames[i]))
                {
                    if ((tested[i] & T16) == 0)
                    {
                        sb16.Append(codeNames[i] + " ");
                        missing16++;
                    }
                    if ((tested[i] & T32) == 0)
                    {
                        sb32.Append(codeNames[i] + " ");
                        missing32++;
                    }
                    if ((tested[i] & T64) == 0)
                    {
                        sb64.Append(codeNames[i] + " ");
                        missing64++;
                    }
                }
            }
            Assert.Equal("16: 0 ins ", $"16: {missing16} ins " + sb16.ToString());
            Assert.Equal("32: 0 ins ", $"32: {missing32} ins " + sb32.ToString());
            Assert.Equal("64: 0 ins ", $"64: {missing64} ins " + sb64.ToString());
        }
Exemplo n.º 26
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);
        }
Exemplo n.º 27
0
        public static (OptionsProps property, object value) ParseOption(string keyValue)
        {
            var kv = keyValue.Split(kvseps, 2);

            if (kv.Length != 2)
            {
                throw new InvalidOperationException($"Expected key=value: '{keyValue}'");
            }
            var    valueStr = kv[1].Trim();
            var    prop     = ToEnumConverter.GetOptionsProps(kv[0].Trim());
            object value;

            switch (prop)
            {
            case OptionsProps.AddLeadingZeroToHexNumbers:
            case OptionsProps.AlwaysShowScale:
            case OptionsProps.AlwaysShowSegmentRegister:
            case OptionsProps.BranchLeadingZeroes:
            case OptionsProps.DisplacementLeadingZeroes:
            case OptionsProps.GasNakedRegisters:
            case OptionsProps.GasShowMnemonicSizeSuffix:
            case OptionsProps.GasSpaceAfterMemoryOperandComma:
            case OptionsProps.LeadingZeroes:
            case OptionsProps.MasmAddDsPrefix32:
            case OptionsProps.NasmShowSignExtendedImmediateSize:
            case OptionsProps.PreferST0:
            case OptionsProps.RipRelativeAddresses:
            case OptionsProps.ScaleBeforeIndex:
            case OptionsProps.ShowBranchSize:
            case OptionsProps.ShowSymbolAddress:
            case OptionsProps.ShowZeroDisplacements:
            case OptionsProps.SignedImmediateOperands:
            case OptionsProps.SignedMemoryDisplacements:
            case OptionsProps.SmallHexNumbersInDecimal:
            case OptionsProps.SpaceAfterMemoryBracket:
            case OptionsProps.SpaceAfterOperandSeparator:
            case OptionsProps.SpaceBetweenMemoryAddOperators:
            case OptionsProps.SpaceBetweenMemoryMulOperators:
            case OptionsProps.UppercaseAll:
            case OptionsProps.UppercaseDecorators:
            case OptionsProps.UppercaseHex:
            case OptionsProps.UppercaseKeywords:
            case OptionsProps.UppercaseMnemonics:
            case OptionsProps.UppercasePrefixes:
            case OptionsProps.UppercaseRegisters:
            case OptionsProps.UsePseudoOps:
            case OptionsProps.ShowUselessPrefixes:
                value = NumberConverter.ToBoolean(valueStr);
                break;

            case OptionsProps.BinaryDigitGroupSize:
            case OptionsProps.DecimalDigitGroupSize:
            case OptionsProps.FirstOperandCharIndex:
            case OptionsProps.HexDigitGroupSize:
            case OptionsProps.OctalDigitGroupSize:
            case OptionsProps.TabSize:
                value = NumberConverter.ToInt32(valueStr);
                break;

            case OptionsProps.IP:
                value = NumberConverter.ToUInt64(valueStr);
                break;

            case OptionsProps.BinaryPrefix:
            case OptionsProps.BinarySuffix:
            case OptionsProps.DecimalPrefix:
            case OptionsProps.DecimalSuffix:
            case OptionsProps.DigitSeparator:
            case OptionsProps.HexPrefix:
            case OptionsProps.HexSuffix:
            case OptionsProps.OctalPrefix:
            case OptionsProps.OctalSuffix:
                value = valueStr == "<null>" ? null : valueStr;
                break;

            case OptionsProps.MemorySizeOptions:
                value = ToEnumConverter.GetMemorySizeOptions(valueStr);
                break;

            case OptionsProps.NumberBase:
                value = ToEnumConverter.GetNumberBase(valueStr);
                break;

            case OptionsProps.CC_b:
                value = ToEnumConverter.GetCC_b(valueStr);
                break;

            case OptionsProps.CC_ae:
                value = ToEnumConverter.GetCC_ae(valueStr);
                break;

            case OptionsProps.CC_e:
                value = ToEnumConverter.GetCC_e(valueStr);
                break;

            case OptionsProps.CC_ne:
                value = ToEnumConverter.GetCC_ne(valueStr);
                break;

            case OptionsProps.CC_be:
                value = ToEnumConverter.GetCC_be(valueStr);
                break;

            case OptionsProps.CC_a:
                value = ToEnumConverter.GetCC_a(valueStr);
                break;

            case OptionsProps.CC_p:
                value = ToEnumConverter.GetCC_p(valueStr);
                break;

            case OptionsProps.CC_np:
                value = ToEnumConverter.GetCC_np(valueStr);
                break;

            case OptionsProps.CC_l:
                value = ToEnumConverter.GetCC_l(valueStr);
                break;

            case OptionsProps.CC_ge:
                value = ToEnumConverter.GetCC_ge(valueStr);
                break;

            case OptionsProps.CC_le:
                value = ToEnumConverter.GetCC_le(valueStr);
                break;

            case OptionsProps.CC_g:
                value = ToEnumConverter.GetCC_g(valueStr);
                break;

            case OptionsProps.DecoderOptions:
                value = ToEnumConverter.GetDecoderOptions(valueStr);
                break;

            default:
                throw new InvalidOperationException();
            }
            return(prop, value);
        }
Exemplo n.º 28
0
        static (string hexBytes, Code code, DecoderOptions options, InstructionInfoTestCase testCase) ParseLine(string line, int bitness, Dictionary <string, Register> toRegister)
        {
            Static.Assert(MiscInstrInfoTestConstants.InstrInfoElemsPerLine == 5 ? 0 : -1);
            var elems = line.Split(commaSeparator, MiscInstrInfoTestConstants.InstrInfoElemsPerLine);

            if (elems.Length != MiscInstrInfoTestConstants.InstrInfoElemsPerLine)
            {
                throw new Exception($"Expected {MiscInstrInfoTestConstants.InstrInfoElemsPerLine - 1} commas");
            }

            var testCase = new InstructionInfoTestCase();

            var hexBytes = ToHexBytes(elems[0].Trim());
            var code     = ToEnumConverter.GetCode(elems[1].Trim());

            testCase.Encoding = ToEnumConverter.GetEncodingKind(elems[2].Trim());
            var cpuidFeatureStrings = elems[3].Trim().Split(new[] { ';' });

            var cpuidFeatures = new CpuidFeature[cpuidFeatureStrings.Length];

            testCase.CpuidFeatures = cpuidFeatures;
            for (int i = 0; i < cpuidFeatures.Length; i++)
            {
                cpuidFeatures[i] = ToEnumConverter.GetCpuidFeature(cpuidFeatureStrings[i]);
            }

            var options = DecoderOptions.None;

            foreach (var keyValue in elems[4].Split(spaceSeparator, StringSplitOptions.RemoveEmptyEntries))
            {
                string key, value;
                int    index = keyValue.IndexOf('=');
                if (index >= 0)
                {
                    key   = keyValue.Substring(0, index);
                    value = keyValue.Substring(index + 1);
                }
                else
                {
                    key   = keyValue;
                    value = string.Empty;
                }

                switch (key)
                {
                case InstructionInfoKeys.IsProtectedMode:
                    if (value != string.Empty)
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    testCase.IsProtectedMode = true;
                    break;

                case InstructionInfoKeys.IsPrivileged:
                    if (value != string.Empty)
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    testCase.IsPrivileged = true;
                    break;

                case InstructionInfoKeys.IsSaveRestoreInstruction:
                    if (value != string.Empty)
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    testCase.IsSaveRestoreInstruction = true;
                    break;

                case InstructionInfoKeys.IsStackInstruction:
                    if (!int.TryParse(value, out testCase.StackPointerIncrement))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    testCase.IsStackInstruction = true;
                    break;

                case InstructionInfoKeys.IsSpecial:
                    if (value != string.Empty)
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    testCase.IsSpecial = true;
                    break;

                case InstructionInfoKeys.RflagsRead:
                    if (!ParseRflags(value, ref testCase.RflagsRead))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.RflagsUndefined:
                    if (!ParseRflags(value, ref testCase.RflagsUndefined))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.RflagsWritten:
                    if (!ParseRflags(value, ref testCase.RflagsWritten))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.RflagsCleared:
                    if (!ParseRflags(value, ref testCase.RflagsCleared))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.RflagsSet:
                    if (!ParseRflags(value, ref testCase.RflagsSet))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.FlowControl:
                    if (!ToEnumConverter.TryFlowControl(value, out testCase.FlowControl))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.Op0Access:
                    if (!InstructionInfoDicts.ToAccess.TryGetValue(value, out testCase.Op0Access))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.Op1Access:
                    if (!InstructionInfoDicts.ToAccess.TryGetValue(value, out testCase.Op1Access))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.Op2Access:
                    if (!InstructionInfoDicts.ToAccess.TryGetValue(value, out testCase.Op2Access))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.Op3Access:
                    if (!InstructionInfoDicts.ToAccess.TryGetValue(value, out testCase.Op3Access))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.Op4Access:
                    if (!InstructionInfoDicts.ToAccess.TryGetValue(value, out testCase.Op4Access))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.ReadRegister:
                    if (!AddRegisters(toRegister, value, OpAccess.Read, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.CondReadRegister:
                    if (!AddRegisters(toRegister, value, OpAccess.CondRead, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.WriteRegister:
                    if (!AddRegisters(toRegister, value, OpAccess.Write, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.CondWriteRegister:
                    if (!AddRegisters(toRegister, value, OpAccess.CondWrite, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.ReadWriteRegister:
                    if (!AddRegisters(toRegister, value, OpAccess.ReadWrite, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.ReadCondWriteRegister:
                    if (!AddRegisters(toRegister, value, OpAccess.ReadCondWrite, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.ReadMemory:
                    if (!AddMemory(bitness, toRegister, value, OpAccess.Read, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.CondReadMemory:
                    if (!AddMemory(bitness, toRegister, value, OpAccess.CondRead, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.ReadWriteMemory:
                    if (!AddMemory(bitness, toRegister, value, OpAccess.ReadWrite, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.ReadCondWriteMemory:
                    if (!AddMemory(bitness, toRegister, value, OpAccess.ReadCondWrite, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.WriteMemory:
                    if (!AddMemory(bitness, toRegister, value, OpAccess.Write, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.CondWriteMemory:
                    if (!AddMemory(bitness, toRegister, value, OpAccess.CondWrite, testCase))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                case InstructionInfoKeys.DecoderOptions:
                    if (!TryParseDecoderOptions(value.Split(semicolonSeparator), ref options))
                    {
                        throw new Exception($"Invalid key-value value, '{keyValue}'");
                    }
                    break;

                default:
                    throw new Exception($"Invalid key-value value, '{keyValue}'");
                }
            }

            return(hexBytes, code, options, testCase);
        }
Exemplo n.º 29
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);
        }
Exemplo n.º 30
0
        static OptionsInstructionInfo ReadTestCase(string line, int lineNo)
        {
            var parts = line.Split(seps);

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

            int bitness  = NumberConverter.ToInt32(parts[0].Trim());
            var hexBytes = parts[1].Trim();

            HexUtils.ToByteArray(hexBytes);
            var code       = ToCode(parts[2].Trim());
            var properties = new List <(OptionsProps property, object value)>();

            foreach (var part in parts[3].Split(optsseps, StringSplitOptions.RemoveEmptyEntries))
            {
                var kv = part.Split(kvseps, 2);
                if (kv.Length != 2)
                {
                    throw new InvalidOperationException($"Expected key=value: '{part}'");
                }
                var    valueStr = kv[1].Trim();
                var    prop     = ToEnumConverter.GetOptionsProps(kv[0].Trim());
                object value;
                switch (prop)
                {
                case OptionsProps.AddLeadingZeroToHexNumbers:
                case OptionsProps.AlwaysShowScale:
                case OptionsProps.AlwaysShowSegmentRegister:
                case OptionsProps.BranchLeadingZeroes:
                case OptionsProps.DisplacementLeadingZeroes:
                case OptionsProps.GasNakedRegisters:
                case OptionsProps.GasShowMnemonicSizeSuffix:
                case OptionsProps.GasSpaceAfterMemoryOperandComma:
                case OptionsProps.LeadingZeroes:
                case OptionsProps.MasmAddDsPrefix32:
                case OptionsProps.NasmShowSignExtendedImmediateSize:
                case OptionsProps.PreferST0:
                case OptionsProps.RipRelativeAddresses:
                case OptionsProps.ScaleBeforeIndex:
                case OptionsProps.ShowBranchSize:
                case OptionsProps.ShowZeroDisplacements:
                case OptionsProps.SignedImmediateOperands:
                case OptionsProps.SignedMemoryDisplacements:
                case OptionsProps.SmallHexNumbersInDecimal:
                case OptionsProps.SpaceAfterMemoryBracket:
                case OptionsProps.SpaceAfterOperandSeparator:
                case OptionsProps.SpaceBetweenMemoryAddOperators:
                case OptionsProps.SpaceBetweenMemoryMulOperators:
                case OptionsProps.UppercaseAll:
                case OptionsProps.UppercaseDecorators:
                case OptionsProps.UppercaseHex:
                case OptionsProps.UppercaseKeywords:
                case OptionsProps.UppercaseMnemonics:
                case OptionsProps.UppercasePrefixes:
                case OptionsProps.UppercaseRegisters:
                case OptionsProps.UsePseudoOps:
                    value = NumberConverter.ToBoolean(valueStr);
                    break;

                case OptionsProps.BinaryDigitGroupSize:
                case OptionsProps.DecimalDigitGroupSize:
                case OptionsProps.FirstOperandCharIndex:
                case OptionsProps.HexDigitGroupSize:
                case OptionsProps.OctalDigitGroupSize:
                case OptionsProps.TabSize:
                    value = NumberConverter.ToInt32(valueStr);
                    break;

                case OptionsProps.IP:
                    value = NumberConverter.ToUInt64(valueStr);
                    break;

                case OptionsProps.BinaryPrefix:
                case OptionsProps.BinarySuffix:
                case OptionsProps.DecimalPrefix:
                case OptionsProps.DecimalSuffix:
                case OptionsProps.DigitSeparator:
                case OptionsProps.HexPrefix:
                case OptionsProps.HexSuffix:
                case OptionsProps.OctalPrefix:
                case OptionsProps.OctalSuffix:
                    value = valueStr == "<null>" ? null : valueStr;
                    break;

                case OptionsProps.MemorySizeOptions:
                    value = ToEnumConverter.GetMemorySizeOptions(valueStr);
                    break;

                case OptionsProps.NumberBase:
                    value = ToEnumConverter.GetNumberBase(valueStr);
                    break;

                default:
                    throw new InvalidOperationException();
                }
                properties.Add((prop, value));
            }

            return(new OptionsInstructionInfo(bitness, hexBytes, code, properties));
        }