#pragma warning disable xUnit1026 // Theory methods should use all of their parameters void Test_all_OpCodeInfos(int lineNo, Code code, string opCodeString, OpCodeInfoTestCase tc) { #pragma warning restore xUnit1026 // Theory methods should use all of their parameters var info = tc.Code.ToOpCode(); Assert.Equal(tc.Code, info.Code); #pragma warning disable xUnit2006 // Do not use invalid string equality check // Show the full string without ellipses by using Equal<string>() instead of Equal() Assert.Equal <string>(tc.OpCodeString, info.ToString()); #pragma warning restore xUnit2006 // Do not use invalid string equality check Assert.Equal(tc.Encoding, info.Encoding); Assert.Equal(tc.IsInstruction, info.IsInstruction); Assert.Equal(tc.Mode16, info.Mode16); Assert.Equal(tc.Mode32, info.Mode32); Assert.Equal(tc.Mode64, info.Mode64); Assert.Equal(tc.Fwait, info.Fwait); Assert.Equal(tc.OperandSize, info.OperandSize); Assert.Equal(tc.AddressSize, info.AddressSize); Assert.Equal(tc.L, info.L); Assert.Equal(tc.W, info.W); Assert.Equal(tc.IsLIG, info.IsLIG); Assert.Equal(tc.IsWIG, info.IsWIG); Assert.Equal(tc.IsWIG32, info.IsWIG32); Assert.Equal(tc.TupleType, info.TupleType); Assert.Equal(tc.CanBroadcast, info.CanBroadcast); Assert.Equal(tc.CanUseRoundingControl, info.CanUseRoundingControl); Assert.Equal(tc.CanSuppressAllExceptions, info.CanSuppressAllExceptions); Assert.Equal(tc.CanUseOpMaskRegister, info.CanUseOpMaskRegister); Assert.Equal(tc.CanUseZeroingMasking, info.CanUseZeroingMasking); Assert.Equal(tc.CanUseLockPrefix, info.CanUseLockPrefix); Assert.Equal(tc.CanUseXacquirePrefix, info.CanUseXacquirePrefix); Assert.Equal(tc.CanUseXreleasePrefix, info.CanUseXreleasePrefix); Assert.Equal(tc.CanUseRepPrefix, info.CanUseRepPrefix); Assert.Equal(tc.CanUseRepnePrefix, info.CanUseRepnePrefix); Assert.Equal(tc.CanUseBndPrefix, info.CanUseBndPrefix); Assert.Equal(tc.CanUseHintTakenPrefix, info.CanUseHintTakenPrefix); Assert.Equal(tc.CanUseNotrackPrefix, info.CanUseNotrackPrefix); Assert.Equal(tc.Table, info.Table); Assert.Equal(tc.MandatoryPrefix, info.MandatoryPrefix); Assert.Equal(tc.OpCode, info.OpCode); Assert.Equal(tc.IsGroup, info.IsGroup); Assert.Equal(tc.GroupIndex, info.GroupIndex); Assert.Equal(tc.OpCount, info.OpCount); Assert.Equal(tc.Op0Kind, info.Op0Kind); Assert.Equal(tc.Op1Kind, info.Op1Kind); Assert.Equal(tc.Op2Kind, info.Op2Kind); Assert.Equal(tc.Op3Kind, info.Op3Kind); Assert.Equal(tc.Op4Kind, info.Op4Kind); Assert.Equal(tc.Op0Kind, info.GetOpKind(0)); Assert.Equal(tc.Op1Kind, info.GetOpKind(1)); Assert.Equal(tc.Op2Kind, info.GetOpKind(2)); Assert.Equal(tc.Op3Kind, info.GetOpKind(3)); Assert.Equal(tc.Op4Kind, info.GetOpKind(4)); Assert.Equal(5, Iced.Intel.DecoderConstants.MaxOpCount); for (int i = tc.OpCount; i < Iced.Intel.DecoderConstants.MaxOpCount; i++) { Assert.Equal(OpCodeOperandKind.None, info.GetOpKind(i)); } }
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); }
#pragma warning disable xUnit1026 // Theory methods should use all of their parameters void Test_all_OpCodeInfos(int lineNo, Code code, string opCodeString, string instructionString, OpCodeInfoTestCase tc) { #pragma warning restore xUnit1026 // Theory methods should use all of their parameters var info = tc.Code.ToOpCode(); Assert.Equal(tc.Code, info.Code); #pragma warning disable xUnit2006 // Do not use invalid string equality check // Show the full string without ellipses by using Equal<string>() instead of Equal() Assert.Equal <string>(tc.OpCodeString, info.ToOpCodeString()); Assert.Equal <string>(tc.InstructionString, info.ToInstructionString()); #pragma warning restore xUnit2006 // Do not use invalid string equality check Assert.True((object)info.ToInstructionString() == info.ToString()); Assert.Equal(tc.Mnemonic, info.Mnemonic); Assert.Equal(tc.Encoding, info.Encoding); Assert.Equal(tc.IsInstruction, info.IsInstruction); Assert.Equal(tc.Mode16, info.Mode16); Assert.Equal(tc.Mode16, info.IsAvailableInMode(16)); Assert.Equal(tc.Mode32, info.Mode32); Assert.Equal(tc.Mode32, info.IsAvailableInMode(32)); Assert.Equal(tc.Mode64, info.Mode64); Assert.Equal(tc.Mode64, info.IsAvailableInMode(64)); Assert.Equal(tc.Fwait, info.Fwait); Assert.Equal(tc.OperandSize, info.OperandSize); Assert.Equal(tc.AddressSize, info.AddressSize); Assert.Equal(tc.L, info.L); Assert.Equal(tc.W, info.W); Assert.Equal(tc.IsLIG, info.IsLIG); Assert.Equal(tc.IsWIG, info.IsWIG); Assert.Equal(tc.IsWIG32, info.IsWIG32); Assert.Equal(tc.TupleType, info.TupleType); Assert.Equal(tc.MemorySize, info.MemorySize); Assert.Equal(tc.BroadcastMemorySize, info.BroadcastMemorySize); Assert.Equal(tc.DecoderOption, info.DecoderOption); Assert.Equal(tc.CanBroadcast, info.CanBroadcast); Assert.Equal(tc.CanUseRoundingControl, info.CanUseRoundingControl); Assert.Equal(tc.CanSuppressAllExceptions, info.CanSuppressAllExceptions); Assert.Equal(tc.CanUseOpMaskRegister, info.CanUseOpMaskRegister); Assert.Equal(tc.RequireOpMaskRegister, info.RequireOpMaskRegister); if (tc.RequireOpMaskRegister) { Assert.True(info.CanUseOpMaskRegister); Assert.False(info.CanUseZeroingMasking); } Assert.Equal(tc.CanUseZeroingMasking, info.CanUseZeroingMasking); Assert.Equal(tc.CanUseLockPrefix, info.CanUseLockPrefix); Assert.Equal(tc.CanUseXacquirePrefix, info.CanUseXacquirePrefix); Assert.Equal(tc.CanUseXreleasePrefix, info.CanUseXreleasePrefix); Assert.Equal(tc.CanUseRepPrefix, info.CanUseRepPrefix); Assert.Equal(tc.CanUseRepnePrefix, info.CanUseRepnePrefix); Assert.Equal(tc.CanUseBndPrefix, info.CanUseBndPrefix); Assert.Equal(tc.CanUseHintTakenPrefix, info.CanUseHintTakenPrefix); Assert.Equal(tc.CanUseNotrackPrefix, info.CanUseNotrackPrefix); Assert.Equal(tc.IgnoresRoundingControl, info.IgnoresRoundingControl); Assert.Equal(tc.AmdLockRegBit, info.AmdLockRegBit); Assert.Equal(tc.DefaultOpSize64, info.DefaultOpSize64); Assert.Equal(tc.ForceOpSize64, info.ForceOpSize64); Assert.Equal(tc.IntelForceOpSize64, info.IntelForceOpSize64); Assert.Equal(tc.Cpl0 && !tc.Cpl1 && !tc.Cpl2 && !tc.Cpl3, info.MustBeCpl0); Assert.Equal(tc.Cpl0, info.Cpl0); Assert.Equal(tc.Cpl1, info.Cpl1); Assert.Equal(tc.Cpl2, info.Cpl2); Assert.Equal(tc.Cpl3, info.Cpl3); Assert.Equal(tc.IsInputOutput, info.IsInputOutput); Assert.Equal(tc.IsNop, info.IsNop); Assert.Equal(tc.IsReservedNop, info.IsReservedNop); Assert.Equal(tc.IsSerializingIntel, info.IsSerializingIntel); Assert.Equal(tc.IsSerializingAmd, info.IsSerializingAmd); Assert.Equal(tc.MayRequireCpl0, info.MayRequireCpl0); Assert.Equal(tc.IsCetTracked, info.IsCetTracked); Assert.Equal(tc.IsNonTemporal, info.IsNonTemporal); Assert.Equal(tc.IsFpuNoWait, info.IsFpuNoWait); Assert.Equal(tc.IgnoresModBits, info.IgnoresModBits); Assert.Equal(tc.No66, info.No66); Assert.Equal(tc.NFx, info.NFx); Assert.Equal(tc.RequiresUniqueRegNums, info.RequiresUniqueRegNums); Assert.Equal(tc.RequiresUniqueDestRegNum, info.RequiresUniqueDestRegNum); Assert.Equal(tc.IsPrivileged, info.IsPrivileged); Assert.Equal(tc.IsSaveRestore, info.IsSaveRestore); Assert.Equal(tc.IsStackInstruction, info.IsStackInstruction); Assert.Equal(tc.IgnoresSegment, info.IgnoresSegment); Assert.Equal(tc.IsOpMaskReadWrite, info.IsOpMaskReadWrite); Assert.Equal(tc.RealMode, info.RealMode); Assert.Equal(tc.ProtectedMode, info.ProtectedMode); Assert.Equal(tc.Virtual8086Mode, info.Virtual8086Mode); Assert.Equal(tc.CompatibilityMode, info.CompatibilityMode); Assert.Equal(tc.LongMode, info.LongMode); Assert.Equal(tc.UseOutsideSmm, info.UseOutsideSmm); Assert.Equal(tc.UseInSmm, info.UseInSmm); Assert.Equal(tc.UseOutsideEnclaveSgx, info.UseOutsideEnclaveSgx); Assert.Equal(tc.UseInEnclaveSgx1, info.UseInEnclaveSgx1); Assert.Equal(tc.UseInEnclaveSgx2, info.UseInEnclaveSgx2); Assert.Equal(tc.UseOutsideVmxOp, info.UseOutsideVmxOp); Assert.Equal(tc.UseInVmxRootOp, info.UseInVmxRootOp); Assert.Equal(tc.UseInVmxNonRootOp, info.UseInVmxNonRootOp); Assert.Equal(tc.UseOutsideSeam, info.UseOutsideSeam); Assert.Equal(tc.UseInSeam, info.UseInSeam); Assert.Equal(tc.TdxNonRootGenUd, info.TdxNonRootGenUd); Assert.Equal(tc.TdxNonRootGenVe, info.TdxNonRootGenVe); Assert.Equal(tc.TdxNonRootMayGenEx, info.TdxNonRootMayGenEx); Assert.Equal(tc.IntelVmExit, info.IntelVmExit); Assert.Equal(tc.IntelMayVmExit, info.IntelMayVmExit); Assert.Equal(tc.IntelSmmVmExit, info.IntelSmmVmExit); Assert.Equal(tc.AmdVmExit, info.AmdVmExit); Assert.Equal(tc.AmdMayVmExit, info.AmdMayVmExit); Assert.Equal(tc.TsxAbort, info.TsxAbort); Assert.Equal(tc.TsxImplAbort, info.TsxImplAbort); Assert.Equal(tc.TsxMayAbort, info.TsxMayAbort); Assert.Equal(tc.IntelDecoder16, info.IntelDecoder16); Assert.Equal(tc.IntelDecoder32, info.IntelDecoder32); Assert.Equal(tc.IntelDecoder64, info.IntelDecoder64); Assert.Equal(tc.AmdDecoder16, info.AmdDecoder16); Assert.Equal(tc.AmdDecoder32, info.AmdDecoder32); Assert.Equal(tc.AmdDecoder64, info.AmdDecoder64); Assert.Equal(tc.Table, info.Table); Assert.Equal(tc.MandatoryPrefix, info.MandatoryPrefix); Assert.Equal(tc.OpCode, info.OpCode); Assert.Equal(tc.OpCodeLength, info.OpCodeLength); Assert.Equal(tc.IsGroup, info.IsGroup); Assert.Equal(tc.GroupIndex, info.GroupIndex); Assert.Equal(tc.IsRmGroup, info.IsRmGroup); Assert.Equal(tc.RmGroupIndex, info.RmGroupIndex); Assert.Equal(tc.OpCount, info.OpCount); Assert.Equal(tc.Op0Kind, info.Op0Kind); Assert.Equal(tc.Op1Kind, info.Op1Kind); Assert.Equal(tc.Op2Kind, info.Op2Kind); Assert.Equal(tc.Op3Kind, info.Op3Kind); Assert.Equal(tc.Op4Kind, info.Op4Kind); Assert.Equal(tc.Op0Kind, info.GetOpKind(0)); Assert.Equal(tc.Op1Kind, info.GetOpKind(1)); Assert.Equal(tc.Op2Kind, info.GetOpKind(2)); Assert.Equal(tc.Op3Kind, info.GetOpKind(3)); Assert.Equal(tc.Op4Kind, info.GetOpKind(4)); Static.Assert(IcedConstants.MaxOpCount == 5 ? 0 : -1); for (int i = tc.OpCount; i < IcedConstants.MaxOpCount; i++) { Assert.Equal(OpCodeOperandKind.None, info.GetOpKind(i)); } }
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; tc.Code = ToCode(parts[0].Trim()); 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 "g": 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 "op": 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]); } if (Iced.Intel.DecoderConstants.MaxOpCount != 5) { throw new InvalidOperationException("Invalid MaxOpCount value"); } if (opParts.Length >= 6) { throw new InvalidOperationException($"Invalid number of operands: '{value}'"); } break; case "tt": tc.TupleType = ToTupleType(value.Trim()); break; default: throw new InvalidOperationException($"Invalid key: '{key}'"); } } else { switch (key) { case "notinstr": tc.IsInstruction = false; break; case "16b": tc.Mode16 = true; break; case "32b": tc.Mode32 = true; break; case "64b": tc.Mode64 = true; break; case "fwait": tc.Fwait = true; break; case "o16": tc.OperandSize = 16; break; case "o32": tc.OperandSize = 32; break; case "o64": tc.OperandSize = 64; break; case "a16": tc.AddressSize = 16; break; case "a32": tc.AddressSize = 32; break; case "a64": tc.AddressSize = 64; break; case "LIG": tc.IsLIG = true; gotVectorLength = true; break; case "L0": tc.L = 0; gotVectorLength = true; break; case "L1": tc.L = 1; gotVectorLength = true; break; case "L128": tc.L = 0; gotVectorLength = true; break; case "L256": tc.L = 1; gotVectorLength = true; break; case "L512": tc.L = 2; gotVectorLength = true; break; case "WIG": tc.IsWIG = true; gotW = true; break; case "WIG32": tc.W = 0; tc.IsWIG32 = true; gotW = true; break; case "W0": tc.W = 0; gotW = true; break; case "W1": tc.W = 1; gotW = true; break; case "b": tc.CanBroadcast = true; break; case "er": tc.CanUseRoundingControl = true; break; case "sae": tc.CanSuppressAllExceptions = true; break; case "k": tc.CanUseOpMaskRegister = true; break; case "z": tc.CanUseZeroingMasking = true; break; case "lock": tc.CanUseLockPrefix = true; break; case "xacquire": tc.CanUseXacquirePrefix = true; break; case "xrelease": tc.CanUseXreleasePrefix = true; break; case "rep": case "repe": tc.CanUseRepPrefix = true; break; case "repne": tc.CanUseRepnePrefix = true; break; case "bnd": tc.CanUseBndPrefix = true; break; case "ht": tc.CanUseHintTakenPrefix = true; break; case "notrack": 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"); } break; default: throw new InvalidOperationException(); } 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; tc.Code = ToCode(parts[0].Trim()); 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); }