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); }