using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using Indy.IL2CPU.Assembler.X86; namespace Indy.IL2CPU.Tests.AssemblerTests.X86 { public static partial class TestCodeGenerator { private static string mOutFile; class ConstraintsContainer { public Constraints SourceInfo; public Constraints DestInfo; public Instruction.InstructionSizes InvalidSizes = Instruction.InstructionSizes.None; public bool MemToMem = false; public bool ImmediateToImmediate = false; } public class TestState { public string Description; public bool Success; public string Message; } class Constraints { public bool TestMem32 = true; public bool TestMem16 = true; public bool TestMem8 = true; public bool TestImmediate8 = true; public bool TestImmediate16 = true; public bool TestImmediate32 = true; public bool TestRegisters = true; public bool TestCR = false; public bool TestSegments = false; public IEnumerable InvalidRegisters = new Guid[0]; } private static Dictionary opcodesException; private static void Initialize() { var xTempPath = typeof(TestCodeGenerator).Assembly.Location; xTempPath = xTempPath.Substring(0, xTempPath.LastIndexOf("source", StringComparison.InvariantCultureIgnoreCase) + "source".Length); xTempPath = Path.Combine(xTempPath, "Indy.IL2CPU.Tests"); xTempPath = Path.Combine(xTempPath, "AssemblerTests"); xTempPath = Path.Combine(xTempPath, "X86"); mOutFile = Path.Combine(xTempPath, "AutoGeneratedTests.cs"); opcodesException = new Dictionary(); AddExceptions(); } public static void Execute() { Initialize(); if ((File.GetAttributes(mOutFile) & FileAttributes.ReadOnly) != 0) { throw new Exception(String.Format("File '{0}' is readonly, please check the file out!", mOutFile)); } using (var xOutput = new StreamWriter(mOutFile, false)) { xOutput.WriteLine("using System;"); xOutput.WriteLine("using System.Collections.Generic;"); xOutput.WriteLine("using System.Linq;"); xOutput.WriteLine("using System.Text;"); xOutput.WriteLine("using Indy.IL2CPU.Assembler.X86;"); xOutput.WriteLine("using NUnit.Framework;"); xOutput.WriteLine(); xOutput.WriteLine("namespace Indy.IL2CPU.Tests.AssemblerTests.X86 {"); foreach (Type type in typeof(Instruction).Assembly.GetTypes()) { if (type == typeof(ShiftLeft)) { System.Diagnostics.Debugger.Break(); } GenerateSingle(type, xOutput); } xOutput.WriteLine("}"); } } private static void GenerateSingle(Type aType, StreamWriter aOutput) { if (aType.IsAbstract) { return; } if (!aType.IsSubclassOf(typeof(Instruction))) { return; } if (!Instruction.HasEncodingOptions(aType)) { WriteTestFixtureHeader(aType, aOutput); { aOutput.WriteLine("[Test]"); aOutput.WriteLine("[Category(\"MissingEncodingOptions\")]"); aOutput.WriteLine("public void DoTest(){"); aOutput.WriteLine("Assert.Fail(\"No Encoding Options specified\");"); aOutput.WriteLine("}"); } WriteTestFixtureFooter(aType, aOutput); return; } if (aType.IsSubclassOf(typeof(Assembler.X86.InstructionWithDestinationAndSourceAndSize))) { GenerateInstructionWithDestinationAndSourceAndSize(aType, aOutput); return; } if (aType.IsSubclassOf(typeof(Assembler.X86.InstructionWithDestinationAndSource))) { GenerateInstructionWithDestinationAndSource(aType, aOutput); return; } if (aType.IsSubclassOf(typeof(Assembler.X86.InstructionWithDestinationAndSize))) { GenerateInstructionWithDestinationAndSize(aType, aOutput); return; } if (aType.IsSubclassOf(typeof(Assembler.X86.InstructionWithDestination))) { GenerateInstructionWithDestination(aType, aOutput); return; } if (aType.IsSubclassOf(typeof(Assembler.X86.InstructionWithSize))) { GenerateInstructionWithSize(aType, aOutput); return; } if (aType.IsSubclassOf(typeof(Assembler.X86.Instruction))) { GenerateSimpleInstruction(aType, aOutput); return; } throw new Exception("Type not handled: " + aType.FullName); } private static void WriteTestFixtureHeader(Type aType, StreamWriter aOutput) { aOutput.WriteLine("\t[TestFixture]"); aOutput.WriteLine("\tpublic partial class {0}Tests: BaseTest {{", aType.Name); } private static void WriteTestFixtureFooter(Type aType, StreamWriter aOutput) { aOutput.WriteLine("\t}"); } private static void WriteTestMethodHeader(string aName, StreamWriter aOutput) { aOutput.WriteLine("\t\t[Test]"); aOutput.WriteLine("\t\tpublic void Test{0}() {{", aName); } private static void WriteTestMethodFooter(string aName, StreamWriter aOutput) { aOutput.WriteLine("\t\t\tVerify();"); aOutput.WriteLine("\t\t}"); } private static void GenerateSimpleInstruction(Type aType, StreamWriter aOutput) { WriteTestFixtureHeader(aType, aOutput); { WriteTestMethodHeader("Instruction", aOutput); { aOutput.WriteLine("\t\t\tnew global::{0}();", aType.FullName); } WriteTestMethodFooter("Instruction", aOutput); } WriteTestFixtureFooter(aType, aOutput); } private static void GenerateInstructionWithSize(Type aType, StreamWriter aOutput) { ConstraintsContainer xInfo = null; if (opcodesException.ContainsKey(aType)) { xInfo = opcodesException[aType]; } WriteTestFixtureHeader(aType, aOutput); { if (!(xInfo != null && ((xInfo.InvalidSizes & Instruction.InstructionSizes.DWord) != 0))) { WriteTestMethodHeader("InstructionSize32", aOutput); { aOutput.WriteLine("\t\t\tnew global::{0}{{Size = 32}};", aType.FullName); } WriteTestMethodFooter("InstructionSize32", aOutput); } if (!(xInfo != null && ((xInfo.InvalidSizes & Instruction.InstructionSizes.Word) != 0))) { WriteTestMethodHeader("InstructionSize16", aOutput); { aOutput.WriteLine("\t\t\tnew global::{0}{{Size = 16}};", aType.FullName); } WriteTestMethodFooter("InstructionSize16", aOutput); } if (!(xInfo != null && ((xInfo.InvalidSizes & Instruction.InstructionSizes.Byte) != 0))) { WriteTestMethodHeader("InstructionSize8", aOutput); { aOutput.WriteLine("\t\t\tnew global::{0}{{Size = 8}};", aType.FullName); } WriteTestMethodFooter("InstructionSize8", aOutput); } } WriteTestFixtureFooter(aType, aOutput); } private static void GenerateInstructionWithDestination(Type aType, StreamWriter aOutput) { WriteTestFixtureHeader(aType, aOutput); { foreach (var xItem in GetDestinationPossibilities(aType)) { if (xItem.Value.Length > 0) { WriteTestMethodHeader(xItem.Key, aOutput); { foreach (var xLine in xItem.Value) { aOutput.WriteLine("\t\t\tnew global::{0}{{{1}}};", aType.FullName, xLine); } } WriteTestMethodFooter(xItem.Key, aOutput); } } } WriteTestFixtureFooter(aType, aOutput); } private static bool ShouldTestMemorySource(Type aType, byte aSize) { if (!opcodesException.ContainsKey(aType)) { return true; } if (opcodesException[aType].SourceInfo == null) { return true; } switch (aSize) { case 8: return opcodesException[aType].SourceInfo.TestMem8; case 16: return opcodesException[aType].SourceInfo.TestMem16; case 32: return opcodesException[aType].SourceInfo.TestMem32; default: throw new Exception("Wrong Size: " + aSize); } } private static bool ShouldTestImmediateSource(Type aType, byte aSize) { if (!opcodesException.ContainsKey(aType)) { return true; } if (opcodesException[aType].SourceInfo == null) { return true; } switch (aSize) { case 8: return opcodesException[aType].SourceInfo.TestImmediate8; case 16: return opcodesException[aType].SourceInfo.TestImmediate16; case 32: return opcodesException[aType].SourceInfo.TestImmediate32; default: throw new Exception("Wrong Size: " + aSize); } } private static bool ShouldTestMemoryDestination(Type aType, byte aSize) { if (!opcodesException.ContainsKey(aType)) { return true; } if (opcodesException[aType].DestInfo == null) { return true; } switch (aSize) { case 8: return opcodesException[aType].DestInfo.TestMem8; case 16: return opcodesException[aType].DestInfo.TestMem16; case 32: return opcodesException[aType].DestInfo.TestMem32; default: throw new Exception("Wrong Size: " + aSize); } } private static bool ShouldTestImmediateDestination(Type aType, byte aSize) { if (!opcodesException.ContainsKey(aType)) { return true; } if (opcodesException[aType].DestInfo == null) { return true; } switch (aSize) { case 8: return opcodesException[aType].DestInfo.TestImmediate8; case 16: return opcodesException[aType].DestInfo.TestImmediate16; case 32: return opcodesException[aType].DestInfo.TestImmediate32; default: throw new Exception("Wrong Size: " + aSize); } } private static void GenerateInstructionWithDestinationAndSize(Type aType, StreamWriter aOutput) { WriteTestFixtureHeader(aType, aOutput); { foreach (var xSize in new byte[] { 8, 16, 32 }) { foreach (var xItem in GetDestinationWithSizePossibilities(aType, xSize)) { if (xItem.Value.Length == 0) { continue; } WriteTestMethodHeader(xItem.Key + "Size" + xSize, aOutput); { foreach (var xLine in xItem.Value) { aOutput.WriteLine("\t\t\tnew global::{0}{{{1}, Size = {2}}};", aType.FullName, xLine, xSize); } } WriteTestMethodFooter(xItem.Key + "Size" + xSize, aOutput); } } } WriteTestFixtureFooter(aType, aOutput); } private static IEnumerable> GetDestinationPossibilities(Type aType) { if (!opcodesException.ContainsKey(aType) || opcodesException[aType].DestInfo == null || opcodesException[aType].DestInfo.TestImmediate32) { yield return new KeyValuePair("ImmediateDestination", new string[] { "DestinationValue = 30", "DestinationValue = 300", "DestinationValue = 300000" }); } if (!opcodesException.ContainsKey(aType) || opcodesException[aType].DestInfo == null || opcodesException[aType].DestInfo.TestMem32) { yield return new KeyValuePair("8BitMemoryAddressDestination", new string[] { "DestinationValue = 65, DestinationIsIndirect = true"}); yield return new KeyValuePair("16BitMemoryAddressDestination", new string[] { "DestinationValue = 650, DestinationIsIndirect = true"}); yield return new KeyValuePair("32BitMemoryAddressDestination", new string[] { "DestinationValue = 650000, DestinationIsIndirect = true"}); } if (!opcodesException.ContainsKey(aType) || opcodesException[aType].DestInfo.TestRegisters) { var xRegistersToSkip = new List(); if (opcodesException.ContainsKey(aType) && opcodesException[aType].DestInfo.InvalidRegisters != null) { xRegistersToSkip.AddRange(opcodesException[aType].DestInfo.InvalidRegisters); } foreach (var xReg in Registers.GetRegisters()) { if (xRegistersToSkip.Contains(xReg)) { continue; } if (!Registers.Is32Bit(xReg)) { continue; } if (Registers.IsCR(xReg)) { continue; } if (!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && opcodesException[aType].DestInfo.TestMem32)) { yield return new KeyValuePair("MemoryAtRegister" + Registers.GetRegisterName(xReg) + "Destination", new string[] { String.Format("DestinationReg = Registers.{0}, DestinationIsIndirect=true", Registers.GetRegisterName(xReg)), //offset 8 String.Format("DestinationReg = Registers.{0}, DestinationIsIndirect=true, DestinationDisplacement = 203", Registers.GetRegisterName(xReg)), //offset 16 String.Format("DestinationReg = Registers.{0}, DestinationIsIndirect=true, DestinationDisplacement = 2030", Registers.GetRegisterName(xReg)), //offset 32 String.Format("DestinationReg = Registers.{0}, DestinationIsIndirect=true, DestinationDisplacement = 203000", Registers.GetRegisterName(xReg))}); } } var xItems = new List(); foreach (Guid register in Registers.GetRegisters()) { if (!aType.Namespace.Contains("SSE") && (Registers.getXMMs().Contains(register))) continue; if (Registers.getCRs().Contains(register) && (!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && (!opcodesException[aType].DestInfo.TestCR)))) continue; if ((!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && opcodesException[aType].DestInfo.InvalidRegisters != null && (opcodesException[aType].DestInfo.InvalidRegisters.Contains(register))))) continue; if (Registers.IsSegment(register) && !(opcodesException.ContainsKey(aType) && opcodesException[aType].DestInfo.TestSegments)) { continue; } if (Registers.GetSize(register) == 32) { xItems.Add("DestinationReg = Registers." + Registers.GetRegisterName(register)); } } if (xItems.Count > 0) { yield return new KeyValuePair("RegisterDestination", xItems.ToArray()); } } yield break; } private static IEnumerable> GetSourcePossibilities(Type aType) { if (!opcodesException.ContainsKey(aType) || opcodesException[aType].SourceInfo == null || opcodesException[aType].SourceInfo.TestImmediate32) { yield return new KeyValuePair("ImmediateSource", new string[] { "SourceValue = 30", "SourceValue = 300", "SourceValue = 300000" }); } if (!opcodesException.ContainsKey(aType) || opcodesException[aType].SourceInfo == null || opcodesException[aType].SourceInfo.TestMem32) { yield return new KeyValuePair("8BitMemoryAddressSource", new string[] { "SourceValue = 65, SourceIsIndirect = true"}); yield return new KeyValuePair("16BitMemoryAddressSource", new string[] { "SourceValue = 650, SourceIsIndirect = true"}); yield return new KeyValuePair("32BitMemoryAddressSource", new string[] { "SourceValue = 650000, SourceIsIndirect = true"}); } if (!opcodesException.ContainsKey(aType) || opcodesException[aType].SourceInfo.TestRegisters) { var xRegistersToSkip = new List(); if (opcodesException.ContainsKey(aType) && opcodesException[aType].SourceInfo.InvalidRegisters != null) { xRegistersToSkip.AddRange(opcodesException[aType].SourceInfo.InvalidRegisters); } foreach (var xReg in Registers.GetRegisters()) { if (xRegistersToSkip.Contains(xReg)) { continue; } if (!Registers.Is32Bit(xReg)) { continue; } if (Registers.IsCR(xReg)) { continue; } if (!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && opcodesException[aType].SourceInfo.TestMem32)) { yield return new KeyValuePair("MemoryAtRegister" + Registers.GetRegisterName(xReg) + "Source", new string[] { String.Format("SourceReg = Registers.{0}, SourceIsIndirect=true", Registers.GetRegisterName(xReg)), //offset 8 String.Format("SourceReg = Registers.{0}, SourceIsIndirect=true, SourceDisplacement = 203", Registers.GetRegisterName(xReg)), //offset 16 String.Format("SourceReg = Registers.{0}, SourceIsIndirect=true, SourceDisplacement = 2030", Registers.GetRegisterName(xReg)), //offset 32 String.Format("SourceReg = Registers.{0}, SourceIsIndirect=true, SourceDisplacement = 203000", Registers.GetRegisterName(xReg))}); } } var xItems = new List(); foreach (Guid register in Registers.GetRegisters()) { if (!aType.Namespace.Contains("SSE") && (Registers.getXMMs().Contains(register))) continue; if (Registers.getCRs().Contains(register) && (!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && (!opcodesException[aType].SourceInfo.TestCR)))) continue; if ((!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && opcodesException[aType].SourceInfo.InvalidRegisters != null && (opcodesException[aType].SourceInfo.InvalidRegisters.Contains(register))))) continue; if (Registers.IsSegment(register) && !(opcodesException.ContainsKey(aType) && opcodesException[aType].SourceInfo.TestSegments)) { continue; } if (Registers.GetSize(register) == 32) { xItems.Add("SourceReg = Registers." + Registers.GetRegisterName(register)); } } if (xItems.Count > 0) { yield return new KeyValuePair("RegisterSource", xItems.ToArray()); } } yield break; } private static IEnumerable> GetDestinationWithSizePossibilities(Type aType, byte aSize) { var xItems = new List(); { if (aSize == 8 && ShouldTestImmediateDestination(aType, aSize)) { //Test Immediate 8 xItems.Add(String.Format("DestinationValue = 30")); } if (aSize == 16 && ShouldTestImmediateDestination(aType, aSize)) { //Test Immediate 16 xItems.Add(String.Format("DestinationValue = 300")); } if (aSize == 32 && ShouldTestImmediateDestination(aType, aSize)) { //Test Immediate 32 xItems.Add(String.Format("DestinationValue = 300000")); } } yield return new KeyValuePair("ImmediateDestination", xItems.ToArray()); xItems.Clear(); if (ShouldTestMemoryDestination(aType, aSize)) { yield return new KeyValuePair(String.Format("MemoryDestination", aSize), new string[]{ //memory 8 bits address //no offset String.Format("DestinationValue = 65, DestinationIsIndirect = true"), //memory 16 bits address //no offset String.Format("DestinationValue = 650, DestinationIsIndirect = true"), // memory 32 bits address //no offset String.Format("DestinationValue = 650000, DestinationIsIndirect = true")}); } if (!opcodesException.ContainsKey(aType) || opcodesException[aType].DestInfo.TestRegisters) { var xRegistersToSkip = new List(); if (opcodesException.ContainsKey(aType) && opcodesException[aType].DestInfo.InvalidRegisters != null) { xRegistersToSkip.AddRange(opcodesException[aType].DestInfo.InvalidRegisters); } foreach (var xReg in Registers.GetRegisters()) { if (xRegistersToSkip.Contains(xReg)) { continue; } if (!Registers.Is32Bit(xReg)) { continue; } if (Registers.IsCR(xReg)) { continue; } if (ShouldTestMemoryDestination(aType, aSize)) { yield return new KeyValuePair("MemoryAtRegister" + Registers.GetRegisterName(xReg) + "Destination", new string[] { //memory //no offset String.Format("DestinationReg = Registers.{0}, DestinationIsIndirect = true", Registers.GetRegisterName(xReg)), //offset 8 String.Format("DestinationReg = Registers.{0}, DestinationIsIndirect = true, DestinationDisplacement = 203", Registers.GetRegisterName(xReg)), //offset 16 String.Format("DestinationReg = Registers.{0}, DestinationIsIndirect = true, DestinationDisplacement = 2030", Registers.GetRegisterName(xReg)), //offset 32 String.Format("DestinationReg = Registers.{0}, DestinationIsIndirect = true, DestinationDisplacement = 203000", Registers.GetRegisterName(xReg)) }); } } xItems.Clear(); foreach (Guid register in Registers.GetRegisters()) { if (!aType.Namespace.Contains("SSE") && (Registers.getXMMs().Contains(register))) continue; if (Registers.getCRs().Contains(register) && (!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && (!opcodesException[aType].DestInfo.TestCR)))) continue; if ((!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && opcodesException[aType].DestInfo.InvalidRegisters != null && (opcodesException[aType].DestInfo.InvalidRegisters.Contains(register))))) continue; if (Registers.IsSegment(register) && !(opcodesException.ContainsKey(aType) && opcodesException[aType].DestInfo.TestSegments)) { continue; } if (Registers.GetSize(register) == aSize) { xItems.Add(String.Format("DestinationReg = Registers.{0}", Registers.GetRegisterName(register))); } } if (xItems.Count > 0) { yield return new KeyValuePair("RegisterDestination", xItems.ToArray()); } } } private static IEnumerable> GetSourceWithSizePossibilities(Type aType, byte aSize) { var xItems = new List(); { if (aSize == 8 && ShouldTestImmediateSource(aType, aSize)) { //Test Immediate 8 xItems.Add(String.Format("SourceValue = 30")); } if (aSize == 16 && ShouldTestImmediateSource(aType, aSize)) { //Test Immediate 16 xItems.Add(String.Format("SourceValue = 300")); } if (aSize == 32 && ShouldTestImmediateSource(aType, aSize)) { //Test Immediate 32 xItems.Add(String.Format("SourceValue = 300000")); } } yield return new KeyValuePair("ImmediateSource", xItems.ToArray()); xItems.Clear(); if (ShouldTestMemorySource(aType, aSize)) { yield return new KeyValuePair(String.Format("MemorySource", aSize), new string[]{ //memory 8 bits address //no offset String.Format("SourceValue = 65, SourceIsIndirect = true"), //memory 16 bits address //no offset String.Format("SourceValue = 650, SourceIsIndirect = true"), // memory 32 bits address //no offset String.Format("SourceValue = 650000, SourceIsIndirect = true"), }); } if (!opcodesException.ContainsKey(aType) || opcodesException[aType].SourceInfo.TestRegisters) { var xRegistersToSkip = new List(); if (opcodesException.ContainsKey(aType) && opcodesException[aType].SourceInfo.InvalidRegisters != null) { xRegistersToSkip.AddRange(opcodesException[aType].SourceInfo.InvalidRegisters); } foreach (var xReg in Registers.GetRegisters()) { if (xRegistersToSkip.Contains(xReg)) { continue; } if (!Registers.Is32Bit(xReg)) { continue; } if (Registers.IsCR(xReg)) { continue; } if (ShouldTestMemorySource(aType, aSize)) { yield return new KeyValuePair("MemoryAtRegister" + Registers.GetRegisterName(xReg) + "Source", new string[] { //memory //no offset String.Format("SourceReg = Registers.{0}, SourceIsIndirect = true", Registers.GetRegisterName(xReg)), //offset 8 String.Format("SourceReg = Registers.{0}, SourceIsIndirect = true, SourceDisplacement = 203", Registers.GetRegisterName(xReg)), //offset 16 String.Format("SourceReg = Registers.{0}, SourceIsIndirect = true, SourceDisplacement = 2030", Registers.GetRegisterName(xReg)), //offset 32 String.Format("SourceReg = Registers.{0}, SourceIsIndirect = true, SourceDisplacement = 203000", Registers.GetRegisterName(xReg)) }); } } xItems.Clear(); foreach (Guid register in Registers.GetRegisters()) { if (!aType.Namespace.Contains("SSE") && (Registers.getXMMs().Contains(register))) continue; if (Registers.getCRs().Contains(register) && (!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && (!opcodesException[aType].SourceInfo.TestCR)))) continue; if ((!opcodesException.ContainsKey(aType) || (opcodesException.ContainsKey(aType) && opcodesException[aType].SourceInfo.InvalidRegisters != null && (opcodesException[aType].SourceInfo.InvalidRegisters.Contains(register))))) continue; if (Registers.IsSegment(register) && !(opcodesException.ContainsKey(aType) && opcodesException[aType].SourceInfo.TestSegments)) { continue; } if (Registers.GetSize(register) == aSize) { xItems.Add(String.Format("SourceReg = Registers.{0}", Registers.GetRegisterName(register))); } } if (xItems.Count > 0) { yield return new KeyValuePair("RegisterSource", xItems.ToArray()); } } } private static void GenerateInstructionWithDestinationAndSource(Type aType, StreamWriter aOutput) { WriteTestFixtureHeader(aType, aOutput); { foreach (var xSourceItem in GetSourcePossibilities(aType)) { foreach (var xDestItem in GetDestinationPossibilities(aType)) { if (opcodesException.ContainsKey(aType)) { if (!opcodesException[aType].MemToMem) { if (xSourceItem.Key.Contains("Memory") && xDestItem.Key.Contains("Memory")) { continue; } } if(!opcodesException[aType].ImmediateToImmediate) { if (xSourceItem.Key.Contains("Value") && xDestItem.Key.Contains("Value") && !xSourceItem.Key.Contains("IsIndirect") && !xDestItem.Key.Contains("IsIndirect")) { continue; } } } if(xSourceItem.Value.Length ==0) { continue; } WriteTestMethodHeader(xSourceItem.Key + xDestItem.Key, aOutput); { foreach (var xSourceLine in xSourceItem.Value) { { foreach (var xLine in xDestItem.Value) { aOutput.WriteLine("\t\t\tnew global::{0}{{{1}, {2}}};", aType.FullName, xSourceLine, xLine); } } } } WriteTestMethodFooter(xSourceItem.Key + xDestItem.Key, aOutput); } } } WriteTestFixtureFooter(aType, aOutput); } private static void GenerateInstructionWithDestinationAndSourceAndSize(Type aType, StreamWriter aOutput) { WriteTestFixtureHeader(aType, aOutput); { foreach(var xSize in new byte[] {8, 16, 32}){ foreach (var xSourceItem in GetSourceWithSizePossibilities(aType, xSize)) { foreach (var xDestItem in GetDestinationWithSizePossibilities(aType, xSize)) { if (opcodesException.ContainsKey(aType)) { if (!opcodesException[aType].MemToMem) { if (xSourceItem.Key.Contains("Memory") && xDestItem.Key.Contains("Memory")) { continue; } } if (!opcodesException[aType].ImmediateToImmediate) { if (xSourceItem.Key.Contains("Value") && xDestItem.Key.Contains("Value") && !xSourceItem.Key.Contains("IsIndirect") && !xDestItem.Key.Contains("IsIndirect")) { continue; } } } if (xSourceItem.Value.Length == 0) { continue; } WriteTestMethodHeader(xSourceItem.Key + xDestItem.Key + "Size" + xSize, aOutput); { foreach (var xSourceLine in xSourceItem.Value) { foreach (var xLine in xDestItem.Value) { aOutput.WriteLine("\t\t\tnew global::{0}{{{1}, {2}, Size = {3}}};", aType.FullName, xSourceLine, xLine, xSize); } } } WriteTestMethodFooter(xSourceItem.Key + xDestItem.Key + "Size" + xSize, aOutput); } } } } WriteTestFixtureFooter(aType, aOutput); } } }