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 codeStr = parts[2].Trim(); if (CodeUtils.IsIgnored(codeStr)) { return(null); } var code = ToCode(codeStr); var properties = new List <(OptionsProps property, object value)>(); foreach (var part in parts[3].Split(optsseps, StringSplitOptions.RemoveEmptyEntries)) { properties.Add(OptionsParser.ParseOption(part)); } return(new OptionsInstructionInfo(bitness, hexBytes, code, properties)); }
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()); }
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(); testCase.IP = bitness switch { 16 => DecoderConstants.DEFAULT_IP16, 32 => DecoderConstants.DEFAULT_IP32, 64 => DecoderConstants.DEFAULT_IP64, _ => throw new InvalidOperationException(), }; var hexBytes = ToHexBytes(elems[0].Trim()); var codeStr = elems[1].Trim(); if (CodeUtils.IsIgnored(codeStr)) { return(default);
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); }
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); } } }
static SymbolOptionsTestCase?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(); if (CodeUtils.IsIgnored(elems[1].Trim())) { return(null); } var bitness = NumberConverter.ToInt32(elems[2].Trim()); var formattedString = elems[3].Trim().Replace('|', ','); var flags = SymbolTestFlags.None; foreach (var value in elems[4].Split(spaceSeparator, StringSplitOptions.RemoveEmptyEntries)) { if (!Dicts.ToSymbolTestFlags.TryGetValue(value, out var f)) { throw new InvalidOperationException($"Invalid flags value: {value}"); } flags |= f; } return(new SymbolOptionsTestCase(hexBytes, bitness, formattedString, flags)); }
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())); }
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); }
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)); }
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(); Assert.Equal(tested.Length, codeNames.Length); for (int i = 0; i < tested.Length; i++) { if (!tested[i] && !CodeUtils.IsIgnored(codeNames[i])) { sb.Append(codeNames[i] + " "); missing++; } } Assert.Equal("0 ins ", $"{missing} ins " + sb.ToString()); }
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()); }
static OpCodeInfoTestCase ReadTestCase(string line, int lineNo) { var parts = line.Split(seps); if (parts.Length != 8) { throw new InvalidOperationException($"Invalid number of commas ({parts.Length - 1} commas)"); } var tc = new OpCodeInfoTestCase(); tc.LineNumber = lineNo; tc.IsInstruction = true; tc.GroupIndex = -1; var code = parts[0].Trim(); if (CodeUtils.IsIgnored(code)) { return(null); } tc.Code = ToCode(code); tc.Encoding = ToEncoding(parts[1].Trim()); tc.MandatoryPrefix = ToMandatoryPrefix(parts[2].Trim()); tc.Table = ToTable(parts[3].Trim()); tc.OpCode = ToOpCode(parts[4].Trim(), out tc.OpCodeLength); tc.OpCodeString = parts[5].Trim(); tc.InstructionString = parts[6].Trim().Replace('|', ','); bool gotVectorLength = false; bool gotW = false; foreach (var part in parts[7].Split(optsseps)) { var key = part.Trim(); if (key.Length == 0) { continue; } int index = key.IndexOf('='); if (index >= 0) { var value = key.Substring(index + 1); key = key.Substring(0, index); switch (key) { case OpCodeInfoKeys.GroupIndex: if (!uint.TryParse(value, out uint groupIndex) || groupIndex > 7) { throw new InvalidOperationException($"Invalid group index: {value}"); } tc.GroupIndex = (int)groupIndex; tc.IsGroup = true; break; case OpCodeInfoKeys.RmGroupIndex: if (!uint.TryParse(value, out uint rmGroupIndex) || rmGroupIndex > 7) { throw new InvalidOperationException($"Invalid group index: {value}"); } tc.RmGroupIndex = (int)rmGroupIndex; tc.IsRmGroup = true; break; case OpCodeInfoKeys.OpCodeOperandKind: var opParts = value.Split(opseps); tc.OpCount = opParts.Length; if (opParts.Length >= 1) { tc.Op0Kind = ToOpCodeOperandKind(opParts[0]); } if (opParts.Length >= 2) { tc.Op1Kind = ToOpCodeOperandKind(opParts[1]); } if (opParts.Length >= 3) { tc.Op2Kind = ToOpCodeOperandKind(opParts[2]); } if (opParts.Length >= 4) { tc.Op3Kind = ToOpCodeOperandKind(opParts[3]); } if (opParts.Length >= 5) { tc.Op4Kind = ToOpCodeOperandKind(opParts[4]); } Static.Assert(IcedConstants.MaxOpCount == 5 ? 0 : -1); if (opParts.Length >= 6) { throw new InvalidOperationException($"Invalid number of operands: '{value}'"); } break; case OpCodeInfoKeys.TupleType: tc.TupleType = ToTupleType(value.Trim()); break; case OpCodeInfoKeys.DecoderOption: tc.DecoderOption = ToDecoderOptions(value.Trim()); break; default: throw new InvalidOperationException($"Invalid key: '{key}'"); } } else { switch (key) { case OpCodeInfoFlags.NoInstruction: tc.IsInstruction = false; break; case OpCodeInfoFlags.Bit16: tc.Mode16 = true; break; case OpCodeInfoFlags.Bit32: tc.Mode32 = true; break; case OpCodeInfoFlags.Bit64: tc.Mode64 = true; break; case OpCodeInfoFlags.Fwait: tc.Fwait = true; break; case OpCodeInfoFlags.OperandSize16: tc.OperandSize = 16; break; case OpCodeInfoFlags.OperandSize32: tc.OperandSize = 32; break; case OpCodeInfoFlags.OperandSize64: tc.OperandSize = 64; break; case OpCodeInfoFlags.AddressSize16: tc.AddressSize = 16; break; case OpCodeInfoFlags.AddressSize32: tc.AddressSize = 32; break; case OpCodeInfoFlags.AddressSize64: tc.AddressSize = 64; break; case OpCodeInfoFlags.LIG: tc.IsLIG = true; gotVectorLength = true; break; case OpCodeInfoFlags.L0: tc.L = 0; gotVectorLength = true; break; case OpCodeInfoFlags.L1: tc.L = 1; gotVectorLength = true; break; case OpCodeInfoFlags.L128: tc.L = 0; gotVectorLength = true; break; case OpCodeInfoFlags.L256: tc.L = 1; gotVectorLength = true; break; case OpCodeInfoFlags.L512: tc.L = 2; gotVectorLength = true; break; case OpCodeInfoFlags.WIG: tc.IsWIG = true; gotW = true; break; case OpCodeInfoFlags.WIG32: tc.W = 0; tc.IsWIG32 = true; gotW = true; break; case OpCodeInfoFlags.W0: tc.W = 0; gotW = true; break; case OpCodeInfoFlags.W1: tc.W = 1; gotW = true; break; case OpCodeInfoFlags.Broadcast: tc.CanBroadcast = true; break; case OpCodeInfoFlags.RoundingControl: tc.CanUseRoundingControl = true; break; case OpCodeInfoFlags.SuppressAllExceptions: tc.CanSuppressAllExceptions = true; break; case OpCodeInfoFlags.OpMaskRegister: tc.CanUseOpMaskRegister = true; break; case OpCodeInfoFlags.RequireOpMaskRegister: tc.CanUseOpMaskRegister = true; tc.RequireOpMaskRegister = true; break; case OpCodeInfoFlags.ZeroingMasking: tc.CanUseZeroingMasking = true; break; case OpCodeInfoFlags.Lock: tc.CanUseLockPrefix = true; break; case OpCodeInfoFlags.Xacquire: tc.CanUseXacquirePrefix = true; break; case OpCodeInfoFlags.Xrelease: tc.CanUseXreleasePrefix = true; break; case OpCodeInfoFlags.Rep: case OpCodeInfoFlags.Repe: tc.CanUseRepPrefix = true; break; case OpCodeInfoFlags.Repne: tc.CanUseRepnePrefix = true; break; case OpCodeInfoFlags.Bnd: tc.CanUseBndPrefix = true; break; case OpCodeInfoFlags.HintTaken: tc.CanUseHintTakenPrefix = true; break; case OpCodeInfoFlags.Notrack: tc.CanUseNotrackPrefix = true; break; case OpCodeInfoFlags.IgnoresRoundingControl: tc.IgnoresRoundingControl = true; break; case OpCodeInfoFlags.AmdLockRegBit: tc.AmdLockRegBit = true; break; case OpCodeInfoFlags.DefaultOpSize64: tc.DefaultOpSize64 = true; break; case OpCodeInfoFlags.ForceOpSize64: tc.ForceOpSize64 = true; break; case OpCodeInfoFlags.IntelForceOpSize64: tc.IntelForceOpSize64 = true; break; case OpCodeInfoFlags.Cpl0: tc.Cpl0 = true; break; case OpCodeInfoFlags.Cpl1: tc.Cpl1 = true; break; case OpCodeInfoFlags.Cpl2: tc.Cpl2 = true; break; case OpCodeInfoFlags.Cpl3: tc.Cpl3 = true; break; case OpCodeInfoFlags.InputOutput: tc.IsInputOutput = true; break; case OpCodeInfoFlags.Nop: tc.IsNop = true; break; case OpCodeInfoFlags.ReservedNop: tc.IsReservedNop = true; break; case OpCodeInfoFlags.SerializingIntel: tc.IsSerializingIntel = true; break; case OpCodeInfoFlags.SerializingAmd: tc.IsSerializingAmd = true; break; case OpCodeInfoFlags.MayRequireCpl0: tc.MayRequireCpl0 = true; break; case OpCodeInfoFlags.CetTracked: tc.IsCetTracked = true; break; case OpCodeInfoFlags.NonTemporal: tc.IsNonTemporal = true; break; case OpCodeInfoFlags.FpuNoWait: tc.IsFpuNoWait = true; break; case OpCodeInfoFlags.IgnoresModBits: tc.IgnoresModBits = true; break; case OpCodeInfoFlags.No66: tc.No66 = true; break; case OpCodeInfoFlags.NFx: tc.NFx = true; break; case OpCodeInfoFlags.RequiresUniqueRegNums: tc.RequiresUniqueRegNums = true; break; case OpCodeInfoFlags.Privileged: tc.IsPrivileged = true; break; case OpCodeInfoFlags.SaveRestore: tc.IsSaveRestore = true; break; case OpCodeInfoFlags.StackInstruction: tc.IsStackInstruction = true; break; case OpCodeInfoFlags.IgnoresSegment: tc.IgnoresSegment = true; break; case OpCodeInfoFlags.OpMaskReadWrite: tc.IsOpMaskReadWrite = true; break; case OpCodeInfoFlags.RealMode: tc.RealMode = true; break; case OpCodeInfoFlags.ProtectedMode: tc.ProtectedMode = true; break; case OpCodeInfoFlags.Virtual8086Mode: tc.Virtual8086Mode = true; break; case OpCodeInfoFlags.CompatibilityMode: tc.CompatibilityMode = true; break; case OpCodeInfoFlags.LongMode: tc.LongMode = true; break; case OpCodeInfoFlags.UseOutsideSmm: tc.UseOutsideSmm = true; break; case OpCodeInfoFlags.UseInSmm: tc.UseInSmm = true; break; case OpCodeInfoFlags.UseOutsideEnclaveSgx: tc.UseOutsideEnclaveSgx = true; break; case OpCodeInfoFlags.UseInEnclaveSgx1: tc.UseInEnclaveSgx1 = true; break; case OpCodeInfoFlags.UseInEnclaveSgx2: tc.UseInEnclaveSgx2 = true; break; case OpCodeInfoFlags.UseOutsideVmxOp: tc.UseOutsideVmxOp = true; break; case OpCodeInfoFlags.UseInVmxRootOp: tc.UseInVmxRootOp = true; break; case OpCodeInfoFlags.UseInVmxNonRootOp: tc.UseInVmxNonRootOp = true; break; case OpCodeInfoFlags.UseOutsideSeam: tc.UseOutsideSeam = true; break; case OpCodeInfoFlags.UseInSeam: tc.UseInSeam = true; break; case OpCodeInfoFlags.TdxNonRootGenUd: tc.TdxNonRootGenUd = true; break; case OpCodeInfoFlags.TdxNonRootGenVe: tc.TdxNonRootGenVe = true; break; case OpCodeInfoFlags.TdxNonRootMayGenEx: tc.TdxNonRootMayGenEx = true; break; case OpCodeInfoFlags.IntelVmExit: tc.IntelVmExit = true; break; case OpCodeInfoFlags.IntelMayVmExit: tc.IntelMayVmExit = true; break; case OpCodeInfoFlags.IntelSmmVmExit: tc.IntelSmmVmExit = true; break; case OpCodeInfoFlags.AmdVmExit: tc.AmdVmExit = true; break; case OpCodeInfoFlags.AmdMayVmExit: tc.AmdMayVmExit = true; break; case OpCodeInfoFlags.TsxAbort: tc.TsxAbort = true; break; case OpCodeInfoFlags.TsxImplAbort: tc.TsxImplAbort = true; break; case OpCodeInfoFlags.TsxMayAbort: tc.TsxMayAbort = true; break; case OpCodeInfoFlags.IntelDecoder16: tc.IntelDecoder16 = true; break; case OpCodeInfoFlags.IntelDecoder32: tc.IntelDecoder32 = true; break; case OpCodeInfoFlags.IntelDecoder64: tc.IntelDecoder64 = true; break; case OpCodeInfoFlags.AmdDecoder16: tc.AmdDecoder16 = true; break; case OpCodeInfoFlags.AmdDecoder32: tc.AmdDecoder32 = true; break; case OpCodeInfoFlags.AmdDecoder64: tc.AmdDecoder64 = true; break; default: throw new InvalidOperationException($"Invalid key: '{key}'"); } } } switch (tc.Encoding) { case EncodingKind.Legacy: case EncodingKind.D3NOW: break; case EncodingKind.VEX: case EncodingKind.EVEX: case EncodingKind.XOP: if (!gotVectorLength) { throw new InvalidOperationException("Missing vector length: L0/L1/L128/L256/L512/LIG"); } if (!gotW) { throw new InvalidOperationException("Missing W bit: W0/W1/WIG/WIG32"); } break; default: throw new InvalidOperationException(); } return(tc); }
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); }
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 codeStr = elems[2].Trim(); if (CodeUtils.IsIgnored(codeStr)) { return(null); } var code = ToEnumConverter.GetCode(codeStr); 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)); }
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); }
static OpCodeInfoTestCase ReadTestCase(string line, int lineNo) { var parts = line.Split(seps); if (parts.Length != 8) { throw new InvalidOperationException($"Invalid number of commas ({parts.Length - 1} commas)"); } var tc = new OpCodeInfoTestCase(); tc.LineNumber = lineNo; tc.IsInstruction = true; tc.GroupIndex = -1; var code = parts[0].Trim(); if (CodeUtils.IsIgnored(code)) { return(null); } tc.Code = ToCode(code); tc.Encoding = ToEncoding(parts[1].Trim()); tc.MandatoryPrefix = ToMandatoryPrefix(parts[2].Trim()); tc.Table = ToTable(parts[3].Trim()); tc.OpCode = ToOpCode(parts[4].Trim()); tc.OpCodeString = parts[5].Trim(); tc.InstructionString = parts[6].Trim().Replace('|', ','); bool gotVectorLength = false; bool gotW = false; foreach (var part in parts[7].Split(optsseps)) { var key = part.Trim(); if (key.Length == 0) { continue; } int index = key.IndexOf('='); if (index >= 0) { var value = key.Substring(index + 1); key = key.Substring(0, index); switch (key) { case OpCodeInfoKeys.GroupIndex: if (!uint.TryParse(value, out uint groupIndex) || groupIndex > 7) { throw new InvalidOperationException($"Invalid group index: {value}"); } tc.GroupIndex = (int)groupIndex; tc.IsGroup = true; break; case OpCodeInfoKeys.OpCodeOperandKind: var opParts = value.Split(opseps); tc.OpCount = opParts.Length; if (opParts.Length >= 1) { tc.Op0Kind = ToOpCodeOperandKind(opParts[0]); } if (opParts.Length >= 2) { tc.Op1Kind = ToOpCodeOperandKind(opParts[1]); } if (opParts.Length >= 3) { tc.Op2Kind = ToOpCodeOperandKind(opParts[2]); } if (opParts.Length >= 4) { tc.Op3Kind = ToOpCodeOperandKind(opParts[3]); } if (opParts.Length >= 5) { tc.Op4Kind = ToOpCodeOperandKind(opParts[4]); } Static.Assert(IcedConstants.MaxOpCount == 5 ? 0 : -1); if (opParts.Length >= 6) { throw new InvalidOperationException($"Invalid number of operands: '{value}'"); } break; case OpCodeInfoKeys.TupleType: tc.TupleType = ToTupleType(value.Trim()); break; default: throw new InvalidOperationException($"Invalid key: '{key}'"); } } else { switch (key) { case OpCodeInfoFlags.NotInstruction: tc.IsInstruction = false; break; case OpCodeInfoFlags.Bit16: tc.Mode16 = true; break; case OpCodeInfoFlags.Bit32: tc.Mode32 = true; break; case OpCodeInfoFlags.Bit64: tc.Mode64 = true; break; case OpCodeInfoFlags.Fwait: tc.Fwait = true; break; case OpCodeInfoFlags.OperandSize16: tc.OperandSize = 16; break; case OpCodeInfoFlags.OperandSize32: tc.OperandSize = 32; break; case OpCodeInfoFlags.OperandSize64: tc.OperandSize = 64; break; case OpCodeInfoFlags.AddressSize16: tc.AddressSize = 16; break; case OpCodeInfoFlags.AddressSize32: tc.AddressSize = 32; break; case OpCodeInfoFlags.AddressSize64: tc.AddressSize = 64; break; case OpCodeInfoFlags.LIG: tc.IsLIG = true; gotVectorLength = true; break; case OpCodeInfoFlags.L0: tc.L = 0; gotVectorLength = true; break; case OpCodeInfoFlags.L1: tc.L = 1; gotVectorLength = true; break; case OpCodeInfoFlags.L128: tc.L = 0; gotVectorLength = true; break; case OpCodeInfoFlags.L256: tc.L = 1; gotVectorLength = true; break; case OpCodeInfoFlags.L512: tc.L = 2; gotVectorLength = true; break; case OpCodeInfoFlags.WIG: tc.IsWIG = true; gotW = true; break; case OpCodeInfoFlags.WIG32: tc.W = 0; tc.IsWIG32 = true; gotW = true; break; case OpCodeInfoFlags.W0: tc.W = 0; gotW = true; break; case OpCodeInfoFlags.W1: tc.W = 1; gotW = true; break; case OpCodeInfoFlags.Broadcast: tc.CanBroadcast = true; break; case OpCodeInfoFlags.RoundingControl: tc.CanUseRoundingControl = true; break; case OpCodeInfoFlags.SuppressAllExceptions: tc.CanSuppressAllExceptions = true; break; case OpCodeInfoFlags.OpMaskRegister: tc.CanUseOpMaskRegister = true; break; case OpCodeInfoFlags.RequireNonZeroOpMaskRegister: tc.CanUseOpMaskRegister = true; tc.RequireNonZeroOpMaskRegister = true; break; case OpCodeInfoFlags.ZeroingMasking: tc.CanUseZeroingMasking = true; break; case OpCodeInfoFlags.LockPrefix: tc.CanUseLockPrefix = true; break; case OpCodeInfoFlags.XacquirePrefix: tc.CanUseXacquirePrefix = true; break; case OpCodeInfoFlags.XreleasePrefix: tc.CanUseXreleasePrefix = true; break; case OpCodeInfoFlags.RepPrefix: case OpCodeInfoFlags.RepePrefix: tc.CanUseRepPrefix = true; break; case OpCodeInfoFlags.RepnePrefix: tc.CanUseRepnePrefix = true; break; case OpCodeInfoFlags.BndPrefix: tc.CanUseBndPrefix = true; break; case OpCodeInfoFlags.HintTakenPrefix: tc.CanUseHintTakenPrefix = true; break; case OpCodeInfoFlags.NotrackPrefix: tc.CanUseNotrackPrefix = true; break; default: throw new InvalidOperationException($"Invalid key: '{key}'"); } } } switch (tc.Encoding) { case EncodingKind.Legacy: case EncodingKind.D3NOW: break; case EncodingKind.VEX: case EncodingKind.EVEX: case EncodingKind.XOP: if (!gotVectorLength) { throw new InvalidOperationException("Missing vector length: L0/L1/L128/L256/L512/LIG"); } if (!gotW) { throw new InvalidOperationException("Missing W bit: W0/W1/WIG/WIG32"); } break; default: throw new InvalidOperationException(); } return(tc); }